diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 9364f22aed35e1a1e9d07c121510f80be3ab0502 (patch) | |
tree | d49911209b132da58d838efa852daf28d516df21 /WebCore/page | |
parent | 87eb0cb35bad8784770ebc807e6c982432e47107 (diff) | |
download | external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.zip external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.gz external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.bz2 |
Initial Contribution
Diffstat (limited to 'WebCore/page')
51 files changed, 1182 insertions, 4377 deletions
diff --git a/WebCore/page/AXObjectCache.h b/WebCore/page/AXObjectCache.h deleted file mode 100644 index d73a5a3..0000000 --- a/WebCore/page/AXObjectCache.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2003, 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. - */ - -#ifndef AXObjectCache_h -#define AXObjectCache_h - -#include <limits.h> - -#include <wtf/HashMap.h> -#include <wtf/HashSet.h> - -#ifdef __OBJC__ -@class WebCoreAXObject; -@class WebCoreTextMarker; -#else -class WebCoreAXObject; -class WebCoreTextMarker; -#endif - -namespace WebCore { - - class RenderObject; - class String; - class VisiblePosition; - - typedef unsigned AXID; - - struct AXIDHashTraits : WTF::GenericHashTraits<unsigned> { - static TraitType deletedValue() { return UINT_MAX; } - }; - - class AXObjectCache { - public: - ~AXObjectCache(); - - WebCoreAXObject* get(RenderObject*); - void remove(RenderObject*); - - void removeAXID(WebCoreAXObject*); - - WebCoreTextMarker* textMarkerForVisiblePosition(const VisiblePosition&); - VisiblePosition visiblePositionForTextMarker(WebCoreTextMarker*); - - void childrenChanged(RenderObject*); - void postNotification(RenderObject*, const String& message); - void postNotificationToElement(RenderObject*, const String& message); - void handleFocusedUIElementChanged(); - -#if PLATFORM(MAC) - static void enableAccessibility() { gAccessibilityEnabled = true; } - static bool accessibilityEnabled() { return gAccessibilityEnabled; } -#else - static bool accessibilityEnabled() { return false; } -#endif - - private: -#if PLATFORM(MAC) - static bool gAccessibilityEnabled; -#endif - - AXID getAXID(WebCoreAXObject*); - - HashMap<RenderObject*, WebCoreAXObject*> m_objects; - HashSet<AXID, IntHash<AXID>, AXIDHashTraits> m_idsInUse; - }; - -#if !PLATFORM(MAC) - inline AXObjectCache::~AXObjectCache() { } - inline WebCoreAXObject* AXObjectCache::get(RenderObject*) { return 0; } - inline void AXObjectCache::remove(RenderObject*) { } - inline void AXObjectCache::removeAXID(WebCoreAXObject*) { } - inline void AXObjectCache::childrenChanged(RenderObject*) { } - inline void AXObjectCache::postNotification(RenderObject*, const String&) { } - inline void AXObjectCache::postNotificationToElement(RenderObject*, const String&) { } - inline void AXObjectCache::handleFocusedUIElementChanged() { } -#endif - -} - -#endif diff --git a/WebCore/page/AnimationController.cpp b/WebCore/page/AnimationController.cpp index 9d7a1f7..0c78364 100644 --- a/WebCore/page/AnimationController.cpp +++ b/WebCore/page/AnimationController.cpp @@ -427,19 +427,11 @@ void ImplicitAnimation::animate(CompositeImplicitAnimation* animation, RenderObj RenderStyle* CompositeImplicitAnimation::animate(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle) { - const Transition* currentTransitions = currentStyle->transitions(); - const Transition* targetTransitions = targetStyle->transitions(); - if (currentTransitions != targetTransitions && !(currentTransitions && targetTransitions && *currentTransitions == *targetTransitions)) { - reset(renderer); - deleteAllValues(m_animations); - m_animations.clear(); - } - // Get the animation layers from the target style. // For each one, we need to create a new animation unless one exists already (later occurrences of duplicate // triggers in the layer list get ignored). if (m_animations.isEmpty()) { - for (const Transition* transition = currentTransitions; transition; transition = transition->next()) { + for (const Transition* transition = targetStyle->transitions(); transition; transition = transition->next()) { int property = transition->transitionProperty(); int duration = transition->transitionDuration(); int repeatCount = transition->transitionRepeatCount(); @@ -456,7 +448,7 @@ RenderStyle* CompositeImplicitAnimation::animate(RenderObject* renderer, RenderS HashMap<int, ImplicitAnimation*>::iterator end = m_animations.end(); for (HashMap<int, ImplicitAnimation*>::iterator it = m_animations.begin(); it != end; ++it) it->second->animate(this, renderer, currentStyle, targetStyle, result); - + if (result) return result; @@ -512,7 +504,7 @@ AnimationControllerPrivate::~AnimationControllerPrivate() CompositeImplicitAnimation* AnimationControllerPrivate::get(RenderObject* renderer) { CompositeImplicitAnimation* animation = m_animations.get(renderer); - if (!animation && renderer->style()->transitions()) { + if (!animation) { animation = new CompositeImplicitAnimation(); m_animations.set(renderer, animation); } @@ -592,11 +584,8 @@ RenderStyle* AnimationController::updateImplicitAnimations(RenderObject* rendere // have changed, we reset the animation. We then do a blend to get new values and we return // a new style. ASSERT(renderer->element()); // FIXME: We do not animate generated content yet. - + CompositeImplicitAnimation* animation = m_data->get(renderer); - if (!animation) - return newStyle; - RenderStyle* result = animation->animate(renderer, renderer->style(), newStyle); m_data->updateTimer(); return result; diff --git a/WebCore/page/BarInfo.h b/WebCore/page/BarInfo.h index 4cbbcfc..261d3dd 100644 --- a/WebCore/page/BarInfo.h +++ b/WebCore/page/BarInfo.h @@ -29,7 +29,6 @@ #ifndef BarInfo_h #define BarInfo_h -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> namespace WebCore { @@ -39,15 +38,13 @@ namespace WebCore { class BarInfo : public RefCounted<BarInfo> { public: enum Type { Locationbar, Menubar, Personalbar, Scrollbars, Statusbar, Toolbar }; - - static PassRefPtr<BarInfo> create(Frame* frame, Type type) { return adoptRef(new BarInfo(frame, type)); } - + + BarInfo(Frame*, Type); void disconnectFrame(); bool visible() const; private: - BarInfo(Frame*, Type); Frame* m_frame; Type m_type; }; diff --git a/WebCore/page/Console.h b/WebCore/page/Console.h index 062cfdd..81e39be 100644 --- a/WebCore/page/Console.h +++ b/WebCore/page/Console.h @@ -38,8 +38,7 @@ namespace WebCore { class Console : public RefCounted<Console> { public: - static PassRefPtr<Console> create(Frame* frame) { return adoptRef(new Console(frame)); } - + Console(Frame*); void disconnectFrame(); void error(const String& message); @@ -48,8 +47,6 @@ namespace WebCore { void warn(const String& message); private: - Console(Frame*); - Frame* m_frame; }; diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp index d331b19..f2c3c75 100644 --- a/WebCore/page/ContextMenuController.cpp +++ b/WebCore/page/ContextMenuController.cpp @@ -43,6 +43,7 @@ #include "HitTestRequest.h" #include "HitTestResult.h" #include "InspectorController.h" +#include "KURL.h" #include "MouseEvent.h" #include "Node.h" #include "Page.h" diff --git a/WebCore/page/DOMSelection.h b/WebCore/page/DOMSelection.h index fd8d1fc..d4a579f 100644 --- a/WebCore/page/DOMSelection.h +++ b/WebCore/page/DOMSelection.h @@ -45,7 +45,7 @@ namespace WebCore { class DOMSelection : public RefCounted<DOMSelection> { public: - static PassRefPtr<DOMSelection> create(Frame* frame) { return adoptRef(new DOMSelection(frame)); } + DOMSelection(Frame*); Frame* frame() const; void disconnectFrame(); @@ -92,8 +92,6 @@ namespace WebCore { //TextRange *createRange(); private: - DOMSelection(Frame*); - Frame* m_frame; }; diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp index 22f7489..f091c3d 100644 --- a/WebCore/page/DOMWindow.cpp +++ b/WebCore/page/DOMWindow.cpp @@ -159,63 +159,63 @@ void DOMWindow::clear() Screen* DOMWindow::screen() const { if (!m_screen) - m_screen = Screen::create(m_frame); + m_screen = new Screen(m_frame); return m_screen.get(); } History* DOMWindow::history() const { if (!m_history) - m_history = History::create(m_frame); + m_history = new History(m_frame); return m_history.get(); } BarInfo* DOMWindow::locationbar() const { if (!m_locationbar) - m_locationbar = BarInfo::create(m_frame, BarInfo::Locationbar); + m_locationbar = new BarInfo(m_frame, BarInfo::Locationbar); return m_locationbar.get(); } BarInfo* DOMWindow::menubar() const { if (!m_menubar) - m_menubar = BarInfo::create(m_frame, BarInfo::Menubar); + m_menubar = new BarInfo(m_frame, BarInfo::Menubar); return m_menubar.get(); } BarInfo* DOMWindow::personalbar() const { if (!m_personalbar) - m_personalbar = BarInfo::create(m_frame, BarInfo::Personalbar); + m_personalbar = new BarInfo(m_frame, BarInfo::Personalbar); return m_personalbar.get(); } BarInfo* DOMWindow::scrollbars() const { if (!m_scrollbars) - m_scrollbars = BarInfo::create(m_frame, BarInfo::Scrollbars); + m_scrollbars = new BarInfo(m_frame, BarInfo::Scrollbars); return m_scrollbars.get(); } BarInfo* DOMWindow::statusbar() const { if (!m_statusbar) - m_statusbar = BarInfo::create(m_frame, BarInfo::Statusbar); + m_statusbar = new BarInfo(m_frame, BarInfo::Statusbar); return m_statusbar.get(); } BarInfo* DOMWindow::toolbar() const { if (!m_toolbar) - m_toolbar = BarInfo::create(m_frame, BarInfo::Toolbar); + m_toolbar = new BarInfo(m_frame, BarInfo::Toolbar); return m_toolbar.get(); } Console* DOMWindow::console() const { if (!m_console) - m_console = Console::create(m_frame); + m_console = new Console(m_frame); return m_console.get(); } @@ -230,7 +230,7 @@ void DOMWindow::postMessage(const String& message, const String& domain, const S DOMSelection* DOMWindow::getSelection() { if (!m_selection) - m_selection = DOMSelection::create(m_frame); + m_selection = new DOMSelection(m_frame); return m_selection.get(); } @@ -453,6 +453,13 @@ int DOMWindow::scrollX() const return view->contentsX(); } +#ifdef ANDROID_ORIENTATION_SUPPORT +int DOMWindow::orientation() const +{ + return screen()->orientation(); +} +#endif + int DOMWindow::scrollY() const { if (!m_frame) diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h index adb4731..c814126 100644 --- a/WebCore/page/DOMWindow.h +++ b/WebCore/page/DOMWindow.h @@ -50,7 +50,7 @@ namespace WebCore { class DOMWindow : public RefCounted<DOMWindow> { public: - static PassRefPtr<DOMWindow> create(Frame* frame) { return adoptRef(new DOMWindow(frame)); } + DOMWindow(Frame*); virtual ~DOMWindow(); Frame* frame() { return m_frame; } @@ -100,6 +100,9 @@ namespace WebCore { int scrollY() const; int pageXOffset() const { return scrollX(); } int pageYOffset() const { return scrollY(); } +#ifdef ANDROID_ORIENTATION_SUPPORT + int orientation() const; +#endif bool closed() const; @@ -157,8 +160,6 @@ namespace WebCore { void resizeTo(float width, float height) const; private: - DOMWindow(Frame*); - Frame* m_frame; mutable RefPtr<Screen> m_screen; mutable RefPtr<DOMSelection> m_selection; diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl index 655d6ab..33850d0 100644 --- a/WebCore/page/DOMWindow.idl +++ b/WebCore/page/DOMWindow.idl @@ -83,6 +83,9 @@ module window { attribute [Replaceable] long scrollY; readonly attribute long pageXOffset; readonly attribute long pageYOffset; +#if defined(ANDROID_ORIENTATION_SUPPORT) + attribute [Replaceable] long orientation; +#endif [RequiresAllArguments] void scrollBy(in long x, in long y); [RequiresAllArguments] void scrollTo(in long x, in long y); diff --git a/WebCore/page/EditorClient.h b/WebCore/page/EditorClient.h deleted file mode 100644 index 802aa4f..0000000 --- a/WebCore/page/EditorClient.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007 Trolltech ASA - * - * 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 EditorClient_h -#define EditorClient_h - -#include "EditorInsertAction.h" -#include "PlatformString.h" -#include "TextAffinity.h" -#include <wtf/Forward.h> -#include <wtf/Vector.h> - -#if PLATFORM(MAC) -class NSArray; -class NSData; -class NSString; -class NSURL; -#endif - -namespace WebCore { - -class CSSStyleDeclaration; -class EditCommand; -class Element; -class Frame; -class HTMLElement; -class KeyboardEvent; -class Node; -class Range; -class Selection; -class String; -class VisiblePosition; - -struct GrammarDetail { - int location; - int length; - Vector<String> guesses; - String userDescription; -}; - -class EditorClient { -public: - virtual ~EditorClient() { } - virtual void pageDestroyed() = 0; - - virtual bool shouldDeleteRange(Range*) = 0; - virtual bool shouldShowDeleteInterface(HTMLElement*) = 0; - virtual bool smartInsertDeleteEnabled() = 0; - virtual bool isContinuousSpellCheckingEnabled() = 0; - virtual void toggleContinuousSpellChecking() = 0; - virtual bool isGrammarCheckingEnabled() = 0; - virtual void toggleGrammarChecking() = 0; - virtual int spellCheckerDocumentTag() = 0; - - virtual bool isEditable() = 0; - - virtual bool shouldBeginEditing(Range*) = 0; - virtual bool shouldEndEditing(Range*) = 0; - virtual bool shouldInsertNode(Node*, Range*, EditorInsertAction) = 0; - virtual bool shouldInsertText(String, Range*, EditorInsertAction) = 0; - virtual bool shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity, bool stillSelecting) = 0; - - virtual bool shouldApplyStyle(CSSStyleDeclaration*, Range*) = 0; -// virtual bool shouldChangeTypingStyle(CSSStyleDeclaration* fromStyle, CSSStyleDeclaration* toStyle) = 0; -// virtual bool doCommandBySelector(SEL selector) = 0; - virtual bool shouldMoveRangeAfterDelete(Range*, Range*) = 0; - - virtual void didBeginEditing() = 0; - virtual void respondToChangedContents() = 0; - virtual void respondToChangedSelection() = 0; - virtual void didEndEditing() = 0; - virtual void didWriteSelectionToPasteboard() = 0; - virtual void didSetSelectionTypesForPasteboard() = 0; -// virtual void didChangeTypingStyle:(NSNotification *)notification = 0; -// virtual void didChangeSelection:(NSNotification *)notification = 0; -// virtual NSUndoManager* undoManager:(WebView *)webView = 0; - - virtual void registerCommandForUndo(PassRefPtr<EditCommand>) = 0; - virtual void registerCommandForRedo(PassRefPtr<EditCommand>) = 0; - virtual void clearUndoRedoOperations() = 0; - - virtual bool canUndo() const = 0; - virtual bool canRedo() const = 0; - - virtual void undo() = 0; - virtual void redo() = 0; - - virtual void handleKeyboardEvent(KeyboardEvent*) = 0; - virtual void handleInputMethodKeydown(KeyboardEvent*) = 0; - - virtual void textFieldDidBeginEditing(Element*) = 0; - virtual void textFieldDidEndEditing(Element*) = 0; - virtual void textDidChangeInTextField(Element*) = 0; - virtual bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*) = 0; - virtual void textWillBeDeletedInTextField(Element*) = 0; - virtual void textDidChangeInTextArea(Element*) = 0; - -#if PLATFORM(MAC) - // FIXME: This should become SelectionController::toWebArchive() - virtual NSData* dataForArchivedSelection(Frame*) = 0; - - virtual NSString* userVisibleString(NSURL*) = 0; -#ifdef BUILDING_ON_TIGER - virtual NSArray* pasteboardTypesForSelection(Frame*) = 0; -#endif -#endif - - virtual void ignoreWordInSpellDocument(const String&) = 0; - virtual void learnWord(const String&) = 0; - virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) = 0; - virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0; - virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail& detail) = 0; - virtual void updateSpellingUIWithMisspelledWord(const String&) = 0; - virtual void showSpellingUI(bool show) = 0; - virtual bool spellingUIIsShowing() = 0; - virtual void getGuessesForWord(const String&, Vector<String>& guesses) = 0; - virtual void setInputMethodState(bool enabled) = 0; -}; - -} - -#endif // EditorClient_h diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index adb4086..4ecbe13 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -60,7 +60,9 @@ #include "TextEvent.h" #if ENABLE(SVG) +#include "SVGCursorElement.h" #include "SVGDocument.h" +#include "SVGLength.h" #include "SVGNames.h" #endif @@ -694,6 +696,16 @@ Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Pla for (unsigned i = 0; i < cursors->size(); ++i) { CachedImage* cimage = (*cursors)[i].cursorImage; IntPoint hotSpot = (*cursors)[i].hotSpot; +#if ENABLE(SVG) + if (!cimage) { + Element* e = node->document()->getElementById((*cursors)[i].cursorFragmentId); + if (e && e->hasTagName(cursorTag)) { + hotSpot.setX(int(static_cast<SVGCursorElement*>(e)->x().value())); + hotSpot.setY(int(static_cast<SVGCursorElement*>(e)->y().value())); + cimage = static_cast<SVGCursorElement*>(e)->cachedImage(); + } + } +#endif if (!cimage) continue; if (cimage->image()->isNull()) diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp index 2552ed4..6e8081e 100644 --- a/WebCore/page/Frame.cpp +++ b/WebCore/page/Frame.cpp @@ -74,10 +74,22 @@ #include "kjs_window.h" #include "visible_units.h" +#ifdef MANUAL_MERGE_REQUIRED +#ifdef ANDROID_BRIDGE + #define LOG_TAG "webcore" + #undef LOG + #include <utils/Log.h> + + #include "WebCoreViewBridge.h" + #include "FrameAndroid.h" +#endif + +#else // MANUAL_MERGE_REQUIRED #if FRAME_LOADS_USER_STYLESHEET #include "UserStyleSheetLoader.h" #endif +#endif // MANUAL_MERGE_REQUIRED #if ENABLE(SVG) #include "SVGDocument.h" #include "SVGDocumentExtensions.h" @@ -104,7 +116,11 @@ struct FrameCounter { ~FrameCounter() { if (count) +#ifdef ANDROID_BRIDGE + fprintf(stderr, "LEAK: %d Frame\n", count); +#else LOG(WebCoreFrameLeaks, "LEAK: %d Frame\n", count); +#endif } }; int FrameCounter::count = 0; @@ -119,8 +135,7 @@ static inline Frame* parentFromOwnerElement(HTMLFrameOwnerElement* ownerElement) } Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* frameLoaderClient) - : RefCounted<Frame>(0) - , d(new FramePrivate(page, parentFromOwnerElement(ownerElement), this, ownerElement, frameLoaderClient)) + : d(new FramePrivate(page, parentFromOwnerElement(ownerElement), this, ownerElement, frameLoaderClient)) { AtomicString::init(); EventNames::init(); @@ -138,8 +153,8 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* if (!ownerElement) page->setMainFrame(this); else { - // FIXME: It's bad to have a ref() here but not in the !ownerElement case. - // We need to straighten this out. + // FIXME: Frames were originally created with a refcount of 1. + // Leave this ref call here until we can straighten that out. ref(); page->incrementFrameCount(); ownerElement->m_contentFrame = this; @@ -328,23 +343,23 @@ AnimationController* Frame::animationController() const return &d->m_animationController; } -static RegularExpression* createRegExpForLabels(const Vector<String>& labels) +static RegularExpression *createRegExpForLabels(const Vector<String>& labels) { // REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being // the same across calls. We can't do that. static RegularExpression wordRegExp = RegularExpression("\\w"); - String pattern("("); + DeprecatedString pattern("("); unsigned int numLabels = labels.size(); unsigned int i; for (i = 0; i < numLabels; i++) { - String label = labels[i]; + DeprecatedString label = labels[i].deprecatedString(); bool startsWithWordChar = false; bool endsWithWordChar = false; if (label.length() != 0) { - startsWithWordChar = wordRegExp.search(label.substring(0, 1)) >= 0; - endsWithWordChar = wordRegExp.search(label.substring(label.length() - 1, 1)) >= 0; + startsWithWordChar = wordRegExp.search(label.at(0)) >= 0; + endsWithWordChar = wordRegExp.search(label.at(label.length() - 1)) >= 0; } if (i != 0) @@ -380,10 +395,10 @@ String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellE for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) { if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { // For each text chunk, run the regexp - String nodeString = n->nodeValue(); + DeprecatedString nodeString = n->nodeValue().deprecatedString(); int pos = regExp->searchRev(nodeString); if (pos >= 0) - return nodeString.substring(pos, regExp->matchedLength()); + return nodeString.mid(pos, regExp->matchedLength()); } } } @@ -427,14 +442,15 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element searchedCellAbove = true; } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { // For each text chunk, run the regexp - String nodeString = n->nodeValue(); + DeprecatedString nodeString = n->nodeValue().deprecatedString(); // add 100 for slop, to make it more likely that we'll search whole nodes if (lengthSearched + nodeString.length() > maxCharsSearched) nodeString = nodeString.right(charsSearchedThreshold - lengthSearched); int pos = regExp->searchRev(nodeString); if (pos >= 0) - return nodeString.substring(pos, regExp->matchedLength()); - lengthSearched += nodeString.length(); + return nodeString.mid(pos, regExp->matchedLength()); + else + lengthSearched += nodeString.length(); } } @@ -448,9 +464,9 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element) { - String name = element->getAttribute(nameAttr); + DeprecatedString name = element->getAttribute(nameAttr).deprecatedString(); // Make numbers and _'s in field names behave like word boundaries, e.g., "address2" - replace(name, RegularExpression("\\d"), " "); + name.replace(RegularExpression("\\d"), " "); name.replace('_', ' '); OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels)); @@ -473,7 +489,7 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e } while (pos != -1); if (bestPos != -1) - return name.substring(bestPos, bestLength); + return name.mid(bestPos, bestLength); return String(); } @@ -520,10 +536,12 @@ void Frame::setCaretVisible(bool flag) void Frame::clearCaretRectIfNeeded() { +#ifndef ANDROID_DRAW_OWN_CARET if (d->m_caretPaint) { d->m_caretPaint = false; selectionController()->invalidateCaretRect(); } +#endif } // Helper function that tells whether a particular node is an element that has an entire @@ -570,9 +588,11 @@ void Frame::selectionLayoutChanged() { bool caretRectChanged = selectionController()->recomputeCaretRect(); +#ifndef ANDROID_DRAW_OWN_CARET bool shouldBlink = d->m_caretVisible && selectionController()->isCaret() && selectionController()->isContentEditable(); + shouldBlink = false; // If the caret moved, stop the blink timer so we can restart with a // black caret in the new location. if (caretRectChanged || !shouldBlink) @@ -587,6 +607,10 @@ void Frame::selectionLayoutChanged() selectionController()->invalidateCaretRect(); } } +#else + if (caretRectChanged == false) + return; +#endif if (!renderer()) return; @@ -620,6 +644,7 @@ void Frame::selectionLayoutChanged() void Frame::caretBlinkTimerFired(Timer<Frame>*) { +#ifndef ANDROID_DRAW_OWN_CARET ASSERT(d->m_caretVisible); ASSERT(selectionController()->isCaret()); bool caretPaint = d->m_caretPaint; @@ -627,20 +652,25 @@ void Frame::caretBlinkTimerFired(Timer<Frame>*) return; d->m_caretPaint = !caretPaint; selectionController()->invalidateCaretRect(); +#endif } void Frame::paintCaret(GraphicsContext* p, const IntRect& rect) const { +#ifndef ANDROID_DRAW_OWN_CARET if (d->m_caretPaint && d->m_caretVisible) selectionController()->paintCaret(p, rect); +#endif } void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const { +#ifndef ANDROID_DRAW_OWN_CARET SelectionController* dragCaretController = d->m_page->dragCaretController(); ASSERT(dragCaretController->selection().isCaret()); if (dragCaretController->selection().start().node()->document()->frame() == this) dragCaretController->paintCaret(p, rect); +#endif } int Frame::zoomFactor() const @@ -1643,7 +1673,7 @@ FrameTree* Frame::tree() const DOMWindow* Frame::domWindow() const { if (!d->m_domWindow) - d->m_domWindow = DOMWindow::create(const_cast<Frame*>(this)); + d->m_domWindow = new DOMWindow(const_cast<Frame*>(this)); return d->m_domWindow.get(); } @@ -1689,7 +1719,7 @@ void Frame::disconnectOwnerElement() String Frame::documentTypeString() const { if (Document *doc = document()) - if (DocumentType *doctype = doc->doctype()) + if (DocumentType *doctype = doc->realDocType()) return doctype->toString(); return String(); @@ -1751,10 +1781,10 @@ bool Frame::shouldClose() String text = beforeUnloadEvent->result(); text.replace('\\', backslashAsCurrencySymbol()); - return chrome->runBeforeUnloadConfirmPanel(text, this); } + void Frame::scheduleClose() { if (!shouldClose()) diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h index 24c9903..ea9eadc 100644 --- a/WebCore/page/Frame.h +++ b/WebCore/page/Frame.h @@ -37,6 +37,7 @@ #include <wtf/unicode/Unicode.h> #include <wtf/Forward.h> #include <wtf/Vector.h> +#include "RenderObject.h" struct NPObject; @@ -100,7 +101,6 @@ class KURL; class Node; class Page; class Range; -class RegularExpression; class RenderPart; class Selection; class SelectionController; @@ -146,6 +146,42 @@ public: RenderPart* ownerRenderer(); // renderer for the element that contains this frame friend class FramePrivate; +#ifdef ANDROID_BRIDGE + friend class FrameAndroid; +#endif + +#ifdef ANDROID_INSTRUMENT + void resetTimeCounter(); + void reportTimeCounter(String url, int totalTime, int totalThreadTime); + +private: + void resetParsingTimeCounter(); + void reportParsingTimeCounter(); + + void resetCSSTimeCounter(); + void reportCSSTimeCounter(); + + void resetCalculateStyleTimeCounter(); + void reportCalculateStyleTimeCounter(); + + void resetLayoutTimeCounter(); + void reportLayoutTimeCounter(); + + void resetPaintTimeCounter(); + void reportPaintTimeCounter(); + + void resetSharedTimerTimeCounter(); + void reportSharedTimerTimeCounter(); + + void resetResourceLoadTimeCounter(); + void reportResourceLoadTimeCounter(); + + void resetWebViewCoreTimeCounter(); + void reportWebViewCoreTimeCounter(); + + void resetFramebridgeTimeCounter(); + void reportFramebridgeTimeCounter(); +#endif private: FramePrivate* d; @@ -330,7 +366,7 @@ public: void selectionTextRects(Vector<FloatRect>&, bool clipToVisibleContent = true) const; HTMLFormElement* currentForm() const; - + void revealSelection(const RenderLayer::ScrollAlignment& = RenderLayer::gAlignCenterIfNeeded) const; void revealCaret(const RenderLayer::ScrollAlignment& = RenderLayer::gAlignCenterIfNeeded) const; void setSelectionFromNone(); diff --git a/WebCore/page/FrameTree.cpp b/WebCore/page/FrameTree.cpp index 0831be8..92e198d 100644 --- a/WebCore/page/FrameTree.cpp +++ b/WebCore/page/FrameTree.cpp @@ -118,7 +118,7 @@ AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const String name; name += framePathPrefix; if (frame) - name += frame->tree()->name().string().substring(framePathPrefixLength, + name += frame->tree()->name().domString().substring(framePathPrefixLength, frame->tree()->name().length() - framePathPrefixLength - framePathSuffixLength); for (int i = chain.size() - 1; i >= 0; --i) { frame = chain[i]; diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp index d56175a..21adc10 100644 --- a/WebCore/page/FrameView.cpp +++ b/WebCore/page/FrameView.cpp @@ -27,7 +27,6 @@ #include "FrameView.h" #include "AXObjectCache.h" -#include "CSSStyleSelector.h" #include "EventHandler.h" #include "FloatRect.h" #include "Frame.h" @@ -43,6 +42,13 @@ #include "RenderTheme.h" #include "RenderView.h" +#ifdef ANDROID_INSTRUMENT +#undef LOG +#include <utils/Log.h> +#include "SystemTime.h" +#include "FrameTree.h" +#endif + namespace WebCore { using namespace HTMLNames; @@ -314,6 +320,23 @@ RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const return onlyDuringLayout && layoutPending() ? 0 : d->layoutRoot; } +#ifdef ANDROID_INSTRUMENT +static uint32_t sTotalTimeUsed = 0; +static uint32_t sCounter = 0; + +void Frame::resetLayoutTimeCounter() +{ + sTotalTimeUsed = 0; + sCounter = 0; +} + +void Frame::reportLayoutTimeCounter() +{ + LOG(LOG_DEBUG, "WebCore", "*-* Total layout time: %d ms called %d times\n", + sTotalTimeUsed, sCounter); +} +#endif + void FrameView::layout(bool allowSubtree) { if (d->midLayout) @@ -365,11 +388,6 @@ void FrameView::layout(bool allowSubtree) performPostLayoutTasks(); } - // Viewport-dependent media queries may cause us to need completely different style information. - // Check that here. - if (document->styleSelector()->affectedByViewportChange()) - document->updateStyleSelector(); - // Always ensure our style info is up-to-date. This can happen in situations where // the layout beats any sort of style recalc update that needs to occur. if (m_frame->needsReapplyStyles()) @@ -391,6 +409,12 @@ void FrameView::layout(bool allowSubtree) return; } +#ifdef ANDROID_INSTRUMENT + uint32_t startTime = 0; + if (!m_frame->tree() || !m_frame->tree()->parent()) + startTime = get_thread_msec(); +#endif + d->nestedLayoutCount++; ScrollbarMode hMode = d->hmode; @@ -507,6 +531,15 @@ void FrameView::layout(bool allowSubtree) if (didFirstLayout) m_frame->loader()->didFirstLayout(); +#ifdef ANDROID_INSTRUMENT + if (!m_frame->tree()->parent()) { + uint32_t time = get_thread_msec() - startTime; + sTotalTimeUsed += time; + sCounter++; + if (time > 1000) + LOGW("***** FrameView::layout() used %d ms\n", time); + } +#endif ASSERT(!root->needsLayout()); setStaticBackground(useSlowRepaints()); @@ -735,7 +768,11 @@ void FrameView::scheduleRelayout() if (!m_frame->document() || !m_frame->document()->shouldScheduleLayout()) return; +#ifdef ANDROID_MOBILE + int delay = m_frame->document()->minimumLayoutDelay() + m_frame->document()->extraLayoutDelay(); +#else int delay = m_frame->document()->minimumLayoutDelay(); +#endif if (d->layoutTimer.isActive() && d->delayedLayout && !delay) unscheduleRelayout(); if (d->layoutTimer.isActive()) @@ -748,6 +785,11 @@ void FrameView::scheduleRelayout() printf("Scheduling layout for %d\n", delay); #endif +#if defined(FLATTEN_IFRAME) || defined(FLATTEN_FRAMESET) + if (m_frame->ownerRenderer()) + m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc(); +#endif + d->layoutTimer.startOneShot(delay * 0.001); } @@ -790,7 +832,11 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* o) } } } else { +#ifdef ANDROID_MOBILE + int delay = m_frame->document()->minimumLayoutDelay() + m_frame->document()->extraLayoutDelay(); +#else int delay = m_frame->document()->minimumLayoutDelay(); +#endif d->layoutRoot = o; d->delayedLayout = delay != 0; d->layoutTimer.startOneShot(delay * 0.001); diff --git a/WebCore/page/GlobalHistory.h b/WebCore/page/GlobalHistory.h deleted file mode 100644 index 4857f6f..0000000 --- a/WebCore/page/GlobalHistory.h +++ /dev/null @@ -1,37 +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. - */ - -#ifndef GlobalHistory_h -#define GlobalHistory_h - -#include <wtf/unicode/Unicode.h> - -namespace WebCore { - - bool historyContains(const UChar* characters, unsigned length); - -} // namespace WebCore - -#endif // GlobalHistory_h diff --git a/WebCore/page/History.h b/WebCore/page/History.h index f0df2de..815a44d 100644 --- a/WebCore/page/History.h +++ b/WebCore/page/History.h @@ -26,7 +26,6 @@ #ifndef History_h #define History_h -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> namespace WebCore { @@ -35,8 +34,8 @@ namespace WebCore { class History : public RefCounted<History> { public: - static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); } - + History(Frame*); + Frame* frame() const; void disconnectFrame(); @@ -46,8 +45,6 @@ namespace WebCore { void go(int distance); private: - History(Frame*); - Frame* m_frame; }; diff --git a/WebCore/page/InspectorController.cpp b/WebCore/page/InspectorController.cpp index ba08f01..df748a0 100644 --- a/WebCore/page/InspectorController.cpp +++ b/WebCore/page/InspectorController.cpp @@ -115,11 +115,24 @@ struct InspectorResource : public RefCounted<InspectorResource> { Other }; - static PassRefPtr<InspectorResource> create(long long identifier, DocumentLoader* documentLoader, Frame* frame) + InspectorResource(long long identifier, DocumentLoader* documentLoader, Frame* frame) + : identifier(identifier) + , loader(documentLoader) + , frame(frame) + , scriptContext(0) + , scriptObject(0) + , expectedContentLength(0) + , cached(false) + , finished(false) + , failed(false) + , length(0) + , responseStatusCode(0) + , startTime(-1.0) + , responseReceivedTime(-1.0) + , endTime(-1.0) { - return adoptRef(new InspectorResource(identifier, documentLoader, frame)); } - + ~InspectorResource() { setScriptObject(0, 0); @@ -186,25 +199,6 @@ struct InspectorResource : public RefCounted<InspectorResource> { double startTime; double responseReceivedTime; double endTime; - -private: - InspectorResource(long long identifier, DocumentLoader* documentLoader, Frame* frame) - : identifier(identifier) - , loader(documentLoader) - , frame(frame) - , scriptContext(0) - , scriptObject(0) - , expectedContentLength(0) - , cached(false) - , finished(false) - , failed(false) - , length(0) - , responseStatusCode(0) - , startTime(-1.0) - , responseReceivedTime(-1.0) - , endTime(-1.0) - { - } }; #pragma mark - @@ -212,9 +206,19 @@ private: #if ENABLE(DATABASE) struct InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> { - static PassRefPtr<InspectorDatabaseResource> create(Database* database, const String& domain, const String& name, const String& version) + InspectorDatabaseResource(Database* database, String domain, String name, String version) + : database(database) + , domain(domain) + , name(name) + , version(version) + , scriptContext(0) + , scriptObject(0) { - return adoptRef(new InspectorDatabaseResource(database, domain, name, version)); + } + + InspectorDatabaseResource() + { + setScriptObject(0, 0); } void setScriptObject(JSContextRef context, JSObjectRef newScriptObject) @@ -236,17 +240,6 @@ struct InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> String version; JSContextRef scriptContext; JSObjectRef scriptObject; - -private: - InspectorDatabaseResource(Database* database, const String& domain, const String& name, const String& version) - : database(database) - , domain(domain) - , name(name) - , version(version) - , scriptContext(0) - , scriptObject(0) - { - } }; #endif @@ -1428,11 +1421,11 @@ void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader, if (!enabled()) return; - RefPtr<InspectorResource> resource = InspectorResource::create(m_nextIdentifier--, loader, loader->frame()); + InspectorResource* resource = new InspectorResource(m_nextIdentifier--, loader, loader->frame()); resource->finished = true; - updateResourceRequest(resource.get(), request); - updateResourceResponse(resource.get(), response); + updateResourceRequest(resource, request); + updateResourceResponse(resource, response); resource->length = length; resource->cached = true; @@ -1443,10 +1436,10 @@ void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader, if (loader->frame() == m_inspectedPage->mainFrame() && request.url() == loader->requestURL()) m_mainResource = resource; - addResource(resource.get()); + addResource(resource); if (windowVisible()) - addAndUpdateScriptResource(resource.get()); + addAndUpdateScriptResource(resource); } void InspectorController::identifierForInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) @@ -1454,17 +1447,17 @@ void InspectorController::identifierForInitialRequest(unsigned long identifier, if (!enabled()) return; - RefPtr<InspectorResource> resource = InspectorResource::create(identifier, loader, loader->frame()); + InspectorResource* resource = new InspectorResource(identifier, loader, loader->frame()); - updateResourceRequest(resource.get(), request); + updateResourceRequest(resource, request); if (loader->frame() == m_inspectedPage->mainFrame() && request.url() == loader->requestURL()) m_mainResource = resource; - addResource(resource.get()); + addResource(resource); if (windowVisible() && loader->isLoadingFromCachedPage() && resource == m_mainResource) - addAndUpdateScriptResource(resource.get()); + addAndUpdateScriptResource(resource); } void InspectorController::willSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) @@ -1581,12 +1574,12 @@ void InspectorController::didOpenDatabase(Database* database, const String& doma if (!enabled()) return; - RefPtr<InspectorDatabaseResource> resource = InspectorDatabaseResource::create(database, domain, name, version); + InspectorDatabaseResource* resource = new InspectorDatabaseResource(database, domain, name, version); m_databaseResources.add(resource); if (windowVisible()) - addDatabaseScriptResource(resource.get()); + addDatabaseScriptResource(resource); } #endif diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp index f60d05c..efae3bf 100644 --- a/WebCore/page/Page.cpp +++ b/WebCore/page/Page.cpp @@ -77,7 +77,7 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi , m_inspectorController(new InspectorController(this, inspectorClient)) , m_settings(new Settings(this)) , m_progress(new ProgressTracker) - , m_backForwardList(BackForwardList::create(this)) + , m_backForwardList(new BackForwardList(this)) , m_editorClient(editorClient) , m_frameCount(0) , m_tabKeyCyclesThroughElements(true) diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h index b685e3f..501890f 100644 --- a/WebCore/page/Page.h +++ b/WebCore/page/Page.h @@ -33,6 +33,17 @@ typedef struct HINSTANCE__* HINSTANCE; #endif +#ifdef ANDROID_FIX +enum TextCaseSensitivity { + TextCaseSensitive, + TextCaseInsensitive +}; + +enum FindDirection { + FindDirectionForward, + FindDirectionBackward +}; +#else typedef enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive @@ -42,6 +53,7 @@ typedef enum FindDirection { FindDirectionForward, FindDirectionBackward }; +#endif namespace WebCore { diff --git a/WebCore/page/Plugin.h b/WebCore/page/Plugin.h index 1e53184..f5b4c63 100644 --- a/WebCore/page/Plugin.h +++ b/WebCore/page/Plugin.h @@ -29,11 +29,10 @@ namespace WebCore { class Plugin : public RefCounted<Plugin> { public: - static PassRefPtr<Plugin> create(Widget* view) { return adoptRef(new Plugin(view)); } + Plugin(Widget* view) : m_view(view) { } Widget* view() const { return m_view; } private: - Plugin(Widget* view) : m_view(view) { } Widget* m_view; }; diff --git a/WebCore/page/Screen.h b/WebCore/page/Screen.h index 288b1ac..510cefd 100644 --- a/WebCore/page/Screen.h +++ b/WebCore/page/Screen.h @@ -30,7 +30,6 @@ #ifndef Screen_h #define Screen_h -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> namespace WebCore { @@ -39,7 +38,7 @@ namespace WebCore { class Screen : public RefCounted<Screen> { public: - static PassRefPtr<Screen> create(Frame *frame) { return adoptRef(new Screen(frame)); } + Screen(Frame*); void disconnectFrame(); unsigned height() const; @@ -50,10 +49,11 @@ namespace WebCore { unsigned availTop() const; unsigned availHeight() const; unsigned availWidth() const; +#ifdef ANDROID_ORIENTATION_SUPPORT + int orientation() const; +#endif private: - Screen(Frame*); - Frame* m_frame; }; diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp index 5253117..9a8adb0 100644 --- a/WebCore/page/Settings.cpp +++ b/WebCore/page/Settings.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007 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 @@ -46,11 +46,23 @@ static void setNeedsReapplyStylesInAllFrames(Page* page) Settings::Settings(Page* page) : m_page(page) +#ifdef ANDROID_LAYOUT + , m_layoutAlgorithm(kLayoutFitColumnToScreen) +#endif , m_editableLinkBehavior(EditableLinkDefaultBehavior) , m_minimumFontSize(0) , m_minimumLogicalFontSize(0) , m_defaultFontSize(0) , m_defaultFixedFontSize(0) +#ifdef ANDROID_LAYOUT + , m_useWideViewport(false) +#endif +#ifdef ANDROID_MULTIPLE_WINDOWS + , m_supportMultipleWindows(true) +#endif +#ifdef ANDROID_BLOCK_NETWORK_IMAGE + , m_blockNetworkImage(false) +#endif , m_isJavaEnabled(false) , m_loadsImagesAutomatically(false) , m_privateBrowsingEnabled(false) @@ -75,6 +87,9 @@ Settings::Settings(Page* page) // A Frame may not have been created yet, so we initialize the AtomicString // hash before trying to use it. AtomicString::init(); +#ifdef ANDROID_META_SUPPORT + resetMetadataSettings(); +#endif } void Settings::setStandardFontFamily(const AtomicString& standardFontFamily) @@ -167,6 +182,13 @@ void Settings::setDefaultFixedFontSize(int defaultFontSize) setNeedsReapplyStylesInAllFrames(m_page); } +#ifdef ANDROID_BLOCK_NETWORK_IMAGE +void Settings::setBlockNetworkImage(bool blockNetworkImage) +{ + m_blockNetworkImage = blockNetworkImage; +} +#endif + void Settings::setLoadsImagesAutomatically(bool loadsImagesAutomatically) { m_loadsImagesAutomatically = loadsImagesAutomatically; @@ -187,6 +209,13 @@ void Settings::setPluginsEnabled(bool arePluginsEnabled) m_arePluginsEnabled = arePluginsEnabled; } +#ifdef ANDROID_PLUGINS +void Settings::setPluginsPath(const String& pluginsPath) +{ + m_pluginsPath = pluginsPath; +} +#endif + void Settings::setPrivateBrowsingEnabled(bool privateBrowsingEnabled) { m_privateBrowsingEnabled = privateBrowsingEnabled; @@ -296,6 +325,95 @@ void Settings::setDeveloperExtrasEnabled(bool developerExtrasEnabled) m_developerExtrasEnabled = developerExtrasEnabled; } +#ifdef ANDROID_META_SUPPORT +void Settings::resetMetadataSettings() +{ + m_viewport_width = -1; + m_viewport_height = -1; + m_viewport_initial_scale = 0; + m_viewport_minimum_scale = 0; + m_viewport_maximum_scale = 0; + m_viewport_user_scalable = true; + m_format_detection_telephone = true; + m_format_detection_address = true; + m_format_detection_email = true; +} + +void Settings::setMetadataSettings(const String& key, const String& value) +{ + if (key == "width") { + if (value == "device-width") { + m_viewport_width = 0; + } else { + int width = value.toInt(); + if (width >= 200 && width <= 10000) { + if (width == 320) { + // This is a hack to accommodate the pages designed for the + // original iPhone. The new version, since 10/2007, is to + // use device-width which works for both prtrait and + // landscape modes. + m_viewport_width = 0; + } else { + m_viewport_width = width; + } + } + } + } else if (key == "height") { + if (value == "device-height") { + m_viewport_height = 0; + } else { + int height = value.toInt(); + if (height >= 200 && height <= 10000) { + m_viewport_height = height; + } + } + } else if (key == "initial-scale") { + int scale = int(value.toFloat() * 100); + if (scale >= 1 && scale <= 1000) { + m_viewport_initial_scale = scale; + } + } else if (key == "minimum-scale") { + int scale = int(value.toFloat() * 100); + if (scale >= 1 && scale <= 1000) { + m_viewport_minimum_scale = scale; + } + } else if (key == "maximum-scale") { + int scale = int(value.toFloat() * 100); + if (scale >= 1 && scale <= 1000) { + m_viewport_maximum_scale = scale; + } + } else if (key == "user-scalable") { + // even Apple doc says using "no", "0" is common in the real world, and + // some sites, e.g. gomoviesapp.com, use "false". + if (value == "no" || value == "0" || value == "false") { + m_viewport_user_scalable = false; + } + } else if (key == "telephone") { + if (value == "no") { + m_format_detection_telephone = false; + } + } else if (key == "address") { + if (value == "no") { + m_format_detection_address = false; + } + } else if (key == "email") { + if (value == "no") { + m_format_detection_email = false; + } + } else if (key == "format-detection") { + // even Apple doc says "format-detection" should be the name of the + // <meta> tag. In the real world, e.g. amazon.com, use + // "format-detection=no" in the "viewport" <meta> tag to disable all + // format detection. + if (value == "no") { + m_format_detection_telephone = false; + m_format_detection_address = false; + m_format_detection_email = false; + } + } +} +#endif + void Settings::setAuthorAndUserStylesEnabled(bool authorAndUserStylesEnabled) { if (m_authorAndUserStylesEnabled == authorAndUserStylesEnabled) diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h index 704b486..28b92c3 100644 --- a/WebCore/page/Settings.h +++ b/WebCore/page/Settings.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. * (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * Redistribution and use in source and binary forms, with or without @@ -28,8 +28,8 @@ #define Settings_h #include "AtomicString.h" -#include "FontDescription.h" #include "KURL.h" +#include "FontDescription.h" namespace WebCore { @@ -43,16 +43,36 @@ namespace WebCore { EditableLinkNeverLive }; - class Settings { + class Settings + { public: Settings(Page*); +#ifdef ANDROID_LAYOUT + // FIXME: How do we determine the margins other than guessing? + #define ANDROID_SSR_MARGIN_PADDING 3 + #define ANDROID_FCTS_MARGIN_PADDING 10 + + enum LayoutAlgorithm { + kLayoutNormal, + kLayoutSSR, + kLayoutFitColumnToScreen + }; +#endif void setStandardFontFamily(const AtomicString&); const AtomicString& standardFontFamily() const { return m_standardFontFamily; } void setFixedFontFamily(const AtomicString&); const AtomicString& fixedFontFamily() const { return m_fixedFontFamily; } +#ifdef ANDROID_LAYOUT + LayoutAlgorithm layoutAlgorithm() const { return m_layoutAlgorithm; } + void setLayoutAlgorithm(LayoutAlgorithm algorithm) { m_layoutAlgorithm = algorithm; } + + bool useWideViewport() const { return m_useWideViewport; } + void setUseWideViewport(bool use) { m_useWideViewport = use; } +#endif + void setSerifFontFamily(const AtomicString&); const AtomicString& serifFontFamily() const { return m_serifFontFamily; } @@ -80,6 +100,10 @@ namespace WebCore { void setLoadsImagesAutomatically(bool); bool loadsImagesAutomatically() const { return m_loadsImagesAutomatically; } +#ifdef ANDROID_BLOCK_NETWORK_IMAGE + void setBlockNetworkImage(bool); + bool blockNetworkImage() const { return m_blockNetworkImage; } +#endif void setJavaScriptEnabled(bool); bool isJavaScriptEnabled() const { return m_isJavaScriptEnabled; } @@ -92,6 +116,11 @@ namespace WebCore { void setPluginsEnabled(bool); bool arePluginsEnabled() const { return m_arePluginsEnabled; } +#ifdef ANDROID_PLUGINS + void setPluginsPath(const String& pluginsPath); + const String& pluginsPath() const { return m_pluginsPath; } +#endif + void setPrivateBrowsingEnabled(bool); bool privateBrowsingEnabled() const { return m_privateBrowsingEnabled; } @@ -140,6 +169,24 @@ namespace WebCore { void setDeveloperExtrasEnabled(bool); bool developerExtrasEnabled() const { return m_developerExtrasEnabled; } +#ifdef ANDROID_META_SUPPORT + void resetMetadataSettings(); + void setMetadataSettings(const String& key, const String& value); + + int viewportWidth() const { return m_viewport_width; } + int viewportHeight() const { return m_viewport_height; } + int viewportInitialScale() const { return m_viewport_initial_scale; } + int viewportMinimumScale() const { return m_viewport_minimum_scale; } + int viewportMaximumScale() const { return m_viewport_maximum_scale; } + bool viewportUserScalable() const { return m_viewport_user_scalable; } + bool formatDetectionAddress() const { return m_format_detection_address; } + bool formatDetectionEmail() const { return m_format_detection_email; } + bool formatDetectionTelephone() const { return m_format_detection_telephone; } +#endif +#ifdef ANDROID_MULTIPLE_WINDOWS + bool supportMultipleWindows() const { return m_supportMultipleWindows; } + void setSupportMultipleWindows(bool support) { m_supportMultipleWindows = support; } +#endif void setAuthorAndUserStylesEnabled(bool); bool authorAndUserStylesEnabled() const { return m_authorAndUserStylesEnabled; } @@ -154,6 +201,9 @@ namespace WebCore { String m_defaultTextEncodingName; String m_ftpDirectoryTemplatePath; +#ifdef ANDROID_PLUGINS + String m_pluginsPath; +#endif KURL m_userStyleSheetLocation; AtomicString m_standardFontFamily; AtomicString m_fixedFontFamily; @@ -161,11 +211,45 @@ namespace WebCore { AtomicString m_sansSerifFontFamily; AtomicString m_cursiveFontFamily; AtomicString m_fantasyFontFamily; +#ifdef ANDROID_LAYOUT + LayoutAlgorithm m_layoutAlgorithm; +#endif EditableLinkBehavior m_editableLinkBehavior; int m_minimumFontSize; int m_minimumLogicalFontSize; int m_defaultFontSize; int m_defaultFixedFontSize; +#ifdef ANDROID_META_SUPPORT + // range is from 200 to 10,000. 0 is a special value means device-width. + // default is -1, which means undefined. + int m_viewport_width; + // range is from 223 to 10,000. 0 is a special value means device-height + // default is -1, which means undefined. + int m_viewport_height; + // range is from 1 to 1000 in percent. default is 0, which means undefined. + int m_viewport_initial_scale; + // range is from 1 to 1000 in percent. default is 0, which means undefined. + int m_viewport_minimum_scale; + // range is from 1 to 1000 in percent. default is 0, which means undefined. + int m_viewport_maximum_scale; + // default is yes + bool m_viewport_user_scalable : 1; + // default is yes + bool m_format_detection_telephone : 1; + // default is yes + bool m_format_detection_address : 1; + // default is yes + bool m_format_detection_email : 1; +#endif +#ifdef ANDROID_LAYOUT + bool m_useWideViewport : 1; +#endif +#ifdef ANDROID_MULTIPLE_WINDOWS + bool m_supportMultipleWindows : 1; +#endif +#ifdef ANDROID_BLOCK_NETWORK_IMAGE + bool m_blockNetworkImage : 1; +#endif bool m_isJavaEnabled : 1; bool m_loadsImagesAutomatically : 1; bool m_privateBrowsingEnabled : 1; diff --git a/WebCore/page/win/PageWin.cpp b/WebCore/page/android/DragControllerAndroid.cpp index f4c744a..a56411d 100644 --- a/WebCore/page/win/PageWin.cpp +++ b/WebCore/page/android/DragControllerAndroid.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * 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 @@ -24,15 +24,37 @@ */ #include "config.h" -#include "Page.h" +#include "DragController.h" +#include "DragData.h" #include "Frame.h" #include "FrameView.h" -#include "FloatRect.h" -#include <windows.h> +#include "Page.h" namespace WebCore { -HINSTANCE Page::s_instanceHandle = 0; +bool DragController::isCopyKeyDown() +{ + return false; +} + +DragOperation DragController::dragOperation(DragData* dragData) +{ + //FIXME: This logic is incomplete + ASSERT(0); + if (dragData->containsURL()) + return DragOperationCopy; + + return DragOperationNone; +} + +// functions new to Jun-07 tip of tree merge: +const float DragController::DragImageAlpha = 1.0f; +static IntSize dummy; +const IntSize& DragController::maxDragImageSize() { return dummy; } +const int DragController::DragIconRightInset = 0; +const int DragController::DragIconBottomInset = 0; +const int DragController::LinkDragBorderInset = 0; +const int DragController::MaxOriginalImageArea = 0; -} // namespace WebCore +} diff --git a/WebCore/page/android/EventHandlerAndroid.cpp b/WebCore/page/android/EventHandlerAndroid.cpp new file mode 100644 index 0000000..ca74a79 --- /dev/null +++ b/WebCore/page/android/EventHandlerAndroid.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2006 Zack Rusin <zack@kde.org> + * + * 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 "EventHandler.h" + +#include "EventNames.h" +#include "FloatPoint.h" +#include "FocusController.h" +#include "Frame.h" +#include "FrameView.h" +#include "KeyboardEvent.h" +#include "MouseEventWithHitTestResults.h" +#include "Page.h" +#include "PlatformScrollBar.h" +#include "PlatformWheelEvent.h" +#include "RenderWidget.h" + +#define LOG_TAG "WebCore" +#undef LOG +#include <utils/Log.h> + +namespace WebCore { + +using namespace EventNames; + +#define notImplemented() { LOGV("%s: Not Implemented", __FUNCTION__); } + +bool EventHandler::tabsToAllControls(KeyboardEvent* ) const +{ + return true; +} + +void EventHandler::focusDocumentView() +{ + if (Page* page = m_frame->page()) + page->focusController()->setFocusedFrame(m_frame); +} + +bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event) +{ + // Figure out which view to send the event to. + RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0; + if (!target || !target->isWidget()) + return false; + + return passMouseDownEventToWidget(static_cast<RenderWidget*>(target)->widget()); +} + +bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget) +{ + return passMouseDownEventToWidget(renderWidget->widget()); +} + +// This function is used to route the mouse down event to the native widgets, it seems like a +// work around for the Mac platform which does not support double clicks, but browsers do. +bool EventHandler::passMouseDownEventToWidget(Widget* widget) +{ + notImplemented(); + return false; +} + +bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const +{ + notImplemented(); + return false; +} + +// This function is called for mouse events by FrameView::handleMousePressEvent() +// It is used to ensure that events are sync. correctly between frames, for example +// if the user presses down in one frame and up in another frame, this function will +// return true if that is the case, and pass the event to the correct frame +bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& event, + Frame* subframe, HitTestResult* hoveredNode) +{ + notImplemented(); + return false; +} + +// This is called to route Wheel Events to child widgets when they are a RenderWidget +// as the parent usually gets Wheel Event. Don't have a mouse with a wheel to confirm +// the operation of this function. +bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& , Widget* widget) +{ + notImplemented(); + return false; +} + +bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) +{ + return passSubframeEventToSubframe(mev, subframe); +} + +bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, + Frame* subframe, HitTestResult* hoveredNode) +{ + return passSubframeEventToSubframe(mev, subframe); +} + +bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) +{ + return passSubframeEventToSubframe(mev, subframe); +} + +bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults&, PlatformScrollbar* scrollbar) +{ + notImplemented(); + return false; +} + +// functions new to Jun-07 tip of tree merge: +Clipboard* EventHandler::createDraggingClipboard() const { return NULL; } + + +} diff --git a/WebCore/page/android/FrameAndroid.cpp b/WebCore/page/android/FrameAndroid.cpp new file mode 100644 index 0000000..ca86bb5 --- /dev/null +++ b/WebCore/page/android/FrameAndroid.cpp @@ -0,0 +1,301 @@ +/* +** +** 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 "FrameAndroid.h" + +#include <JavaScriptCore/bindings/runtime_root.h> +#include <JavaScriptCore/bindings/runtime_object.h> +#include <JavaScriptCore/bindings/jni/jni_utility.h> +#include "jni.h" +#include "kjs_proxy.h" +#include "kjs_window.h" + +#include "CacheBuilder.h" +#include "CachedImage.h" +#include "Document.h" +#include "EventNames.h" +#include "FrameLoader.h" +#include "FramePrivate.h" +#include "FrameView.h" +#include "HTMLAreaElement.h" +#include "HTMLImageElement.h" +#include "HTMLNames.h" +#include "Image.h" +#include "Page.h" +#include "PlatformKeyboardEvent.h" +#include "PlatformString.h" +#ifdef ANDROID_PLUGINS +#include "Plugin.h" +#include "PluginViewAndroid.h" +#endif +#include "RenderImage.h" +#include "RenderTable.h" +#include "RenderTextControl.h" +#include "RenderTheme.h" +#include "RenderView.h" +#include "RenderWidget.h" +#include "SelectionController.h" +#include "Settings.h" +#include "SkScalar.h" +#include "Text.h" +#include "WebCoreFrameBridge.h" +#include "WebCoreViewBridge.h" + +#define LOG_TAG "WebCore" +#undef LOG +#include <utils/Log.h> + +#ifdef ANDROID_INSTRUMENT +#include "CString.h" +#include "Cache.h" +#endif + +using KJS::JSLock; +using KJS::JSValue; + +namespace WebCore { + +#ifdef ANDROID_INSTRUMENT +// The following code should be inside Frame.cpp. But android LOG is conflict +// with webcore LOG +void Frame::resetTimeCounter() { + KJS::JSGlobalObject::resetTimeCounter(); + resetLayoutTimeCounter(); + resetPaintTimeCounter(); + resetCSSTimeCounter(); + resetParsingTimeCounter(); + resetCalculateStyleTimeCounter(); + resetFramebridgeTimeCounter(); + resetSharedTimerTimeCounter(); + resetResourceLoadTimeCounter(); + resetWebViewCoreTimeCounter(); + LOG(LOG_DEBUG, "WebCore", "*-* Start browser instrument\n"); +} + +void Frame::reportTimeCounter(String url, int total, int totalThreadTime) +{ + LOG(LOG_DEBUG, "WebCore", + "*-* Total load time: %d ms, thread time: %d ms for %s\n", + total, totalThreadTime, url.utf8().data()); + KJS::JSGlobalObject::reportTimeCounter(); + reportLayoutTimeCounter(); + reportPaintTimeCounter(); + reportCSSTimeCounter(); + reportParsingTimeCounter(); + reportCalculateStyleTimeCounter(); + reportFramebridgeTimeCounter(); + reportSharedTimerTimeCounter(); + reportResourceLoadTimeCounter(); + reportWebViewCoreTimeCounter(); + LOG(LOG_DEBUG, "WebCore", "Current cache has %d bytes live and %d bytes dead", cache()->getLiveSize(), cache()->getDeadSize()); +} +#endif + +#ifdef ANDROID_PLUGINS +KJS::Bindings::Instance* Frame::createScriptInstanceForWidget(Widget* widget) +{ + if (widget->isFrameView()) + return 0; + + return static_cast<PluginViewAndroid*>(widget)->bindingInstance(); +} +#endif + +FrameAndroid::FrameAndroid(Page* page, HTMLFrameOwnerElement* element, FrameLoaderClient* client) + : Frame(page, element, client), + m_bindingRoot(NULL), m_bridge(NULL) +{ +} + +FrameAndroid::~FrameAndroid() +{ + if (view() != NULL) + view()->getWebCoreViewBridge()->removeFrameGeneration(this); + Release(m_bridge); + setView(0); + loader()->clearRecordedFormValues(); +} + +void FrameAndroid::select(int selectionStart, int selectionEnd) +{ + if (selectionStart > selectionEnd) { + int temp = selectionStart; + selectionStart = selectionEnd; + selectionEnd = temp; + } + Document* doc = document(); + if (!doc) + return; + Node* focus = doc->focusedNode(); + if (!focus) + return; + RenderObject* renderer = focus->renderer(); + if (renderer && (renderer->isTextField() || renderer->isTextArea())) { + RenderTextControl* rtc = static_cast<RenderTextControl*>(renderer); + rtc->setSelectionRange(selectionStart, selectionEnd); + Frame::revealSelection(); + } +} + +void FrameAndroid::cleanupForFullLayout(RenderObject* obj) +{ + recursiveCleanupForFullLayout(obj); +} + +void FrameAndroid::recursiveCleanupForFullLayout(RenderObject* obj) +{ + obj->setNeedsLayout(true, false); +#ifdef ANDROID_LAYOUT + if (obj->isTable()) + (static_cast<RenderTable *>(obj))->clearSingleColumn(); +#endif + for (RenderObject* n = obj->firstChild(); n; n = n->nextSibling()) + recursiveCleanupForFullLayout(n); +} + +KJS::Bindings::RootObject* FrameAndroid::bindingRootObject() +{ + if (!m_bindingRoot) + m_bindingRoot = KJS::Bindings::RootObject::create(0, scriptProxy()->globalObject()); // The root gets deleted by JavaScriptCore. + ASSERT(settings()->isJavaScriptEnabled()); + // The root gets deleted by JavaScriptCore. + m_bindingRoot = KJS::Bindings::RootObject::create(0, scriptProxy()->globalObject()); + return m_bindingRoot.get(); +} + +/* +* This function provides the ability to add a Java class to Javascript and +* expose it through the Window object. +* The code to access the object would look something like: window.<objectName>.<class method> +*/ +void FrameAndroid::addJavascriptInterface(void *javaVM, void* objectInstance, const char* objectNameStr) +{ + // Obtain the window object from KJS + KJS::Bindings::RootObject *root = bindingRootObject(); + KJS::JSObject *rootObject = root->globalObject(); + KJS::ExecState *exec = root->globalObject()->globalExec(); + KJS::JSObject *window = rootObject->get(exec, KJS::Identifier("window"))->getObject(); + if (!window) { + LOGE("Warning: couldn't get window object"); + return; + } + + KJS::Bindings::setJavaVM((JavaVM*)javaVM); + + // Add the binding to JS environment + KJS::JSObject *addedObject = + KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::JavaLanguage, + (jobject)objectInstance, root); + + // Add the binding name to the window's table of child objects. + window->put(exec, KJS::Identifier(objectNameStr), addedObject); +} + +/* +* This function executes the provided javascript string in the context of +* the frame's document. The code is based on the implementation of the same +* function in WebCoreFrameBridge.mm +*/ +String FrameAndroid::stringByEvaluatingJavaScriptFromString(const char* script) +{ + ASSERT(document()); + JSValue* result = loader()->executeScript(String(script), true); + if (!result) + return String(); + JSLock lock; + // note: result->getString() returns a UString. + return String(result->isString() ? result->getString() : + result->toString(scriptProxy()->globalObject()->globalExec())); +} + +#if 0 // disabled for now by <reed> +// experimental function to allow portable code to query our bg-ness +bool android_should_draw_background(RenderObject* obj) +{ + Document* doc = obj->document(); + if (doc) { + Frame* frame = doc->frame(); + if (frame) { + Page* page = frame->page(); + if (page) { + frame = page->mainFrame(); + if (frame) { + return AsAndroidFrame(frame)->shouldDrawBackgroundPhase(); + } + } + } + } + return false; +} +#endif + +///////////////!!!!!!!!!!!! MUST COMPLETE THESE + +#define verifiedOk() { } // not a problem that it's not implemented + +// These two functions are called by JavaScript Window.focus() and Window.blur() methods. If +// a window has the window focus method called on it, it should be moved to the top of the +// browser window stack. If blur is called, it is moved to the bottom of the stack. +void FrameAndroid::focusWindow() { verifiedOk(); notImplemented(); } +void FrameAndroid::unfocusWindow() { verifiedOk(); notImplemented(); } + +// This function is called by JavaScript when window.print() is called. It would normally map +// straight to the menu print item. +// It is ok that we don't support this at this time. +void FrameAndroid::print() { verifiedOk(); } + +// These functions are used to interact with the platform's clipboard. It is ok that we don't +// support these at this time as we currently don't support sites that would use this +// functionality. +void FrameAndroid::issueCutCommand() { verifiedOk(); } +void FrameAndroid::issueCopyCommand() { verifiedOk(); } +void FrameAndroid::issuePasteCommand() { verifiedOk(); } +void FrameAndroid::issuePasteAndMatchStyleCommand() { verifiedOk(); } + +// This function seems to switch the two characters around the cursor. +// See WebHTMLView.mm:transpose. +// We are currently not implementing it. +void FrameAndroid::issueTransposeCommand() { verifiedOk(); } + +// These functions are called when JavaScript tries to access the script interface for +// these objects. For Object and Embed, the interface expected from the 'plugin' is +// well defined here: +// http://www.mozilla.org/projects/plugins/npruntime.html +KJS::Bindings::Instance* FrameAndroid::getObjectInstanceForWidget(Widget *) { ASSERT(0); notImplemented(); return 0; } +KJS::Bindings::Instance* FrameAndroid::getEmbedInstanceForWidget(Widget *) { ASSERT(0); notImplemented(); return 0; } +KJS::Bindings::Instance* FrameAndroid::getAppletInstanceForWidget(Widget*) { ASSERT(0); notImplemented(); return 0; } + +// These two functions are used to handle spell checking and context menus on selected text. +// It seems that if the text is selected, and the user tries to change the selection, the +// shouldChange function indicates if it is allowed or not. The second function is used for +// spell checking - check FrameMac.mm implementation for details. +bool FrameAndroid::shouldChangeSelection(Selection const&,Selection const&,EAffinity,bool) const { notImplemented(); return true; } +void FrameAndroid::respondToChangedSelection(Selection const&,bool) { notImplemented(); } + +// This function is called when an textbox needs to find out if it's contents +// is marked. It is used in conjunction with the set method which uses +// NSArray, a Mac specific type. The set method is called whenever text is +// added (not removed) via a single key press (paste does not count) +Range* FrameAndroid::markedTextRange() const { return 0; } + +// This function is called when determining the correct mimetype for a file that is going +// to be POSTed. That is when the form element <input type="file"> is used, and the file is +// being sent the server, the client should set the mimetype of the file. +String FrameAndroid::mimeTypeForFileName(String const&) const { ASSERT(0); notImplemented(); return String(); } + +}; /* WebCore namespace */ diff --git a/WebCore/page/android/FrameAndroid.h b/WebCore/page/android/FrameAndroid.h new file mode 100644 index 0000000..c0948df --- /dev/null +++ b/WebCore/page/android/FrameAndroid.h @@ -0,0 +1,120 @@ +/* +** +** 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 FrameAndroid_H +#define FrameAndroid_H + +#include "CacheBuilder.h" +#include "Frame.h" +#include "FrameLoaderTypes.h" +#include "PlatformGraphicsContext.h" +#include "Plugin.h" +#include "StringHash.h" +#include "WebCoreFrameBridge.h" + +class WebCoreResourceHandleClientBridge; + +namespace KJS { + namespace Bindings { + class RootObject; + } +} + +namespace WebCore { + +class EditCommand; +class MouseEventWithHitTestResults; +class Node; +class ResourceHandle; +class ResourceRequest; +struct LinkArray; +struct LinkArray; + +enum KWQSelectionDirection { + KWQSelectingNext, + KWQSelectingPrevious +}; + +class FrameAndroid : public Frame +{ +public: + FrameAndroid(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*); + virtual ~FrameAndroid(); + + /* WebCoreFrameBridge setter and getter */ + inline void setBridge(android::WebCoreFrameBridge* bridge) + { + Release(m_bridge); + m_bridge = bridge; + Retain(m_bridge); + } + inline android::WebCoreFrameBridge* bridge() const { return m_bridge; } + + virtual void focusWindow(); + virtual void unfocusWindow(); + + virtual Range* markedTextRange() const; + + virtual String mimeTypeForFileName(const String&) const; + + virtual KJS::Bindings::Instance* getEmbedInstanceForWidget(Widget*); + virtual KJS::Bindings::Instance* getObjectInstanceForWidget(Widget*); + virtual KJS::Bindings::Instance* getAppletInstanceForWidget(Widget*); + virtual KJS::Bindings::RootObject* bindingRootObject(); + + virtual void issueCutCommand(); + virtual void issueCopyCommand(); + virtual void issuePasteCommand(); + virtual void issuePasteAndMatchStyleCommand(); + virtual void issueTransposeCommand(); + virtual void respondToChangedSelection(const Selection& oldSelection, bool closeTyping); + virtual bool shouldChangeSelection(const Selection& oldSelection, + const Selection& newSelection, + EAffinity affinity, + bool stillSelecting) const; + + virtual void print(); + + void addJavascriptInterface(void* javaVM, void* objectInstance, const char* objectNameStr); + String stringByEvaluatingJavaScriptFromString(const char* script); + + /* FrameAndroid specific */ + CacheBuilder& getCacheBuilder() { return m_cacheBuilder; } + void select(int, int); + + void cleanupForFullLayout(RenderObject *); + +private: + static void recursiveCleanupForFullLayout(RenderObject *); + + RefPtr<KJS::Bindings::RootObject> m_bindingRoot; // The root object used for objects + // bound outside the context of a plugin. + /* End FrameAndroid specific */ + + android::WebCoreFrameBridge* m_bridge; + CacheBuilder m_cacheBuilder; + friend class CacheBuilder; +}; + +inline FrameAndroid* Android(Frame* frame) { return static_cast<FrameAndroid*>(frame); } +inline const FrameAndroid* Android(const Frame* frame) { return static_cast<const FrameAndroid*>(frame); } + +inline FrameAndroid* AsAndroidFrame(Frame* frame) { return static_cast<FrameAndroid*>(frame); } + +} + +#endif diff --git a/WebCore/page/android/InspectorControllerAndroid.cpp b/WebCore/page/android/InspectorControllerAndroid.cpp new file mode 100644 index 0000000..b39d32b --- /dev/null +++ b/WebCore/page/android/InspectorControllerAndroid.cpp @@ -0,0 +1,77 @@ +/* +** +** 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 "InspectorController.h" +#include "Frame.h" +#include "Node.h" + +/* +// This stub file was created to avoid building and linking in all the +// Inspector codebase. If you would like to enable the Inspector, do the +// following steps: +// 1. Replace this file in WebCore/Makefile.android with the common +// implementation, ie page/InsepctorController.cpp +// 2. Add the JS API files to JavaScriptCore/Makefile.android: +// ? API/JSBase.cpp \ +// API/JSCallbackConstructor.cpp \ +// API/JSCallbackFunction.cpp \ +// API/JSCallbackObject.cpp \ +// API/JSClassRef.cpp \ +// API/JSContextRef.cpp \ +// API/JSObjectRef.cpp \ +// API/JSStringRef.cpp \ +// API/JSValueRef.cpp +// 3. Add the following LOCAL_C_INCLUDES to JavaScriptCore/Makefile.android: +// ?$(LOCAL_PATH)/API \ +// $(LOCAL_PATH)/ForwardingHeaders \ +// $(LOCAL_PATH)/../../WebKit \ +// 4. Rebuild WebKit +// +// Note, for a functional Inspector, you must implement InspectorClientAndroid +*/ + +namespace WebCore { + +struct InspectorResource : public RefCounted<InspectorResource> { +}; + +struct InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> { +}; + +InspectorController::InspectorController(Page*, InspectorClient*) {} +InspectorController::~InspectorController() {} + +void InspectorController::windowScriptObjectAvailable() {} +void InspectorController::didCommitLoad(DocumentLoader*) {} +void InspectorController::identifierForInitialRequest(unsigned long, DocumentLoader*, ResourceRequest const&) {} +void InspectorController::willSendRequest(DocumentLoader*, unsigned long, ResourceRequest&, ResourceResponse const&) {} +void InspectorController::didReceiveResponse(DocumentLoader*, unsigned long, ResourceResponse const&) {} +void InspectorController::didReceiveContentLength(DocumentLoader*, unsigned long, int) {} +void InspectorController::didFinishLoading(DocumentLoader*, unsigned long) {} +void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader*, ResourceRequest const&, ResourceResponse const&, int) {} +void InspectorController::frameDetachedFromParent(Frame*) {} + +void InspectorController::addMessageToConsole(MessageSource, MessageLevel, String const&, unsigned int, String const&) {} +#if ENABLE(DATABASE) +void InspectorController::didOpenDatabase(Database*, String const&, String const&, String const&) {} +#endif +bool InspectorController::enabled() const { return false; } +void InspectorController::inspect(Node*) {} +bool InspectorController::windowVisible() { return false; } + +} diff --git a/WebCore/page/inspector/DocumentPanel.js b/WebCore/page/inspector/DocumentPanel.js index 8528196..770f9ba 100644 --- a/WebCore/page/inspector/DocumentPanel.js +++ b/WebCore/page/inspector/DocumentPanel.js @@ -805,8 +805,9 @@ WebInspector.DOMNodeTreeElement.prototype = { onreveal: function() { - if (this.listItemElement) - this.listItemElement.scrollIntoViewIfNeeded(false); + if (!this.listItemElement || !this.treeOutline) + return; + this.treeOutline.panel.views.dom.treeContentElement.scrollToElement(this.listItemElement); }, onselect: function() diff --git a/WebCore/page/inspector/Resource.js b/WebCore/page/inspector/Resource.js index ed35970..2f87b13 100644 --- a/WebCore/page/inspector/Resource.js +++ b/WebCore/page/inspector/Resource.js @@ -681,8 +681,9 @@ WebInspector.ResourceTreeElement.prototype = { onreveal: function() { - if (this.listItemElement) - this.listItemElement.scrollIntoViewIfNeeded(false); + if (!this.listItemElement || !this.treeOutline || !this.treeOutline.childrenListElement) + return; + this.treeOutline.childrenListElement.scrollToElement(this.listItemElement); } } diff --git a/WebCore/page/inspector/SourcePanel.js b/WebCore/page/inspector/SourcePanel.js index 32d7899..9d4139c 100644 --- a/WebCore/page/inspector/SourcePanel.js +++ b/WebCore/page/inspector/SourcePanel.js @@ -90,7 +90,7 @@ WebInspector.SourcePanel.prototype = { if (!row) return; this.currentView = this.views.source; - row.scrollIntoViewIfNeeded(true); + row.scrollIntoView(true); }, addMessageToSource: function(msg) diff --git a/WebCore/page/inspector/StylesSidebarPane.js b/WebCore/page/inspector/StylesSidebarPane.js index a701a35..915fc1a 100644 --- a/WebCore/page/inspector/StylesSidebarPane.js +++ b/WebCore/page/inspector/StylesSidebarPane.js @@ -218,7 +218,7 @@ WebInspector.StylePropertiesSection = function(styleRule, subtitle, computedStyl this.editable = (editable && !computedStyle); // Prevent editing the user agent rules. - if (this.styleRule.parentStyleSheet && !this.styleRule.parentStyleSheet.ownerNode && !this.styleRule.parentStyleSheet.href) + if (this.styleRule.parentStyleSheet && !this.styleRule.parentStyleSheet.ownerNode) this.editable = false; this._usedProperties = usedProperties; diff --git a/WebCore/page/inspector/inspector.js b/WebCore/page/inspector/inspector.js index a9f5fcf..04e78e6 100644 --- a/WebCore/page/inspector/inspector.js +++ b/WebCore/page/inspector/inspector.js @@ -927,15 +927,15 @@ WebInspector.performSearch = function(query) selection.addRange(element.representedObject.range); WebInspector.navigateToPanel(element.representedObject.panel, "source"); - element.representedObject.line.scrollIntoViewIfNeeded(true); - element.listItemElement.scrollIntoViewIfNeeded(false); + element.representedObject.line.scrollIntoView(true); + resultsContainer.scrollToElement(element.listItemElement); } var domResultSelected = function(element) { WebInspector.navigateToPanel(element.representedObject.panel, "dom"); element.representedObject.panel.focusedDOMNode = element.representedObject.node; - element.listItemElement.scrollIntoViewIfNeeded(false); + resultsContainer.scrollToElement(element.listItemElement); } for (var i = 0; i < files.length; ++i) { diff --git a/WebCore/page/inspector/utilities.js b/WebCore/page/inspector/utilities.js index 47d721f..a92fe4d 100644 --- a/WebCore/page/inspector/utilities.js +++ b/WebCore/page/inspector/utilities.js @@ -123,6 +123,24 @@ Element.prototype.hasStyleClass = function(className) return regex.test(this.className); } +Element.prototype.scrollToElement = function(element) +{ + if (!element || !this.isAncestor(element)) + return; + + var offsetTop = 0; + var current = element + while (current && current !== this) { + offsetTop += current.offsetTop; + current = current.offsetParent; + } + + if (this.scrollTop > offsetTop) + this.scrollTop = offsetTop; + else if ((this.scrollTop + this.offsetHeight) < (offsetTop + element.offsetHeight)) + this.scrollTop = offsetTop - this.offsetHeight + element.offsetHeight; +} + Node.prototype.firstParentOrSelfWithNodeName = function(nodeName) { for (var node = this; node && (node !== document); node = node.parentNode) @@ -407,18 +425,6 @@ function nodeDisplayName() case Node.COMMENT_NODE: return "<!--" + this.nodeValue + "-->"; - - case Node.DOCUMENT_TYPE_NODE: - var docType = "<!DOCTYPE " + this.nodeName; - if (this.publicId) { - docType += " PUBLIC \"" + this.publicId + "\""; - if (this.systemId) - docType += " \"" + this.systemId + "\""; - } else if (this.systemId) - docType += " SYSTEM \"" + this.systemId + "\""; - if (this.internalSubset) - docType += " [" + this.internalSubset + "]"; - return docType + ">"; } return this.nodeName.toLowerCase().collapseWhitespace(); @@ -637,18 +643,6 @@ function nodeTitleInfo(hasChildren, linkify) info.title = "<span class=\"webkit-html-comment\"><!--" + this.nodeValue.escapeHTML() + "--></span>"; break; - case Node.DOCUMENT_TYPE_NODE: - info.title = "<span class=\"webkit-html-tag\"><!DOCTYPE " + this.nodeName; - if (this.publicId) { - info.title += " PUBLIC \"" + this.publicId + "\""; - if (this.systemId) - info.title += " \"" + this.systemId + "\""; - } else if (this.systemId) - info.title += " SYSTEM \"" + this.systemId + "\""; - if (this.internalSubset) - info.title += " [" + this.internalSubset + "]"; - info.title += "></span>"; - break; default: info.title = this.nodeName.toLowerCase().collapseWhitespace().escapeHTML(); } diff --git a/WebCore/page/mac/AXObjectCacheMac.mm b/WebCore/page/mac/AXObjectCacheMac.mm deleted file mode 100644 index 61d0319..0000000 --- a/WebCore/page/mac/AXObjectCacheMac.mm +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 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. - */ - -#import "config.h" -#import "AXObjectCache.h" - -#import "Document.h" -#import "FoundationExtras.h" -#import "RenderObject.h" -#import "WebCoreAXObject.h" -#import "WebCoreViewFactory.h" - -// The simple Cocoa calls in this file don't throw exceptions. - -namespace WebCore { - -struct TextMarkerData { - AXID axID; - Node* node; - int offset; - EAffinity affinity; -}; - -bool AXObjectCache::gAccessibilityEnabled = false; - -AXObjectCache::~AXObjectCache() -{ - HashMap<RenderObject*, WebCoreAXObject*>::iterator end = m_objects.end(); - for (HashMap<RenderObject*, WebCoreAXObject*>::iterator it = m_objects.begin(); it != end; ++it) { - WebCoreAXObject* obj = (*it).second; - [obj detach]; - HardRelease(obj); - } -} - -WebCoreAXObject* AXObjectCache::get(RenderObject* renderer) -{ - WebCoreAXObject* obj = m_objects.get(renderer); - if (obj) - return obj; - - obj = [[WebCoreAXObject alloc] initWithRenderer:renderer]; - HardRetainWithNSRelease(obj); - m_objects.set(renderer, obj); - return obj; -} - -void AXObjectCache::remove(RenderObject* renderer) -{ - WebCoreAXObject* obj = m_objects.take(renderer); - if (!obj) - return; - [obj detach]; - HardRelease(obj); - - ASSERT(m_objects.size() >= m_idsInUse.size()); -} - -AXID AXObjectCache::getAXID(WebCoreAXObject* obj) -{ - // check for already-assigned ID - AXID objID = [obj axObjectID]; - if (objID) { - ASSERT(m_idsInUse.contains(objID)); - return objID; - } - - // generate a new ID - static AXID lastUsedID = 0; - objID = lastUsedID; - do - ++objID; - while (objID == 0 || objID == AXIDHashTraits::deletedValue() || m_idsInUse.contains(objID)); - m_idsInUse.add(objID); - lastUsedID = objID; - [obj setAXObjectID:objID]; - - return objID; -} - -void AXObjectCache::removeAXID(WebCoreAXObject* obj) -{ - AXID objID = [obj axObjectID]; - if (objID == 0) - return; - ASSERT(objID != AXIDHashTraits::deletedValue()); - ASSERT(m_idsInUse.contains(objID)); - [obj setAXObjectID:0]; - m_idsInUse.remove(objID); -} - -WebCoreTextMarker* AXObjectCache::textMarkerForVisiblePosition(const VisiblePosition& visiblePos) -{ - Position deepPos = visiblePos.deepEquivalent(); - Node* domNode = deepPos.node(); - ASSERT(domNode); - if (!domNode) - return nil; - - // locate the renderer, which must exist for a visible dom node - RenderObject* renderer = domNode->renderer(); - ASSERT(renderer); - - // find or create an accessibility object for this renderer - WebCoreAXObject* obj = get(renderer); - - // create a text marker, adding an ID for the WebCoreAXObject if needed - TextMarkerData textMarkerData; - textMarkerData.axID = getAXID(obj); - textMarkerData.node = domNode; - textMarkerData.offset = deepPos.offset(); - textMarkerData.affinity = visiblePos.affinity(); - return [[WebCoreViewFactory sharedFactory] textMarkerWithBytes:&textMarkerData length:sizeof(textMarkerData)]; -} - -VisiblePosition AXObjectCache::visiblePositionForTextMarker(WebCoreTextMarker* textMarker) -{ - TextMarkerData textMarkerData; - - if (![[WebCoreViewFactory sharedFactory] getBytes:&textMarkerData fromTextMarker:textMarker length:sizeof(textMarkerData)]) - return VisiblePosition(); - - // return empty position if the text marker is no longer valid - if (!m_idsInUse.contains(textMarkerData.axID)) - return VisiblePosition(); - - // generate a VisiblePosition from the data we stored earlier - VisiblePosition visiblePos = VisiblePosition(textMarkerData.node, textMarkerData.offset, textMarkerData.affinity); - - // make sure the node and offset still match (catches stale markers). affinity is not critical for this. - Position deepPos = visiblePos.deepEquivalent(); - if (deepPos.node() != textMarkerData.node || deepPos.offset() != textMarkerData.offset) - return VisiblePosition(); - - return visiblePos; -} - -void AXObjectCache::childrenChanged(RenderObject* renderer) -{ - WebCoreAXObject* obj = m_objects.get(renderer); - if (obj) - [obj childrenChanged]; -} - -void AXObjectCache::postNotification(RenderObject* renderer, const String& message) -{ - if (!renderer) - return; - - // notifications for text input objects are sent to that object - // all others are sent to the top WebArea - WebCoreAXObject* obj = [get(renderer) observableObject]; - if (obj) - NSAccessibilityPostNotification(obj, message); - else - NSAccessibilityPostNotification(get(renderer->document()->renderer()), message); -} - -void AXObjectCache::postNotificationToElement(RenderObject* renderer, const String& message) -{ - // send the notification to the specified element itself, not one of its ancestors - if (renderer) - NSAccessibilityPostNotification(get(renderer), message); -} - -void AXObjectCache::handleFocusedUIElementChanged() -{ - [[WebCoreViewFactory sharedFactory] accessibilityHandleFocusChanged]; -} - -} diff --git a/WebCore/page/mac/EventHandlerMac.mm b/WebCore/page/mac/EventHandlerMac.mm index 5c2a979..ca2f94c 100644 --- a/WebCore/page/mac/EventHandlerMac.mm +++ b/WebCore/page/mac/EventHandlerMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 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 @@ -28,11 +28,21 @@ #include "BlockExceptions.h" #include "ClipboardMac.h" +#include "Cursor.h" +#include "Document.h" +#include "DragController.h" #include "EventNames.h" +#include "FloatPoint.h" #include "FocusController.h" +#include "FoundationExtras.h" #include "FrameLoader.h" #include "Frame.h" +#include "FrameTree.h" #include "FrameView.h" +#include "HTMLFrameOwnerElement.h" +#include "HTMLFrameSetElement.h" +#include "HitTestRequest.h" +#include "HitTestResult.h" #include "KeyboardEvent.h" #include "MouseEventWithHitTestResults.h" #include "Page.h" @@ -138,7 +148,7 @@ bool EventHandler::needsKeyboardEventDisambiguationQuirks() const return false; // RSS view needs arrow key keypress events. - if (isSafari && document->url().protocolIs("feed") || document->url().protocolIs("feeds")) + if (isSafari && document->url().startsWith("feed:", false) || document->url().startsWith("feeds:", false)) return true; Settings* settings = m_frame->settings(); if (!settings) diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm index 6f6f096..8a75797 100644 --- a/WebCore/page/mac/FrameMac.mm +++ b/WebCore/page/mac/FrameMac.mm @@ -83,6 +83,7 @@ #import "TextResourceDecoder.h" #import "UserStyleSheetLoader.h" #import "WebCoreFrameBridge.h" +#import "WebCoreSystemInterface.h" #import "WebCoreViewFactory.h" #import "WebDashboardRegion.h" #import "WebScriptObjectPrivate.h" @@ -157,17 +158,17 @@ RegularExpression* regExpForLabels(NSArray* labels) if (cacheHit != NSNotFound) result = regExps.at(cacheHit); else { - String pattern("("); + DeprecatedString pattern("("); unsigned int numLabels = [labels count]; unsigned int i; for (i = 0; i < numLabels; i++) { - String label = [labels objectAtIndex:i]; + DeprecatedString label = DeprecatedString::fromNSString((NSString*)[labels objectAtIndex:i]); bool startsWithWordChar = false; bool endsWithWordChar = false; if (label.length() != 0) { - startsWithWordChar = wordRegExp.search(label.substring(0, 1)) >= 0; - endsWithWordChar = wordRegExp.search(label.substring(label.length() - 1, 1)) >= 0; + startsWithWordChar = wordRegExp.search(label.at(0)) >= 0; + endsWithWordChar = wordRegExp.search(label.at(label.length() - 1)) >= 0; } if (i != 0) @@ -175,11 +176,13 @@ RegularExpression* regExpForLabels(NSArray* labels) // Search for word boundaries only if label starts/ends with "word characters". // If we always searched for word boundaries, this wouldn't work for languages // such as Japanese. - if (startsWithWordChar) + if (startsWithWordChar) { pattern.append("\\b"); + } pattern.append(label); - if (endsWithWordChar) + if (endsWithWordChar) { pattern.append("\\b"); + } } pattern.append(")"); result = new RegularExpression(pattern, false); @@ -222,10 +225,10 @@ NSString* Frame::searchForNSLabelsAboveCell(RegularExpression* regExp, HTMLTable for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) { if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { // For each text chunk, run the regexp - String nodeString = n->nodeValue(); + DeprecatedString nodeString = n->nodeValue().deprecatedString(); int pos = regExp->searchRev(nodeString); if (pos >= 0) - return nodeString.substring(pos, regExp->matchedLength()); + return nodeString.mid(pos, regExp->matchedLength()).getNSString(); } } } @@ -269,13 +272,13 @@ NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element) searchedCellAbove = true; } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { // For each text chunk, run the regexp - String nodeString = n->nodeValue(); + DeprecatedString nodeString = n->nodeValue().deprecatedString(); // add 100 for slop, to make it more likely that we'll search whole nodes if (lengthSearched + nodeString.length() > maxCharsSearched) nodeString = nodeString.right(charsSearchedThreshold - lengthSearched); int pos = regExp->searchRev(nodeString); if (pos >= 0) - return nodeString.substring(pos, regExp->matchedLength()); + return nodeString.mid(pos, regExp->matchedLength()).getNSString(); lengthSearched += nodeString.length(); } @@ -294,14 +297,11 @@ NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element) NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element) { - String name = element->getAttribute(nameAttr); - if (name.isEmpty()) - return nil; - + DeprecatedString name = element->getAttribute(nameAttr).deprecatedString(); // Make numbers and _'s in field names behave like word boundaries, e.g., "address2" - replace(name, RegularExpression("\\d"), " "); + name.replace(RegularExpression("\\d"), " "); name.replace('_', ' '); - + RegularExpression* regExp = regExpForLabels(labels); // Use the largest match we can find in the whole name string int pos; @@ -317,12 +317,12 @@ NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element) bestPos = pos; bestLength = length; } - start = pos + 1; + start = pos+1; } } while (pos != -1); if (bestPos != -1) - return name.substring(bestPos, bestLength); + return name.mid(bestPos, bestLength).getNSString(); return nil; } diff --git a/WebCore/page/mac/GlobalHistoryMac.mm b/WebCore/page/mac/GlobalHistoryMac.mm deleted file mode 100644 index 466f60e..0000000 --- a/WebCore/page/mac/GlobalHistoryMac.mm +++ /dev/null @@ -1,39 +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. - */ - -#import "config.h" -#import "GlobalHistory.h" - -#import "WebCoreHistory.h" - -namespace WebCore { - -bool historyContains(const UChar* characters, unsigned length) -{ - // the other side of the bridge is careful not to throw exceptions here - return [[WebCoreHistory historyProvider] containsURL:characters length:length]; -} - -} // namespace WebCore diff --git a/WebCore/page/mac/WebCoreAXObject.h b/WebCore/page/mac/WebCoreAXObject.h deleted file mode 100644 index 2014ca6..0000000 --- a/WebCore/page/mac/WebCoreAXObject.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2003, 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. - */ - -#import "AXObjectCache.h" - -namespace WebCore { - class HTMLAreaElement; - class RenderObject; -} - -@interface WebCoreAXObject : NSObject -{ - WebCore::RenderObject* m_renderer; - id m_data; - WebCore::HTMLAreaElement* m_areaElement; - NSMutableArray* m_children; - WebCore::AXID m_id; -} - -- (id)initWithRenderer:(WebCore::RenderObject*)renderer; - -- (BOOL)detached; -- (void)detach; - -- (id)data; -- (void)setData:(id)data; - -- (WebCore::AXID)axObjectID; -- (void)setAXObjectID:(WebCore::AXID)axObjectID; -- (void)removeAXObjectID; - -- (WebCoreAXObject*)firstChild; -- (WebCoreAXObject*)lastChild; -- (WebCoreAXObject*)previousSibling; -- (WebCoreAXObject*)nextSibling; -- (WebCoreAXObject*)parentObject; - -- (WebCoreAXObject*)observableObject; - -- (void)childrenChanged; -- (void)clearChildren; - -@end diff --git a/WebCore/page/mac/WebCoreAXObject.mm b/WebCore/page/mac/WebCoreAXObject.mm deleted file mode 100644 index d514b0e..0000000 --- a/WebCore/page/mac/WebCoreAXObject.mm +++ /dev/null @@ -1,2781 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 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. - */ - -#import "config.h" -#import "WebCoreAXObject.h" - -#import "DOMInternal.h" -#import "ColorMac.h" -#import "Document.h" -#import "EventNames.h" -#import "FocusController.h" -#import "Frame.h" -#import "FrameLoader.h" -#import "FrameView.h" -#import "HTMLAreaElement.h" -#import "HTMLCollection.h" -#import "HTMLFrameElementBase.h" -#import "HTMLImageElement.h" -#import "HTMLInputElement.h" -#import "HTMLLabelElement.h" -#import "HTMLMapElement.h" -#import "HTMLNames.h" -#import "HTMLSelectElement.h" -#import "HTMLTextAreaElement.h" -#import "HitTestRequest.h" -#import "HitTestResult.h" -#import "LocalizedStrings.h" -#import "NodeList.h" -#import "Page.h" -#import "RenderImage.h" -#import "RenderListMarker.h" -#import "RenderMenuList.h" -#import "RenderTextControl.h" -#import "RenderTheme.h" -#import "RenderView.h" -#import "RenderWidget.h" -#import "SelectionController.h" -#import "SimpleFontData.h" -#import "TextIterator.h" -#import "WebCoreFrameBridge.h" -#import "WebCoreFrameView.h" -#import "WebCoreObjCExtras.h" -#import "WebCoreViewFactory.h" -#import "htmlediting.h" -#import "kjs_html.h" -#import "visible_units.h" -#include <mach-o/dyld.h> - -using namespace WebCore; -using namespace EventNames; -using namespace HTMLNames; - -@interface WebCoreAXObject (PrivateWebCoreAXObject) -// forward declarations as needed -- (WebCoreTextMarker*)textMarkerForIndex: (NSNumber*) index lastIndexOK: (BOOL)lastIndexOK; -- (id)doAXLineForTextMarker: (WebCoreTextMarker* ) textMarker; -@end - -@implementation WebCoreAXObject - -#ifndef BUILDING_ON_TIGER -+ (void)initialize -{ - WebCoreObjCFinalizeOnMainThread(self); -} -#endif - --(id)initWithRenderer:(RenderObject*)renderer -{ - [super init]; - m_renderer = renderer; - return self; -} - --(BOOL)detached -{ - return !m_renderer; -} - --(void)detach -{ - // Send unregisterUniqueIdForUIElement unconditionally because if it is - // ever accidently not done (via other bugs in our AX implementation) you - // end up with a crash like <rdar://problem/4273149>. It is safe and not - // expensive to send even if the object is not registered. - [[WebCoreViewFactory sharedFactory] unregisterUniqueIdForUIElement:self]; - [m_data release]; - m_data = 0; - [self removeAXObjectID]; - m_renderer = 0; - [self clearChildren]; -} - -- (void)dealloc -{ - [self detach]; - [super dealloc]; -} - -- (void)finalize -{ - [self detach]; - [super finalize]; -} - --(id)data -{ - return m_data; -} - --(void)setData:(id)data -{ - if (!m_renderer) - return; - - [data retain]; - [m_data release]; - m_data = data; -} - --(HTMLAnchorElement*)anchorElement -{ - // return already-known anchor for image areas - if (m_areaElement) - return m_areaElement; - - // search up the render tree for a RenderObject with a DOM node. Defer to an earlier continuation, though. - RenderObject* currRenderer; - for (currRenderer = m_renderer; currRenderer && !currRenderer->element(); currRenderer = currRenderer->parent()) { - if (currRenderer->continuation()) - return [currRenderer->document()->axObjectCache()->get(currRenderer->continuation()) anchorElement]; - } - - // bail of none found - if (!currRenderer) - return 0; - - // search up the DOM tree for an anchor element - // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement - Node* elt = currRenderer->element(); - for ( ; elt; elt = elt->parentNode()) { - if (elt->isLink() && elt->renderer() && !elt->renderer()->isImage()) - return static_cast<HTMLAnchorElement*>(elt); - } - - return 0; -} - --(BOOL)isImageButton -{ - return m_renderer->isImage() && m_renderer->element() && m_renderer->element()->hasTagName(inputTag); -} - --(Element*)mouseButtonListener -{ - // FIXME: Do the continuation search like anchorElement does - for (EventTargetNode* elt = static_cast<EventTargetNode*>(m_renderer->element()); elt; elt = static_cast<EventTargetNode*>(elt->parentNode())) { - if (elt->getHTMLEventListener(clickEvent) || elt->getHTMLEventListener(mousedownEvent) || elt->getHTMLEventListener(mouseupEvent)) - return static_cast<Element*>(elt); - } - - return 0; -} - --(Element*)actionElement -{ - if (m_renderer->element() && m_renderer->element()->hasTagName(inputTag)) { - HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element()); - if (!input->disabled() && (input->inputType() == HTMLInputElement::CHECKBOX || - input->inputType() == HTMLInputElement::RADIO || - input->isTextButton())) - return input; - } - - if ([self isImageButton] || m_renderer->isMenuList()) - return static_cast<Element*>(m_renderer->element()); - - Element* elt = [self anchorElement]; - if (!elt) - elt = [self mouseButtonListener]; - - return elt; -} - --(WebCoreAXObject*)firstChild -{ - if (!m_renderer || !m_renderer->firstChild()) - return nil; - - return m_renderer->document()->axObjectCache()->get(m_renderer->firstChild()); -} - --(WebCoreAXObject*)lastChild -{ - if (!m_renderer || !m_renderer->lastChild()) - return nil; - - return m_renderer->document()->axObjectCache()->get(m_renderer->lastChild()); -} - --(WebCoreAXObject*)previousSibling -{ - if (!m_renderer || !m_renderer->previousSibling()) - return nil; - - return m_renderer->document()->axObjectCache()->get(m_renderer->previousSibling()); -} - --(WebCoreAXObject*)nextSibling -{ - if (!m_renderer || !m_renderer->nextSibling()) - return nil; - - return m_renderer->document()->axObjectCache()->get(m_renderer->nextSibling()); -} - --(WebCoreAXObject*)parentObject -{ - if (m_areaElement) - return m_renderer->document()->axObjectCache()->get(m_renderer); - - if (!m_renderer || !m_renderer->parent()) - return nil; - - return m_renderer->document()->axObjectCache()->get(m_renderer->parent()); -} - --(WebCoreAXObject*)parentObjectUnignored -{ - WebCoreAXObject* obj = [self parentObject]; - if ([obj accessibilityIsIgnored]) - return [obj parentObjectUnignored]; - - return obj; -} - --(void)addChildrenToArray:(NSMutableArray*)array -{ - // nothing to add if there is no RenderObject - if (!m_renderer) - return; - - // try to add RenderWidget's children, but fall thru if there are none - if (m_renderer->isWidget()) { - RenderWidget* renderWidget = static_cast<RenderWidget*>(m_renderer); - Widget* widget = renderWidget->widget(); - if (widget) { - NSArray* childArr = [(widget->getOuterView()) accessibilityAttributeValue: NSAccessibilityChildrenAttribute]; - [array addObjectsFromArray: childArr]; - return; - } - } - - // add all unignored acc children - for (WebCoreAXObject* obj = [self firstChild]; obj; obj = [obj nextSibling]) { - if ([obj accessibilityIsIgnored]) - [obj addChildrenToArray: array]; - else - [array addObject: obj]; - } - - // for a RenderImage, add the <area> elements as individual accessibility objects - if (m_renderer->isImage() && !m_areaElement) { - HTMLMapElement* map = static_cast<RenderImage*>(m_renderer)->imageMap(); - if (map) { - for (Node* current = map->firstChild(); current; current = current->traverseNextNode(map)) { - // add an <area> element for this child if it has a link - // NOTE: can't cache these because they all have the same renderer, which is the cache key, right? - // plus there may be little reason to since they are being added to the handy array - if (current->isLink()) { - WebCoreAXObject* obj = [[[WebCoreAXObject alloc] initWithRenderer: m_renderer] autorelease]; - obj->m_areaElement = static_cast<HTMLAreaElement*>(current); - [array addObject: obj]; - } - } - } - } -} - --(BOOL)isWebArea -{ - return m_renderer->isRenderView(); -} - --(BOOL)isAnchor -{ - return m_areaElement || (!m_renderer->isImage() && m_renderer->element() && m_renderer->element()->isLink()); -} - --(BOOL)isTextControl -{ - return m_renderer->isTextField() || m_renderer->isTextArea(); -} - -static bool isPasswordFieldElement(Node* node) -{ - if (!node || !node->hasTagName(inputTag)) - return false; - - HTMLInputElement* input = static_cast<HTMLInputElement*>(node); - return input->inputType() == HTMLInputElement::PASSWORD; -} - --(BOOL)isPasswordField -{ - return m_renderer && isPasswordFieldElement(m_renderer->element()); -} - --(BOOL)isAttachment -{ - // widgets are the replaced elements that we represent to AX as attachments - BOOL result = m_renderer && m_renderer->isWidget(); - - // assert that a widget is a replaced element that is not an image - ASSERT(!result || (m_renderer->isReplaced() && !m_renderer->isImage())); - return result; -} - --(NSView*)attachmentView -{ - ASSERT(m_renderer->isReplaced() && m_renderer->isWidget() && !m_renderer->isImage()); - - RenderWidget* renderWidget = static_cast<RenderWidget*>(m_renderer); - Widget* widget = renderWidget->widget(); - if (widget) - return widget->getView(); - - return nil; -} - -static int blockquoteLevel(RenderObject* renderer) -{ - int result = 0; - for (Node* node = renderer->element(); node; node = node->parent()) { - if (node->hasTagName(blockquoteTag)) - result += 1; - } - - return result; -} - -static int headingLevel(RenderObject* renderer) -{ - if (!renderer->isBlockFlow()) - return 0; - - Node* node = renderer->element(); - if (!node) - return 0; - - if (node->hasTagName(h1Tag)) - return 1; - - if (node->hasTagName(h2Tag)) - return 2; - - if (node->hasTagName(h3Tag)) - return 3; - - if (node->hasTagName(h4Tag)) - return 4; - - if (node->hasTagName(h5Tag)) - return 5; - - if (node->hasTagName(h6Tag)) - return 6; - - return 0; -} - --(int)headingLevel -{ - return headingLevel(m_renderer); -} - --(BOOL)isHeading -{ - return [self headingLevel] != 0; -} - --(NSString*)role -{ - if (!m_renderer) - return NSAccessibilityUnknownRole; - - if (m_areaElement) - return @"AXLink"; - if (m_renderer->element() && m_renderer->element()->isLink()) { - if (m_renderer->isImage()) - return @"AXImageMap"; - return @"AXLink"; - } - if (m_renderer->isListMarker()) - return @"AXListMarker"; - if (m_renderer->element() && m_renderer->element()->hasTagName(buttonTag)) - return NSAccessibilityButtonRole; - if (m_renderer->isText()) - return NSAccessibilityStaticTextRole; - if (m_renderer->isImage()) { - if ([self isImageButton]) - return NSAccessibilityButtonRole; - return NSAccessibilityImageRole; - } - if ([self isWebArea]) - return @"AXWebArea"; - - if (m_renderer->isTextField()) - return NSAccessibilityTextFieldRole; - - if (m_renderer->isTextArea()) - return NSAccessibilityTextAreaRole; - - if (m_renderer->element() && m_renderer->element()->hasTagName(inputTag)) { - HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element()); - if (input->inputType() == HTMLInputElement::CHECKBOX) - return NSAccessibilityCheckBoxRole; - if (input->inputType() == HTMLInputElement::RADIO) - return NSAccessibilityRadioButtonRole; - if (input->isTextButton()) - return NSAccessibilityButtonRole; - } - - if (m_renderer->isMenuList()) - return NSAccessibilityPopUpButtonRole; - - if ([self isHeading]) - return @"AXHeading"; - - if (m_renderer->isBlockFlow()) - return NSAccessibilityGroupRole; - if ([self isAttachment]) - return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityRoleAttribute]; - - return NSAccessibilityUnknownRole; -} - --(NSString*)subrole -{ - if ([self isPasswordField]) - return NSAccessibilitySecureTextFieldSubrole; - - if ([self isAttachment]) { - NSView* attachmentView = [self attachmentView]; - if ([[attachmentView accessibilityAttributeNames] containsObject:NSAccessibilitySubroleAttribute]) { - return [attachmentView accessibilityAttributeValue:NSAccessibilitySubroleAttribute]; - } - } - - return nil; -} - --(NSString*)roleDescription -{ - if (!m_renderer) - return nil; - - // attachments have the AXImage role, but a different subrole - if ([self isAttachment]) - return [[self attachmentView] accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute]; - - // FIXME 3447564: It would be better to call some AppKit API to get these strings - // (which would be the best way to localize them) - - NSString* role = [self role]; - if ([role isEqualToString:NSAccessibilityButtonRole]) - return NSAccessibilityRoleDescription(NSAccessibilityButtonRole, [self subrole]); - - if ([role isEqualToString:NSAccessibilityPopUpButtonRole]) - return NSAccessibilityRoleDescription(NSAccessibilityPopUpButtonRole, [self subrole]); - - if ([role isEqualToString:NSAccessibilityStaticTextRole]) - return NSAccessibilityRoleDescription(NSAccessibilityStaticTextRole, [self subrole]); - - if ([role isEqualToString:NSAccessibilityImageRole]) - return NSAccessibilityRoleDescription(NSAccessibilityImageRole, [self subrole]); - - if ([role isEqualToString:NSAccessibilityGroupRole]) - return NSAccessibilityRoleDescription(NSAccessibilityGroupRole, [self subrole]); - - if ([role isEqualToString:NSAccessibilityCheckBoxRole]) - return NSAccessibilityRoleDescription(NSAccessibilityCheckBoxRole, [self subrole]); - - if ([role isEqualToString:NSAccessibilityRadioButtonRole]) - return NSAccessibilityRoleDescription(NSAccessibilityRadioButtonRole, [self subrole]); - - if ([role isEqualToString:NSAccessibilityTextFieldRole]) - return NSAccessibilityRoleDescription(NSAccessibilityTextFieldRole, [self subrole]); - - if ([role isEqualToString:NSAccessibilityTextAreaRole]) - return NSAccessibilityRoleDescription(NSAccessibilityTextAreaRole, [self subrole]); - - if ([role isEqualToString:@"AXWebArea"]) - return AXWebAreaText(); - - if ([role isEqualToString:@"AXLink"]) - return AXLinkText(); - - if ([role isEqualToString:@"AXListMarker"]) - return AXListMarkerText(); - - if ([role isEqualToString:@"AXImageMap"]) - return AXImageMapText(); - - if ([role isEqualToString:@"AXHeading"]) - return AXHeadingText(); - - return NSAccessibilityRoleDescription(NSAccessibilityUnknownRole, nil); -} - --(NSString*)helpText -{ - if (!m_renderer) - return nil; - - if (m_areaElement) { - const AtomicString& summary = static_cast<Element*>(m_areaElement)->getAttribute(summaryAttr); - if (!summary.isEmpty()) - return summary; - const AtomicString& title = static_cast<Element*>(m_areaElement)->getAttribute(titleAttr); - if (!title.isEmpty()) - return title; - } - - for (RenderObject* curr = m_renderer; curr; curr = curr->parent()) { - if (curr->element() && curr->element()->isHTMLElement()) { - const AtomicString& summary = static_cast<Element*>(curr->element())->getAttribute(summaryAttr); - if (!summary.isEmpty()) - return summary; - const AtomicString& title = static_cast<Element*>(curr->element())->getAttribute(titleAttr); - if (!title.isEmpty()) - return title; - } - } - - return nil; -} - --(NSString*)textUnderElement -{ - if (!m_renderer) - return nil; - - Node* e = m_renderer->element(); - Document* d = m_renderer->document(); - if (e && d) { - Frame* p = d->frame(); - if (p) { - // catch stale WebCoreAXObject (see <rdar://problem/3960196>) - if (p->document() != d) - return nil; - return plainText(rangeOfContents(e).get()); - } - } - - // return nil for anonymous text because it is non-trivial to get - // the actual text and, so far, that is not needed - return nil; -} - --(id)value -{ - if (!m_renderer || m_areaElement || [self isPasswordField]) - return nil; - - if (m_renderer->isText()) - return [self textUnderElement]; - - if (m_renderer->isMenuList()) - return static_cast<RenderMenuList*>(m_renderer)->text(); - - if (m_renderer->isListMarker()) - return static_cast<RenderListMarker*>(m_renderer)->text(); - - if ([self isWebArea]) { - if (m_renderer->document()->frame()) - return nil; - - // FIXME: should use startOfDocument and endOfDocument (or rangeForDocument?) here - VisiblePosition startVisiblePosition = m_renderer->positionForCoordinates(0, 0); - VisiblePosition endVisiblePosition = m_renderer->positionForCoordinates(INT_MAX, INT_MAX); - if (startVisiblePosition.isNull() || endVisiblePosition.isNull()) - return nil; - - return plainText(makeRange(startVisiblePosition, endVisiblePosition).get()); - } - - if ([self isAttachment]) { - NSView* attachmentView = [self attachmentView]; - if ([[attachmentView accessibilityAttributeNames] containsObject:NSAccessibilityValueAttribute]) - return [attachmentView accessibilityAttributeValue:NSAccessibilityValueAttribute]; - return nil; - } - - if ([self isHeading]) - return [NSNumber numberWithInt:[self headingLevel]]; - - if ([self isTextControl]) - return (NSString*)(static_cast<RenderTextControl*>(m_renderer)->text()); - - if (m_renderer->element() && m_renderer->element()->hasTagName(inputTag)) { - HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element()); - - // Checkboxes return their state as an integer. 0 for off, 1 for on. - if (input->inputType() == HTMLInputElement::CHECKBOX || - input->inputType() == HTMLInputElement::RADIO) - return [NSNumber numberWithInt:input->checked()]; - } - - // FIXME: We might need to implement a value here for more types - // FIXME: It would be better not to advertise a value at all for the types for which we don't implement one; - // this would require subclassing or making accessibilityAttributeNames do something other than return a - // single static array. - return nil; -} - -static HTMLLabelElement* labelForElement(Element* element) -{ - RefPtr<NodeList> list = element->document()->getElementsByTagName("label"); - unsigned len = list->length(); - for (unsigned i = 0; i < len; i++) { - HTMLLabelElement* label = static_cast<HTMLLabelElement*>(list->item(i)); - if (label->correspondingControl() == element) - return label; - } - - return 0; -} - --(NSString*)title -{ - if (!m_renderer || m_areaElement || !m_renderer->element()) - return nil; - - if (m_renderer->element()->hasTagName(buttonTag)) - return [self textUnderElement]; - - if (m_renderer->element()->hasTagName(inputTag)) { - HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element()); - if (input->isTextButton()) - return input->value(); - - HTMLLabelElement* label = labelForElement(input); - if (label) - return label->innerText(); - } - - if (m_renderer->element()->isLink() || [self isHeading]) - return [self textUnderElement]; - - if ([self isAttachment]) { - NSView* attachmentView = [self attachmentView]; - if ([[attachmentView accessibilityAttributeNames] containsObject:NSAccessibilityTitleAttribute]) - return [attachmentView accessibilityAttributeValue:NSAccessibilityTitleAttribute]; - } - - return nil; -} - -- (NSString*)accessibilityDescription -{ - if (!m_renderer || m_areaElement) - return nil; - - if (m_renderer->isImage()) { - if (m_renderer->element() && m_renderer->element()->isHTMLElement()) { - const AtomicString& alt = static_cast<Element*>(m_renderer->element())->getAttribute(altAttr); - if (alt.isEmpty()) - return nil; - return alt; - } - } else if ([self isAttachment]) { - NSView* attachmentView = [self attachmentView]; - if ([[attachmentView accessibilityAttributeNames] containsObject:NSAccessibilityDescriptionAttribute]) - return [attachmentView accessibilityAttributeValue:NSAccessibilityDescriptionAttribute]; - } - - if ([self isWebArea]) { - Document *document = m_renderer->document(); - Node* owner = document->ownerElement(); - if (owner) { - if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) { - HTMLFrameElementBase* frameElement = static_cast<HTMLFrameElementBase*>(owner); - return frameElement->name(); - } else if (owner->isHTMLElement()) { - return static_cast<Element*>(owner)->getAttribute(nameAttr); - } - } else { - owner = document->body(); - if (owner && owner->isHTMLElement()) - return static_cast<Element*>(owner)->getAttribute(nameAttr); - } - } - - return nil; -} - -static IntRect boundingBoxRect(RenderObject* obj) -{ - IntRect rect; - if (obj) { - if (obj->isInlineContinuation()) - obj = obj->element()->renderer(); - Vector<IntRect> rects; - int x, y; - obj->absolutePosition(x, y); - obj->absoluteRects(rects, x, y); - const size_t n = rects.size(); - for (size_t i = 0; i < n; ++i) { - IntRect r = rects[i]; - if (!r.isEmpty()) { - if (obj->style()->hasAppearance()) - theme()->adjustRepaintRect(obj, r); - rect.unite(r); - } - } - } - return rect; -} - --(NSValue*)position -{ - IntRect rect = m_areaElement ? m_areaElement->getRect(m_renderer) : boundingBoxRect(m_renderer); - - // The Cocoa accessibility API wants the lower-left corner. - NSPoint point = NSMakePoint(rect.x(), rect.bottom()); - if (m_renderer && m_renderer->view() && m_renderer->view()->frameView()) { - NSView* view = m_renderer->view()->frameView()->getDocumentView(); - point = [[view window] convertBaseToScreen: [view convertPoint: point toView:nil]]; - } - - return [NSValue valueWithPoint: point]; -} - --(NSValue*)size -{ - IntRect rect = m_areaElement ? m_areaElement->getRect(m_renderer) : boundingBoxRect(m_renderer); - return [NSValue valueWithSize: NSMakeSize(rect.width(), rect.height())]; -} - -// the closest object for an internal anchor --(id)linkedUIElement -{ - if (![self isAnchor]) - return nil; - - HTMLAnchorElement* anchor = [self anchorElement]; - if (!anchor) - return nil; - - KURL linkURL = anchor->href(); - String ref = linkURL.ref(); - if (ref.isEmpty()) - return nil; - - // check if URL is the same as current URL - linkURL.setRef(""); - if (m_renderer->document()->url() != linkURL) - return nil; - - Node* linkedNode = m_renderer->document()->getElementById(ref); - if (!linkedNode) { - linkedNode = m_renderer->document()->anchors()->namedItem(ref, !m_renderer->document()->inCompatMode()); - if (!linkedNode) - return nil; - } - - // the element we find may not be accessible, keep searching until we find a good one - WebCoreAXObject* linkedAXElement = m_renderer->document()->axObjectCache()->get(linkedNode->renderer()); - while (linkedAXElement && [linkedAXElement accessibilityIsIgnored]) { - linkedNode = linkedNode->traverseNextNode(NULL); - if (!linkedNode) - return nil; - linkedAXElement = m_renderer->document()->axObjectCache()->get(linkedNode->renderer()); - } - - return linkedAXElement; -} - -// accessibilityShouldUseUniqueId is an AppKit method we override so that -// objects will be given a unique ID, and therefore allow AppKit to know when they -// become obsolete (e.g. when the user navigates to a new web page, making this one -// unrendered but not deallocated because it is in the back/forward cache). -// It is important to call NSAccessibilityUnregisterUniqueIdForUIElement in the -// appropriate place (e.g. dealloc) to remove these non-retained references from -// AppKit's id mapping tables. We do this in detach by calling unregisterUniqueIdForUIElement. -// -// Registering an object is also required for observing notifications. Only registered objects can be observed. -- (BOOL)accessibilityShouldUseUniqueId { - if (!m_renderer) - return NO; - - if ([self isWebArea]) - return YES; - - if ([self isTextControl]) - return YES; - - return NO; -} - --(BOOL)accessibilityIsIgnored -{ - // ignore invisible element - if (!m_renderer || m_renderer->style()->visibility() != VISIBLE) - return YES; - - // ignore popup menu items because AppKit does - for (RenderObject* parent = m_renderer->parent(); parent; parent = parent->parent()) { - if (parent->isMenuList()) - return YES; - } - - // NOTE: BRs always have text boxes now, so the text box check here can be removed - if (m_renderer->isText()) - return m_renderer->isBR() || !static_cast<RenderText*>(m_renderer)->firstTextBox(); - - // delegate to the attachment - if ([self isAttachment]) - return [[self attachmentView] accessibilityIsIgnored]; - - if (m_areaElement || (m_renderer->element() && m_renderer->element()->isLink())) - return NO; - - // all controls are accessible - if (m_renderer->element() && m_renderer->element()->isControl()) - return NO; - - if (m_renderer->isBlockFlow() && m_renderer->childrenInline()) - return !static_cast<RenderBlock*>(m_renderer)->firstLineBox() && ![self mouseButtonListener]; - - // ignore images seemingly used as spacers - if (m_renderer->isImage()) { - // informal standard is to ignore images with zero-length alt strings - Element* elt = static_cast<Element*>(m_renderer->element()); - if (elt) { - const AtomicString& alt = elt->getAttribute(altAttr); - if (alt.isEmpty() && !alt.isNull()) - return YES; - } - - // check for one-dimensional image - if (m_renderer->height() <= 1 || m_renderer->width() <= 1) - return YES; - - // check whether rendered image was stretched from one-dimensional file image - RenderImage* image = static_cast<RenderImage*>(m_renderer); - if (image->cachedImage()) { - IntSize imageSize = image->cachedImage()->imageSize(); - return (imageSize.height() <= 1 || imageSize.width() <= 1); - } - - return NO; - } - - return (!m_renderer->isListMarker() && ![self isWebArea]); -} - -- (NSArray*)accessibilityAttributeNames -{ - if ([self isAttachment]) - return [[self attachmentView] accessibilityAttributeNames]; - - static NSArray* attributes = nil; - static NSArray* anchorAttrs = nil; - static NSArray* webAreaAttrs = nil; - static NSArray* textAttrs = nil; - NSMutableArray* tempArray; - if (attributes == nil) { - attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute, - NSAccessibilitySubroleAttribute, - NSAccessibilityRoleDescriptionAttribute, - NSAccessibilityChildrenAttribute, - NSAccessibilityHelpAttribute, - NSAccessibilityParentAttribute, - NSAccessibilityPositionAttribute, - NSAccessibilitySizeAttribute, - NSAccessibilityTitleAttribute, - NSAccessibilityDescriptionAttribute, - NSAccessibilityValueAttribute, - NSAccessibilityFocusedAttribute, - NSAccessibilityEnabledAttribute, - NSAccessibilityWindowAttribute, - @"AXSelectedTextMarkerRange", - @"AXStartTextMarker", - @"AXEndTextMarker", - @"AXVisited", - NSAccessibilityLinkedUIElementsAttribute, - nil]; - } - if (anchorAttrs == nil) { - tempArray = [[NSMutableArray alloc] initWithArray:attributes]; - [tempArray addObject: NSAccessibilityURLAttribute]; - anchorAttrs = [[NSArray alloc] initWithArray:tempArray]; - [tempArray release]; - } - if (webAreaAttrs == nil) { - tempArray = [[NSMutableArray alloc] initWithArray:attributes]; - [tempArray addObject: @"AXLinkUIElements"]; - [tempArray addObject: @"AXLoaded"]; - [tempArray addObject: @"AXLayoutCount"]; - webAreaAttrs = [[NSArray alloc] initWithArray:tempArray]; - [tempArray release]; - } - if (textAttrs == nil) { - tempArray = [[NSMutableArray alloc] initWithArray:attributes]; - [tempArray addObject: NSAccessibilityNumberOfCharactersAttribute]; - [tempArray addObject: NSAccessibilitySelectedTextAttribute]; - [tempArray addObject: NSAccessibilitySelectedTextRangeAttribute]; - [tempArray addObject: NSAccessibilityVisibleCharacterRangeAttribute]; - [tempArray addObject: NSAccessibilityInsertionPointLineNumberAttribute]; - textAttrs = [[NSArray alloc] initWithArray:tempArray]; - [tempArray release]; - } - - if (!m_renderer || [self isPasswordField]) - return attributes; - - if ([self isWebArea]) - return webAreaAttrs; - - if ([self isTextControl]) - return textAttrs; - - if ([self isAnchor] || m_renderer->isImage()) - return anchorAttrs; - - return attributes; -} - -- (NSArray*)accessibilityActionNames -{ - static NSArray* actions = nil; - - if (actions == nil) { - if ([self actionElement]) - actions = [[NSArray alloc] initWithObjects: NSAccessibilityPressAction, nil]; - else if ([self isAttachment]) - actions = [[[self attachmentView] accessibilityActionNames] retain]; - } - - return actions; -} - -- (NSString*)accessibilityActionDescription:(NSString*)action -{ - // we have no custom actions - return NSAccessibilityActionDescription(action); -} - -- (void)accessibilityPerformAction:(NSString*)action -{ - if ([action isEqualToString:NSAccessibilityPressAction]) { - if ([self isAttachment]) { - [[self attachmentView] accessibilityPerformAction:action]; - return; - } - - Element* actionElement = [self actionElement]; - if (!actionElement) - return; - if (Frame* f = actionElement->document()->frame()) - f->loader()->resetMultipleFormSubmissionProtection(); - actionElement->accessKeyAction(true); - } -} - -- (WebCoreTextMarkerRange*) textMarkerRangeFromMarkers: (WebCoreTextMarker*) textMarker1 andEndMarker:(WebCoreTextMarker*) textMarker2 -{ - return [[WebCoreViewFactory sharedFactory] textMarkerRangeWithStart:textMarker1 end:textMarker2]; -} - -- (WebCoreTextMarker*) textMarkerForVisiblePosition: (VisiblePosition)visiblePos -{ - if (visiblePos.isNull()) - return nil; - - if (isPasswordFieldElement(visiblePos.deepEquivalent().node())) - return nil; - - return m_renderer->document()->axObjectCache()->textMarkerForVisiblePosition(visiblePos); -} - -- (VisiblePosition) visiblePositionForTextMarker: (WebCoreTextMarker*)textMarker -{ - return m_renderer->document()->axObjectCache()->visiblePositionForTextMarker(textMarker); -} - -- (VisiblePosition) visiblePositionForStartOfTextMarkerRange: (WebCoreTextMarkerRange*)textMarkerRange -{ - return [self visiblePositionForTextMarker:[[WebCoreViewFactory sharedFactory] startOfTextMarkerRange:textMarkerRange]]; -} - -- (VisiblePosition) visiblePositionForEndOfTextMarkerRange: (WebCoreTextMarkerRange*) textMarkerRange -{ - return [self visiblePositionForTextMarker:[[WebCoreViewFactory sharedFactory] endOfTextMarkerRange:textMarkerRange]]; -} - -- (WebCoreTextMarkerRange*) textMarkerRangeFromVisiblePositions: (VisiblePosition) startPosition andEndPos: (VisiblePosition) endPosition -{ - WebCoreTextMarker* startTextMarker = [self textMarkerForVisiblePosition: startPosition]; - WebCoreTextMarker* endTextMarker = [self textMarkerForVisiblePosition: endPosition]; - return [self textMarkerRangeFromMarkers: startTextMarker andEndMarker:endTextMarker]; -} - -- (WebCoreTextMarkerRange*)textMarkerRange -{ - if (!m_renderer) - return nil; - - // construct VisiblePositions for start and end - Node* node = m_renderer->element(); - VisiblePosition visiblePos1 = VisiblePosition(node, 0, VP_DEFAULT_AFFINITY); - VisiblePosition visiblePos2 = VisiblePosition(node, maxDeepOffset(node), VP_DEFAULT_AFFINITY); - - // the VisiblePositions are equal for nodes like buttons, so adjust for that - if (visiblePos1 == visiblePos2) { - visiblePos2 = visiblePos2.next(); - if (visiblePos2.isNull()) - visiblePos2 = visiblePos1; - } - - WebCoreTextMarker* startTextMarker = [self textMarkerForVisiblePosition: visiblePos1]; - WebCoreTextMarker* endTextMarker = [self textMarkerForVisiblePosition: visiblePos2]; - return [self textMarkerRangeFromMarkers: startTextMarker andEndMarker:endTextMarker]; -} - -- (RenderObject*)topRenderer -{ - return m_renderer->document()->topDocument()->renderer(); -} - -- (FrameView*)frameView -{ - return m_renderer->document()->view(); -} - -- (FrameView*)topFrameView -{ - return m_renderer->document()->topDocument()->renderer()->view()->frameView(); -} - -- (id)accessibilityAttributeValue:(NSString*)attributeName -{ - if (!m_renderer) - return nil; - - if ([attributeName isEqualToString: NSAccessibilityRoleAttribute]) - return [self role]; - - if ([attributeName isEqualToString: NSAccessibilitySubroleAttribute]) - return [self subrole]; - - if ([attributeName isEqualToString: NSAccessibilityRoleDescriptionAttribute]) - return [self roleDescription]; - - if ([attributeName isEqualToString: NSAccessibilityParentAttribute]) { - if (m_renderer->isRenderView() && m_renderer->view() && m_renderer->view()->frameView()) - return m_renderer->view()->frameView()->getView(); - return [self parentObjectUnignored]; - } - - if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute]) { - if (!m_children) { - m_children = [NSMutableArray arrayWithCapacity: 8]; - [m_children retain]; - [self addChildrenToArray: m_children]; - } - return m_children; - } - - if ([self isWebArea]) { - if ([attributeName isEqualToString: @"AXLinkUIElements"]) { - NSMutableArray* links = [NSMutableArray arrayWithCapacity: 32]; - RefPtr<HTMLCollection> coll = m_renderer->document()->links(); - Node* curr = coll->firstItem(); - while (curr) { - RenderObject* obj = curr->renderer(); - if (obj) { - WebCoreAXObject* axobj = obj->document()->axObjectCache()->get(obj); - ASSERT([[axobj role] isEqualToString:@"AXLink"]); - if (![axobj accessibilityIsIgnored]) - [links addObject: axobj]; - } - curr = coll->nextItem(); - } - return links; - } - if ([attributeName isEqualToString: @"AXLoaded"]) - return [NSNumber numberWithBool: (!m_renderer->document()->tokenizer())]; - if ([attributeName isEqualToString: @"AXLayoutCount"]) - return [NSNumber numberWithInt: (static_cast<RenderView*>(m_renderer)->frameView()->layoutCount())]; - } - - if ([self isTextControl]) { - RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer); - if ([attributeName isEqualToString: NSAccessibilityNumberOfCharactersAttribute]) - return [self isPasswordField] ? nil : [NSNumber numberWithUnsignedInt: textControl->text().length()]; - if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]) { - if ([self isPasswordField]) - return nil; - NSString* text = textControl->text(); - return [text substringWithRange: NSMakeRange(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart())]; - } - if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) - return [self isPasswordField] ? nil : [NSValue valueWithRange: NSMakeRange(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart())]; - // TODO: Get actual visible range. <rdar://problem/4712101> - if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute]) - return [self isPasswordField] ? nil : [NSValue valueWithRange: NSMakeRange(0, textControl->text().length())]; - if ([attributeName isEqualToString: NSAccessibilityInsertionPointLineNumberAttribute]) { - if ([self isPasswordField] || textControl->selectionStart() != textControl->selectionEnd()) - return nil; - NSNumber* index = [NSNumber numberWithInt: textControl->selectionStart()]; - return [self doAXLineForTextMarker: [self textMarkerForIndex: index lastIndexOK: YES]]; - } - } - - if ([attributeName isEqualToString: NSAccessibilityURLAttribute]) { - if ([self isAnchor]) { - if (HTMLAnchorElement* anchor = [self anchorElement]) { - NSURL *href = anchor->href(); - return href; - } - } else if (m_renderer->isImage() && m_renderer->element() && m_renderer->element()->hasTagName(imgTag)) { - NSURL *src = static_cast<HTMLImageElement*>(m_renderer->element())->src(); - return src; - } - return nil; - } - - if ([attributeName isEqualToString: @"AXVisited"]) - return [NSNumber numberWithBool: m_renderer->style()->pseudoState() == PseudoVisited]; - - if ([attributeName isEqualToString: NSAccessibilityTitleAttribute]) - return [self title]; - - if ([attributeName isEqualToString: NSAccessibilityDescriptionAttribute]) - return [self accessibilityDescription]; - - if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) - return [self value]; - - if ([attributeName isEqualToString: NSAccessibilityHelpAttribute]) - return [self helpText]; - - if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute]) - return [NSNumber numberWithBool: (m_renderer->element() && m_renderer->document()->focusedNode() == m_renderer->element())]; - - if ([attributeName isEqualToString: NSAccessibilityEnabledAttribute]) - return [NSNumber numberWithBool: m_renderer->element() ? m_renderer->element()->isEnabled() : YES]; - - if ([attributeName isEqualToString: NSAccessibilitySizeAttribute]) - return [self size]; - - if ([attributeName isEqualToString: NSAccessibilityPositionAttribute]) - return [self position]; - - if ([attributeName isEqualToString: NSAccessibilityWindowAttribute]) { - if (m_renderer && m_renderer->view() && m_renderer->view()->frameView()) - return [m_renderer->view()->frameView()->getView() window]; - - return nil; - } - - if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"]) { - // get the selection from the document - Selection selection = [self frameView]->frame()->selectionController()->selection(); - if (selection.isNone()) - return nil; - - return (id) [self textMarkerRangeFromVisiblePositions:selection.visibleStart() andEndPos:selection.visibleEnd()]; - } - - if ([attributeName isEqualToString: @"AXStartTextMarker"]) - return (id) [self textMarkerForVisiblePosition: startOfDocument(m_renderer->document())]; - - if ([attributeName isEqualToString: @"AXEndTextMarker"]) - return (id) [self textMarkerForVisiblePosition: endOfDocument(m_renderer->document())]; - - if ([attributeName isEqualToString: NSAccessibilityLinkedUIElementsAttribute]) - return (id) [self linkedUIElement]; - - return nil; -} - -- (NSArray* )accessibilityParameterizedAttributeNames -{ - if ([self isAttachment]) - return nil; - - static NSArray* paramAttrs = nil; - static NSArray* textParamAttrs = nil; - if (paramAttrs == nil) { - paramAttrs = [[NSArray alloc] initWithObjects: - @"AXUIElementForTextMarker", - @"AXTextMarkerRangeForUIElement", - @"AXLineForTextMarker", - @"AXTextMarkerRangeForLine", - @"AXStringForTextMarkerRange", - @"AXTextMarkerForPosition", - @"AXBoundsForTextMarkerRange", - @"AXAttributedStringForTextMarkerRange", - @"AXTextMarkerRangeForUnorderedTextMarkers", - @"AXNextTextMarkerForTextMarker", - @"AXPreviousTextMarkerForTextMarker", - @"AXLeftWordTextMarkerRangeForTextMarker", - @"AXRightWordTextMarkerRangeForTextMarker", - @"AXLeftLineTextMarkerRangeForTextMarker", - @"AXRightLineTextMarkerRangeForTextMarker", - @"AXSentenceTextMarkerRangeForTextMarker", - @"AXParagraphTextMarkerRangeForTextMarker", - @"AXNextWordEndTextMarkerForTextMarker", - @"AXPreviousWordStartTextMarkerForTextMarker", - @"AXNextLineEndTextMarkerForTextMarker", - @"AXPreviousLineStartTextMarkerForTextMarker", - @"AXNextSentenceEndTextMarkerForTextMarker", - @"AXPreviousSentenceStartTextMarkerForTextMarker", - @"AXNextParagraphEndTextMarkerForTextMarker", - @"AXPreviousParagraphStartTextMarkerForTextMarker", - @"AXStyleTextMarkerRangeForTextMarker", - @"AXLengthForTextMarkerRange", - nil]; - } - - if (textParamAttrs == nil) { - NSMutableArray* tempArray = [[NSMutableArray alloc] initWithArray:paramAttrs]; - [tempArray addObject: (NSString*)kAXLineForIndexParameterizedAttribute]; - [tempArray addObject: (NSString*)kAXRangeForLineParameterizedAttribute]; - [tempArray addObject: (NSString*)kAXStringForRangeParameterizedAttribute]; - [tempArray addObject: (NSString*)kAXRangeForPositionParameterizedAttribute]; - [tempArray addObject: (NSString*)kAXRangeForIndexParameterizedAttribute]; - [tempArray addObject: (NSString*)kAXBoundsForRangeParameterizedAttribute]; - [tempArray addObject: (NSString*)kAXRTFForRangeParameterizedAttribute]; - [tempArray addObject: (NSString*)kAXAttributedStringForRangeParameterizedAttribute]; - [tempArray addObject: (NSString*)kAXStyleRangeForIndexParameterizedAttribute]; - textParamAttrs = [[NSArray alloc] initWithArray:tempArray]; - [tempArray release]; - } - - if ([self isPasswordField]) - return [NSArray array]; - - if (!m_renderer) - return paramAttrs; - - if ([self isTextControl]) - return textParamAttrs; - - return paramAttrs; -} - -- (id)doAXUIElementForTextMarker: (WebCoreTextMarker* ) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - RenderObject* obj = visiblePos.deepEquivalent().node()->renderer(); - if (!obj) - return nil; - - return obj->document()->axObjectCache()->get(obj); -} - -- (id)doAXTextMarkerRangeForUIElement: (id) uiElement -{ - return (id)[uiElement textMarkerRange]; -} - -- (id)doAXLineForTextMarker: (WebCoreTextMarker* ) textMarker -{ - unsigned int lineCount = 0; - VisiblePosition savedVisiblePos; - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // move up until we get to the top - // NOTE: BUG This only takes us to the top of the rootEditableElement, not the top of the - // top document. - while (visiblePos.isNotNull() && !(inSameLine(visiblePos, savedVisiblePos))) { - lineCount += 1; - savedVisiblePos = visiblePos; - visiblePos = previousLinePosition(visiblePos, 0); - } - - return [NSNumber numberWithUnsignedInt:(lineCount - 1)]; -} - -- (id)doAXTextMarkerRangeForLine: (NSNumber*) lineNumber -{ - unsigned lineCount = [lineNumber unsignedIntValue]; - if (lineCount == 0 || !m_renderer) - return nil; - - // iterate over the lines - // NOTE: BUG this is wrong when lineNumber is lineCount+1, because nextLinePosition takes you to the - // last offset of the last line - VisiblePosition visiblePos = m_renderer->document()->renderer()->positionForCoordinates(0, 0); - VisiblePosition savedVisiblePos; - while (--lineCount != 0) { - savedVisiblePos = visiblePos; - visiblePos = nextLinePosition(visiblePos, 0); - if (visiblePos.isNull() || visiblePos == savedVisiblePos) - return nil; - } - - // make a caret selection for the marker position, then extend it to the line - // NOTE: ignores results of sel.modify because it returns false when - // starting at an empty line. The resulting selection in that case - // will be a caret at visiblePos. - SelectionController selectionController; - selectionController.setSelection(Selection(visiblePos)); - selectionController.modify(SelectionController::EXTEND, SelectionController::RIGHT, LineBoundary); - - // return a marker range for the selection start to end - VisiblePosition startPosition = selectionController.selection().visibleStart(); - VisiblePosition endPosition = selectionController.selection().visibleEnd(); - return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition]; -} - -static NSString *nsStringForReplacedNode(Node* replacedNode) -{ - // we should always be given a rendered node and a replaced node, but be safe - // replaced nodes are either attachments (widgets) or images - if (!replacedNode || !replacedNode->renderer() || !replacedNode->renderer()->isReplaced() || replacedNode->isTextNode()) { - ASSERT_NOT_REACHED(); - return nil; - } - - // create an AX object, but skip it if it is not supposed to be seen - WebCoreAXObject* obj = replacedNode->renderer()->document()->axObjectCache()->get(replacedNode->renderer()); - if ([obj accessibilityIsIgnored]) - return nil; - - // use the attachmentCharacter to represent the replaced node - const UniChar attachmentChar = NSAttachmentCharacter; - return [NSString stringWithCharacters:&attachmentChar length:1]; -} - -- (id)doAXStringForTextMarkerRange: (WebCoreTextMarkerRange*) textMarkerRange -{ - // extract the start and end VisiblePosition - VisiblePosition startVisiblePosition = [self visiblePositionForStartOfTextMarkerRange: textMarkerRange]; - if (startVisiblePosition.isNull()) - return nil; - - VisiblePosition endVisiblePosition = [self visiblePositionForEndOfTextMarkerRange: textMarkerRange]; - if (endVisiblePosition.isNull()) - return nil; - - NSMutableString* resultString = [[[NSMutableString alloc] init] autorelease]; - TextIterator it(makeRange(startVisiblePosition, endVisiblePosition).get()); - while (!it.atEnd()) { - // non-zero length means textual node, zero length means replaced node (AKA "attachments" in AX) - if (it.length() != 0) { - [resultString appendString:[NSString stringWithCharacters:it.characters() length:it.length()]]; - } else { - // locate the node and starting offset for this replaced range - int exception = 0; - Node* node = it.range()->startContainer(exception); - ASSERT(node == it.range()->endContainer(exception)); - int offset = it.range()->startOffset(exception); - NSString* attachmentString = nsStringForReplacedNode(node->childNode(offset)); - - // append the replacement string - if (attachmentString) - [resultString appendString:attachmentString]; - } - it.advance(); - } - - return [resultString length] > 0 ? resultString : nil; -} - -- (id)doAXTextMarkerForPosition: (NSPoint) point -{ - // convert absolute point to view coordinates - FrameView* frameView = [self topFrameView]; - NSView* view = frameView->getDocumentView(); - RenderObject* renderer = [self topRenderer]; - Node* innerNode = 0; - - // locate the node containing the point - IntPoint pointResult; - while (1) { - // ask the document layer to hitTest - NSPoint windowCoord = [[view window] convertScreenToBase: point]; - IntPoint ourpoint([view convertPoint:windowCoord fromView:nil]); - - HitTestRequest request(true, true); - HitTestResult result(ourpoint); - renderer->layer()->hitTest(request, result); - innerNode = result.innerNode(); - if (!innerNode || !innerNode->renderer()) - return nil; - - pointResult = result.localPoint(); - - // done if hit something other than a widget - renderer = innerNode->renderer(); - if (!renderer->isWidget()) - break; - - // descend into widget (FRAME, IFRAME, OBJECT...) - Widget* widget = static_cast<RenderWidget*>(renderer)->widget(); - if (!widget || !widget->isFrameView()) - break; - Frame* frame = static_cast<FrameView*>(widget)->frame(); - if (!frame) - break; - Document* document = frame->document(); - if (!document) - break; - renderer = document->renderer(); - frameView = static_cast<FrameView*>(widget); - view = frameView->getDocumentView(); - } - - // get position within the node - VisiblePosition pos = innerNode->renderer()->positionForPoint(pointResult); - return (id) [self textMarkerForVisiblePosition:pos]; -} - -- (id)doAXBoundsForTextMarkerRange: (WebCoreTextMarkerRange*) textMarkerRange -{ - // extract the start and end VisiblePosition - VisiblePosition startVisiblePosition = [self visiblePositionForStartOfTextMarkerRange: textMarkerRange]; - if (startVisiblePosition.isNull()) - return nil; - - VisiblePosition endVisiblePosition = [self visiblePositionForEndOfTextMarkerRange: textMarkerRange]; - if (endVisiblePosition.isNull()) - return nil; - - IntRect rect1 = startVisiblePosition.caretRect(); - IntRect rect2 = endVisiblePosition.caretRect(); - - // readjust for position at the edge of a line. This is to exclude line rect that doesn't need to be accounted in the range bounds - if (rect2.y() != rect1.y()) { - VisiblePosition endOfFirstLine = endOfLine(startVisiblePosition); - if (startVisiblePosition == endOfFirstLine) { - startVisiblePosition.setAffinity(DOWNSTREAM); - rect1 = startVisiblePosition.caretRect(); - } - if (endVisiblePosition == endOfFirstLine) { - endVisiblePosition.setAffinity(UPSTREAM); - rect2 = endVisiblePosition.caretRect(); - } - } - - IntRect ourrect = rect1; - ourrect.unite(rect2); - - // try to use the document view from the first position, so that nested WebAreas work, - // but fall back to the top level doc if we do not find it easily - RenderObject* renderer = startVisiblePosition.deepEquivalent().node()->renderer(); - FrameView* frameView = renderer ? renderer->document()->view() : 0; - if (!frameView) - frameView = [self frameView]; - NSView *view = frameView->getView(); - - // if the rectangle spans lines and contains multiple text chars, use the range's bounding box intead - if (rect1.bottom() != rect2.bottom()) { - RefPtr<Range> dataRange = makeRange(startVisiblePosition, endVisiblePosition); - IntRect boundingBox = dataRange->boundingBox(); - String rangeString = plainText(dataRange.get()); - if (rangeString.length() > 1 && !boundingBox.isEmpty()) - ourrect = boundingBox; - } - - // convert our rectangle to screen coordinates - NSRect rect = ourrect; - rect = NSOffsetRect(rect, -frameView->contentsX(), -frameView->contentsY()); - rect = [view convertRect:rect toView:nil]; - rect.origin = [[view window] convertBaseToScreen:rect.origin]; - - // return the converted rect - return [NSValue valueWithRect:rect]; -} - -static CGColorRef CreateCGColorIfDifferent(NSColor* nsColor, CGColorRef existingColor) -{ - // get color information assuming NSDeviceRGBColorSpace - NSColor* rgbColor = [nsColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; - if (rgbColor == nil) - rgbColor = [NSColor blackColor]; - CGFloat components[4]; - [rgbColor getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]]; - - // create a new CGColorRef to return - CGColorSpaceRef cgColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - CGColorRef cgColor = CGColorCreate(cgColorSpace, components); - CGColorSpaceRelease(cgColorSpace); - CFMakeCollectable(cgColor); - - // check for match with existing color - if (existingColor && CGColorEqualToColor(cgColor, existingColor)) - cgColor = nil; - - return cgColor; -} - -static void AXAttributeStringSetColor(NSMutableAttributedString* attrString, NSString* attribute, NSColor* color, NSRange range) -{ - if (color) { - CGColorRef existingColor = (CGColorRef) [attrString attribute:attribute atIndex:range.location effectiveRange:nil]; - CGColorRef cgColor = CreateCGColorIfDifferent(color, existingColor); - if (cgColor) { - [attrString addAttribute:attribute value:(id)cgColor range:range]; - CGColorRelease(cgColor); - } - } else - [attrString removeAttribute:attribute range:range]; -} - -static void AXAttributeStringSetNumber(NSMutableAttributedString* attrString, NSString* attribute, NSNumber* number, NSRange range) -{ - if (number) - [attrString addAttribute:attribute value:number range:range]; - else - [attrString removeAttribute:attribute range:range]; -} - -static void AXAttributeStringSetFont(NSMutableAttributedString* attrString, NSString* attribute, NSFont* font, NSRange range) -{ - NSDictionary* dict; - - if (font) { - dict = [NSDictionary dictionaryWithObjectsAndKeys: - [font fontName] , NSAccessibilityFontNameKey, - [font familyName] , NSAccessibilityFontFamilyKey, - [font displayName] , NSAccessibilityVisibleNameKey, - [NSNumber numberWithFloat:[font pointSize]] , NSAccessibilityFontSizeKey, - nil]; - - [attrString addAttribute:attribute value:dict range:range]; - } else - [attrString removeAttribute:attribute range:range]; - -} - -static void AXAttributeStringSetStyle(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range) -{ - RenderStyle* style = renderer->style(); - - // set basic font info - AXAttributeStringSetFont(attrString, NSAccessibilityFontTextAttribute, style->font().primaryFont()->getNSFont(), range); - - // set basic colors - AXAttributeStringSetColor(attrString, NSAccessibilityForegroundColorTextAttribute, nsColor(style->color()), range); - AXAttributeStringSetColor(attrString, NSAccessibilityBackgroundColorTextAttribute, nsColor(style->backgroundColor()), range); - - // set super/sub scripting - EVerticalAlign alignment = style->verticalAlign(); - if (alignment == SUB) - AXAttributeStringSetNumber(attrString, NSAccessibilitySuperscriptTextAttribute, [NSNumber numberWithInt:(-1)], range); - else if (alignment == SUPER) - AXAttributeStringSetNumber(attrString, NSAccessibilitySuperscriptTextAttribute, [NSNumber numberWithInt:1], range); - else - [attrString removeAttribute:NSAccessibilitySuperscriptTextAttribute range:range]; - - // set shadow - if (style->textShadow()) - AXAttributeStringSetNumber(attrString, NSAccessibilityShadowTextAttribute, [NSNumber numberWithBool:YES], range); - else - [attrString removeAttribute:NSAccessibilityShadowTextAttribute range:range]; - - // set underline and strikethrough - int decor = style->textDecorationsInEffect(); - if ((decor & UNDERLINE) == 0) { - [attrString removeAttribute:NSAccessibilityUnderlineTextAttribute range:range]; - [attrString removeAttribute:NSAccessibilityUnderlineColorTextAttribute range:range]; - } - - if ((decor & LINE_THROUGH) == 0) { - [attrString removeAttribute:NSAccessibilityStrikethroughTextAttribute range:range]; - [attrString removeAttribute:NSAccessibilityStrikethroughColorTextAttribute range:range]; - } - - if ((decor & (UNDERLINE | LINE_THROUGH)) != 0) { - // find colors using quirk mode approach (strict mode would use current - // color for all but the root line box, which would use getTextDecorationColors) - Color underline, overline, linethrough; - renderer->getTextDecorationColors(decor, underline, overline, linethrough); - - if ((decor & UNDERLINE) != 0) { - AXAttributeStringSetNumber(attrString, NSAccessibilityUnderlineTextAttribute, [NSNumber numberWithBool:YES], range); - AXAttributeStringSetColor(attrString, NSAccessibilityUnderlineColorTextAttribute, nsColor(underline), range); - } - - if ((decor & LINE_THROUGH) != 0) { - AXAttributeStringSetNumber(attrString, NSAccessibilityStrikethroughTextAttribute, [NSNumber numberWithBool:YES], range); - AXAttributeStringSetColor(attrString, NSAccessibilityStrikethroughColorTextAttribute, nsColor(linethrough), range); - } - } -} - -static void AXAttributeStringSetHeadingLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range) -{ - int parentHeadingLevel = headingLevel(renderer->parent()); - - if (parentHeadingLevel) - [attrString addAttribute:@"AXHeadingLevel" value:[NSNumber numberWithInt:parentHeadingLevel] range:range]; - else - [attrString removeAttribute:@"AXHeadingLevel" range:range]; -} - -static void AXAttributeStringSetBlockquoteLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range) -{ - int quoteLevel = blockquoteLevel(renderer); - - if (quoteLevel) - [attrString addAttribute:@"AXBlockQuoteLevel" value:[NSNumber numberWithInt:quoteLevel] range:range]; - else - [attrString removeAttribute:@"AXBlockQuoteLevel" range:range]; -} - -static void AXAttributeStringSetElement(NSMutableAttributedString* attrString, NSString* attribute, id element, NSRange range) -{ - if (element) { - // make a serialiazable AX object - AXUIElementRef axElement = [[WebCoreViewFactory sharedFactory] AXUIElementForElement:element]; - if (axElement) { - [attrString addAttribute:attribute value:(id)axElement range:range]; - CFRelease(axElement); - } - } else - [attrString removeAttribute:attribute range:range]; -} - -static WebCoreAXObject* AXLinkElementForNode (Node* node) -{ - RenderObject* obj = node->renderer(); - if (!obj) - return nil; - - WebCoreAXObject* axObj = obj->document()->axObjectCache()->get(obj); - HTMLAnchorElement* anchor = [axObj anchorElement]; - if (!anchor || !anchor->renderer()) - return nil; - - return anchor->renderer()->document()->axObjectCache()->get(anchor->renderer()); -} - -static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString, Node* node, int offset, NSRange range) -{ - Vector<DocumentMarker> markers = node->renderer()->document()->markersForNode(node); - Vector<DocumentMarker>::iterator markerIt = markers.begin(); - - unsigned endOffset = (unsigned)offset + range.length; - for ( ; markerIt != markers.end(); markerIt++) { - DocumentMarker marker = *markerIt; - - if (marker.type != DocumentMarker::Spelling) - continue; - - if (marker.endOffset <= (unsigned)offset) - continue; - - if (marker.startOffset > endOffset) - break; - - // add misspelling attribute for the intersection of the marker and the range - int rStart = range.location + (marker.startOffset - offset); - int rLength = MIN(marker.endOffset, endOffset) - marker.startOffset; - NSRange spellRange = NSMakeRange(rStart, rLength); - AXAttributeStringSetNumber(attrString, NSAccessibilityMisspelledTextAttribute, [NSNumber numberWithBool:YES], spellRange); - - if (marker.endOffset > endOffset + 1) - break; - } -} - -static void AXAttributedStringAppendText(NSMutableAttributedString* attrString, Node* node, int offset, const UChar* chars, int length) -{ - // skip invisible text - if (!node->renderer()) - return; - - // easier to calculate the range before appending the string - NSRange attrStringRange = NSMakeRange([attrString length], length); - - // append the string from this node - [[attrString mutableString] appendString:[NSString stringWithCharacters:chars length:length]]; - - // add new attributes and remove irrelevant inherited ones - // NOTE: color attributes are handled specially because -[NSMutableAttributedString addAttribute: value: range:] does not merge - // identical colors. Workaround is to not replace an existing color attribute if it matches what we are adding. This also means - // we cannot just pre-remove all inherited attributes on the appended string, so we have to remove the irrelevant ones individually. - - // remove inherited attachment from prior AXAttributedStringAppendReplaced - [attrString removeAttribute:NSAccessibilityAttachmentTextAttribute range:attrStringRange]; - - // set new attributes - AXAttributeStringSetStyle(attrString, node->renderer(), attrStringRange); - AXAttributeStringSetHeadingLevel(attrString, node->renderer(), attrStringRange); - AXAttributeStringSetBlockquoteLevel(attrString, node->renderer(), attrStringRange); - AXAttributeStringSetElement(attrString, NSAccessibilityLinkTextAttribute, AXLinkElementForNode(node), attrStringRange); - - // do spelling last because it tends to break up the range - AXAttributeStringSetSpelling(attrString, node, offset, attrStringRange); -} - -- (id)doAXAttributedStringForTextMarkerRange: (WebCoreTextMarkerRange*) textMarkerRange -{ - // extract the start and end VisiblePosition - VisiblePosition startVisiblePosition = [self visiblePositionForStartOfTextMarkerRange: textMarkerRange]; - if (startVisiblePosition.isNull()) - return nil; - - VisiblePosition endVisiblePosition = [self visiblePositionForEndOfTextMarkerRange: textMarkerRange]; - if (endVisiblePosition.isNull()) - return nil; - - // iterate over the range to build the AX attributed string - NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] init]; - TextIterator it(makeRange(startVisiblePosition, endVisiblePosition).get()); - while (!it.atEnd()) { - // locate the node and starting offset for this range - int exception = 0; - Node* node = it.range()->startContainer(exception); - ASSERT(node == it.range()->endContainer(exception)); - int offset = it.range()->startOffset(exception); - - // non-zero length means textual node, zero length means replaced node (AKA "attachments" in AX) - if (it.length() != 0) { - AXAttributedStringAppendText(attrString, node, offset, it.characters(), it.length()); - } else { - Node* replacedNode = node->childNode(offset); - NSString *attachmentString = nsStringForReplacedNode(replacedNode); - if (attachmentString) { - NSRange attrStringRange = NSMakeRange([attrString length], [attachmentString length]); - - // append the placeholder string - [[attrString mutableString] appendString:attachmentString]; - - // remove all inherited attributes - [attrString setAttributes:nil range:attrStringRange]; - - // add the attachment attribute - WebCoreAXObject* obj = replacedNode->renderer()->document()->axObjectCache()->get(replacedNode->renderer()); - AXAttributeStringSetElement(attrString, NSAccessibilityAttachmentTextAttribute, obj, attrStringRange); - } - } - it.advance(); - } - - return [attrString autorelease]; -} - -- (id)doAXTextMarkerRangeForUnorderedTextMarkers: (NSArray*) markers -{ - // get and validate the markers - if ([markers count] < 2) - return nil; - - WebCoreTextMarker* textMarker1 = (WebCoreTextMarker*) [markers objectAtIndex:0]; - WebCoreTextMarker* textMarker2 = (WebCoreTextMarker*) [markers objectAtIndex:1]; - if (![[WebCoreViewFactory sharedFactory] objectIsTextMarker:textMarker1] || ![[WebCoreViewFactory sharedFactory] objectIsTextMarker:textMarker2]) - return nil; - - // convert to VisiblePosition - VisiblePosition visiblePos1 = [self visiblePositionForTextMarker:textMarker1]; - VisiblePosition visiblePos2 = [self visiblePositionForTextMarker:textMarker2]; - if (visiblePos1.isNull() || visiblePos2.isNull()) - return nil; - - WebCoreTextMarker* startTextMarker; - WebCoreTextMarker* endTextMarker; - bool alreadyInOrder; - - // upstream is ordered before downstream for the same position - if (visiblePos1 == visiblePos2 && visiblePos2.affinity() == UPSTREAM) - alreadyInOrder = false; - - // use selection order to see if the positions are in order - else - alreadyInOrder = Selection(visiblePos1, visiblePos2).isBaseFirst(); - - if (alreadyInOrder) { - startTextMarker = textMarker1; - endTextMarker = textMarker2; - } else { - startTextMarker = textMarker2; - endTextMarker = textMarker1; - } - - return (id) [self textMarkerRangeFromMarkers: startTextMarker andEndMarker:endTextMarker]; -} - -- (id)doAXNextTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - VisiblePosition nextVisiblePos = visiblePos.next(); - if (nextVisiblePos.isNull()) - return nil; - - return (id) [self textMarkerForVisiblePosition:nextVisiblePos]; -} - -- (id)doAXPreviousTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - VisiblePosition previousVisiblePos = visiblePos.previous(); - if (previousVisiblePos.isNull()) - return nil; - - return (id) [self textMarkerForVisiblePosition:previousVisiblePos]; -} - -- (id)doAXLeftWordTextMarkerRangeForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - VisiblePosition startPosition = startOfWord(visiblePos, LeftWordIfOnBoundary); - VisiblePosition endPosition = endOfWord(startPosition); - - return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition]; -} - -- (id)doAXRightWordTextMarkerRangeForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - VisiblePosition startPosition = startOfWord(visiblePos, RightWordIfOnBoundary); - VisiblePosition endPosition = endOfWord(startPosition); - - return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition]; -} - - -static VisiblePosition updateAXLineStartForVisiblePosition(const VisiblePosition& visiblePosition) -{ - // A line in the accessibility sense should include floating objects, such as aligned image, as part of a line. - // So let's update the position to include that. - VisiblePosition tempPosition; - VisiblePosition startPosition = visiblePosition; - Position p; - RenderObject* renderer; - while (true) { - tempPosition = startPosition.previous(); - if (tempPosition.isNull()) - break; - p = tempPosition.deepEquivalent(); - if (!p.node()) - break; - renderer = p.node()->renderer(); - if (!renderer || renderer->inlineBox(p.offset(), tempPosition.affinity()) || (renderer->isRenderBlock() && p.offset() == 0)) - break; - startPosition = tempPosition; - } - - return startPosition; -} - -- (id)doAXLeftLineTextMarkerRangeForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // make a caret selection for the position before marker position (to make sure - // we move off of a line start) - VisiblePosition prevVisiblePos = visiblePos.previous(); - if (prevVisiblePos.isNull()) - return nil; - - VisiblePosition startPosition = startOfLine(prevVisiblePos); - - // keep searching for a valid line start position. Unless the textmarker is at the very beginning, there should - // always be a valid line range. However, startOfLine will return null for position next to a floating object, - // since floating object doesn't really belong to any line. - // This check will reposition the marker before the floating object, to ensure we get a line start. - if (startPosition.isNull()) { - while (startPosition.isNull() && prevVisiblePos.isNotNull()) { - prevVisiblePos = prevVisiblePos.previous(); - startPosition = startOfLine(prevVisiblePos); - } - } else - startPosition = updateAXLineStartForVisiblePosition(startPosition); - - VisiblePosition endPosition = endOfLine(prevVisiblePos); - return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition]; -} - -- (id)doAXRightLineTextMarkerRangeForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // make sure we move off of a line end - VisiblePosition nextVisiblePos = visiblePos.next(); - if (nextVisiblePos.isNull()) - return nil; - - VisiblePosition startPosition = startOfLine(nextVisiblePos); - - // fetch for a valid line start position - if (startPosition.isNull() ) { - startPosition = visiblePos; - nextVisiblePos = nextVisiblePos.next(); - } else - startPosition = updateAXLineStartForVisiblePosition(startPosition); - - VisiblePosition endPosition = endOfLine(nextVisiblePos); - - // as long as the position hasn't reached the end of the doc, keep searching for a valid line end position - // Unless the textmarker is at the very end, there should always be a valid line range. However, endOfLine will - // return null for position by a floating object, since floating object doesn't really belong to any line. - // This check will reposition the marker after the floating object, to ensure we get a line end. - while (endPosition.isNull() && nextVisiblePos.isNotNull()) { - nextVisiblePos = nextVisiblePos.next(); - endPosition = endOfLine(nextVisiblePos); - } - - return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition]; -} - -- (id)doAXSentenceTextMarkerRangeForTextMarker: (WebCoreTextMarker*) textMarker -{ - // NOTE: BUG FO 2 IMPLEMENT (currently returns incorrect answer) - // Related? <rdar://problem/3927736> Text selection broken in 8A336 - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - VisiblePosition startPosition = startOfSentence(visiblePos); - VisiblePosition endPosition = endOfSentence(startPosition); - return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition]; -} - -- (id)doAXParagraphTextMarkerRangeForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - VisiblePosition startPosition = startOfParagraph(visiblePos); - VisiblePosition endPosition = endOfParagraph(startPosition); - return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition]; -} - -- (id)doAXNextWordEndTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // make sure we move off of a word end - visiblePos = visiblePos.next(); - if (visiblePos.isNull()) - return nil; - - VisiblePosition endPosition = endOfWord(visiblePos, LeftWordIfOnBoundary); - return (id) [self textMarkerForVisiblePosition:endPosition]; -} - -- (id)doAXPreviousWordStartTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // make sure we move off of a word start - visiblePos = visiblePos.previous(); - if (visiblePos.isNull()) - return nil; - - VisiblePosition startPosition = startOfWord(visiblePos, RightWordIfOnBoundary); - return (id) [self textMarkerForVisiblePosition:startPosition]; -} - -- (id)doAXNextLineEndTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // to make sure we move off of a line end - VisiblePosition nextVisiblePos = visiblePos.next(); - if (nextVisiblePos.isNull()) - return nil; - - VisiblePosition endPosition = endOfLine(nextVisiblePos); - - // as long as the position hasn't reached the end of the doc, keep searching for a valid line end position - // There are cases like when the position is next to a floating object that'll return null for end of line. This code will avoid returning null. - while (endPosition.isNull() && nextVisiblePos.isNotNull()) { - nextVisiblePos = nextVisiblePos.next(); - endPosition = endOfLine(nextVisiblePos); - } - - return (id) [self textMarkerForVisiblePosition: endPosition]; -} - -- (id)doAXPreviousLineStartTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // make sure we move off of a line start - VisiblePosition prevVisiblePos = visiblePos.previous(); - if (prevVisiblePos.isNull()) - return nil; - - VisiblePosition startPosition = startOfLine(prevVisiblePos); - - // as long as the position hasn't reached the beginning of the doc, keep searching for a valid line start position - // There are cases like when the position is next to a floating object that'll return null for start of line. This code will avoid returning null. - if (startPosition.isNull()) { - while (startPosition.isNull() && prevVisiblePos.isNotNull()) { - prevVisiblePos = prevVisiblePos.previous(); - startPosition = startOfLine(prevVisiblePos); - } - } else - startPosition = updateAXLineStartForVisiblePosition(startPosition); - - return (id) [self textMarkerForVisiblePosition: startPosition]; -} - -- (id)doAXNextSentenceEndTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - // NOTE: BUG FO 2 IMPLEMENT (currently returns incorrect answer) - // Related? <rdar://problem/3927736> Text selection broken in 8A336 - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // make sure we move off of a sentence end - VisiblePosition nextVisiblePos = visiblePos.next(); - if (nextVisiblePos.isNull()) - return nil; - - // an empty line is considered a sentence. If it's skipped, then the sentence parser will not - // see this empty line. Instead, return the end position of the empty line. - VisiblePosition endPosition; - String lineString = plainText(makeRange(startOfLine(visiblePos), endOfLine(visiblePos)).get()); - if (lineString.isEmpty()) - endPosition = nextVisiblePos; - else - endPosition = endOfSentence(nextVisiblePos); - - return (id) [self textMarkerForVisiblePosition: endPosition]; -} - -- (id)doAXPreviousSentenceStartTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - // NOTE: BUG FO 2 IMPLEMENT (currently returns incorrect answer) - // Related? <rdar://problem/3927736> Text selection broken in 8A336 - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // make sure we move off of a sentence start - VisiblePosition previousVisiblePos = visiblePos.previous(); - if (previousVisiblePos.isNull()) - return nil; - - // treat empty line as a separate sentence. - VisiblePosition startPosition; - String lineString = plainText(makeRange(startOfLine(previousVisiblePos), endOfLine(previousVisiblePos)).get()); - if (lineString.isEmpty()) - startPosition = previousVisiblePos; - else - startPosition = startOfSentence(previousVisiblePos); - - return (id) [self textMarkerForVisiblePosition: startPosition]; -} - -- (id)doAXNextParagraphEndTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // make sure we move off of a paragraph end - visiblePos = visiblePos.next(); - if (visiblePos.isNull()) - return nil; - - VisiblePosition endPosition = endOfParagraph(visiblePos); - return (id) [self textMarkerForVisiblePosition: endPosition]; -} - -- (id)doAXPreviousParagraphStartTextMarkerForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - // make sure we move off of a paragraph start - visiblePos = visiblePos.previous(); - if (visiblePos.isNull()) - return nil; - - VisiblePosition startPosition = startOfParagraph(visiblePos); - return (id) [self textMarkerForVisiblePosition: startPosition]; -} - -static VisiblePosition startOfStyleRange (const VisiblePosition visiblePos) -{ - RenderObject* renderer = visiblePos.deepEquivalent().node()->renderer(); - RenderObject* startRenderer = renderer; - RenderStyle* style = renderer->style(); - - // traverse backward by renderer to look for style change - for (RenderObject* r = renderer->previousInPreOrder(); r; r = r->previousInPreOrder()) { - // skip non-leaf nodes - if (r->firstChild()) - continue; - - // stop at style change - if (r->style() != style) - break; - - // remember match - startRenderer = r; - } - - return VisiblePosition(startRenderer->node(), 0, VP_DEFAULT_AFFINITY); -} - -static VisiblePosition endOfStyleRange (const VisiblePosition visiblePos) -{ - RenderObject* renderer = visiblePos.deepEquivalent().node()->renderer(); - RenderObject* endRenderer = renderer; - RenderStyle* style = renderer->style(); - - // traverse forward by renderer to look for style change - for (RenderObject* r = renderer->nextInPreOrder(); r; r = r->nextInPreOrder()) { - // skip non-leaf nodes - if (r->firstChild()) - continue; - - // stop at style change - if (r->style() != style) - break; - - // remember match - endRenderer = r; - } - - return VisiblePosition(endRenderer->node(), maxDeepOffset(endRenderer->node()), VP_DEFAULT_AFFINITY); -} - -- (id)doAXStyleTextMarkerRangeForTextMarker: (WebCoreTextMarker*) textMarker -{ - VisiblePosition visiblePos = [self visiblePositionForTextMarker:textMarker]; - if (visiblePos.isNull()) - return nil; - - VisiblePosition startPosition = startOfStyleRange(visiblePos); - VisiblePosition endPosition = endOfStyleRange(visiblePos); - return (id) [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition]; -} - -- (id)doAXLengthForTextMarkerRange: (WebCoreTextMarkerRange*) textMarkerRange -{ - // NOTE: BUG Multi-byte support - CFStringRef string = (CFStringRef) [self doAXStringForTextMarkerRange: textMarkerRange]; - if (!string) - return nil; - - return [NSNumber numberWithInt:CFStringGetLength(string)]; -} - -// NOTE: Consider providing this utility method as AX API -- (WebCoreTextMarker*)textMarkerForIndex: (NSNumber*) index lastIndexOK: (BOOL)lastIndexOK -{ - ASSERT(m_renderer->isTextField() || m_renderer->isTextArea()); - RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer); - unsigned int indexValue = [index unsignedIntValue]; - - // lastIndexOK specifies whether the position after the last character is acceptable - if (indexValue >= textControl->text().length()) { - if (!lastIndexOK || indexValue > textControl->text().length()) - return nil; - } - VisiblePosition position = textControl->visiblePositionForIndex(indexValue); - position.setAffinity(DOWNSTREAM); - return [self textMarkerForVisiblePosition: position]; -} - -// NOTE: Consider providing this utility method as AX API -- (NSNumber*)indexForTextMarker: (WebCoreTextMarker*) marker -{ - ASSERT(m_renderer->isTextField() || m_renderer->isTextArea()); - RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer); - - VisiblePosition position = [self visiblePositionForTextMarker: marker]; - Node* node = position.deepEquivalent().node(); - if (!node) - return nil; - - for (RenderObject* renderer = node->renderer(); renderer && renderer->element(); renderer = renderer->parent()) { - if (renderer == textControl) - return [NSNumber numberWithInt: textControl->indexForVisiblePosition(position)]; - } - - return nil; -} - -// NOTE: Consider providing this utility method as AX API -- (WebCoreTextMarkerRange*)textMarkerRangeForRange: (NSRange) range -{ - ASSERT(m_renderer->isTextField() || m_renderer->isTextArea()); - RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer); - if (range.location + range.length > textControl->text().length()) - return nil; - - VisiblePosition startPosition = textControl->visiblePositionForIndex(range.location); - startPosition.setAffinity(DOWNSTREAM); - VisiblePosition endPosition = textControl->visiblePositionForIndex(range.location + range.length); - return [self textMarkerRangeFromVisiblePositions:startPosition andEndPos:endPosition]; -} - -// NOTE: Consider providing this utility method as AX API -- (NSValue*)rangeForTextMarkerRange: (WebCoreTextMarkerRange*) textMarkerRange -{ - WebCoreTextMarker* textMarker1 = [[WebCoreViewFactory sharedFactory] startOfTextMarkerRange:textMarkerRange]; - WebCoreTextMarker* textMarker2 = [[WebCoreViewFactory sharedFactory] endOfTextMarkerRange:textMarkerRange]; - NSNumber* index1 = [self indexForTextMarker: textMarker1]; - NSNumber* index2 = [self indexForTextMarker: textMarker2]; - if (!index1 || !index2 || [index1 unsignedIntValue] > [index2 unsignedIntValue]) - return nil; - - return [NSValue valueWithRange: NSMakeRange([index1 unsignedIntValue], [index2 unsignedIntValue] - [index1 unsignedIntValue])]; -} - -// Given an indexed character, the line number of the text associated with this accessibility -// object that contains the character. -- (id)doAXLineForIndex: (NSNumber*) index -{ - return [self doAXLineForTextMarker: [self textMarkerForIndex: index lastIndexOK: NO]]; -} - -// Given a line number, the range of characters of the text associated with this accessibility -// object that contains the line number. -- (id)doAXRangeForLine: (NSNumber*) lineNumber -{ - ASSERT(m_renderer->isTextField() || m_renderer->isTextArea()); - RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer); - - // iterate to the specified line - VisiblePosition visiblePos = textControl->visiblePositionForIndex(0); - VisiblePosition savedVisiblePos; - for (unsigned lineCount = [lineNumber unsignedIntValue]; lineCount != 0; lineCount -= 1) { - savedVisiblePos = visiblePos; - visiblePos = nextLinePosition(visiblePos, 0); - if (visiblePos.isNull() || visiblePos == savedVisiblePos) - return nil; - } - - // make a caret selection for the marker position, then extend it to the line - // NOTE: ignores results of selectionController.modify because it returns false when - // starting at an empty line. The resulting selection in that case - // will be a caret at visiblePos. - SelectionController selectionController; - selectionController.setSelection(Selection(visiblePos)); - selectionController.modify(SelectionController::EXTEND, SelectionController::LEFT, LineBoundary); - selectionController.modify(SelectionController::EXTEND, SelectionController::RIGHT, LineBoundary); - - // calculate the indices for the selection start and end - VisiblePosition startPosition = selectionController.selection().visibleStart(); - VisiblePosition endPosition = selectionController.selection().visibleEnd(); - int index1 = textControl->indexForVisiblePosition(startPosition); - int index2 = textControl->indexForVisiblePosition(endPosition); - - // add one to the end index for a line break not caused by soft line wrap (to match AppKit) - if (endPosition.affinity() == DOWNSTREAM && endPosition.next().isNotNull()) - index2 += 1; - - // return nil rather than an zero-length range (to match AppKit) - if (index1 == index2) - return nil; - - return [NSValue valueWithRange: NSMakeRange(index1, index2 - index1)]; -} - -// A substring of the text associated with this accessibility object that is -// specified by the given character range. -- (id)doAXStringForRange: (NSRange) range -{ - if ([self isPasswordField]) - return nil; - - if (range.length == 0) - return @""; - - ASSERT(m_renderer->isTextField() || m_renderer->isTextArea()); - RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer); - String text = textControl->text(); - if (range.location + range.length > text.length()) - return nil; - - return text.substring(range.location, range.length); -} - -// The composed character range in the text associated with this accessibility object that -// is specified by the given screen coordinates. This parameterized attribute returns the -// complete range of characters (including surrogate pairs of multi-byte glyphs) at the given -// screen coordinates. -// NOTE: This varies from AppKit when the point is below the last line. AppKit returns an -// an error in that case. We return textControl->text().length(), 1. Does this matter? -- (id)doAXRangeForPosition: (NSPoint) point -{ - NSNumber* index = [self indexForTextMarker: [self doAXTextMarkerForPosition: point]]; - if (!index) - return nil; - - return [NSValue valueWithRange: NSMakeRange([index unsignedIntValue], 1)]; -} - -// The composed character range in the text associated with this accessibility object that -// is specified by the given index value. This parameterized attribute returns the complete -// range of characters (including surrogate pairs of multi-byte glyphs) at the given index. -- (id)doAXRangeForIndex: (NSNumber*) number -{ - ASSERT(m_renderer->isTextField() || m_renderer->isTextArea()); - RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer); - String text = textControl->text(); - if (!text.length() || [number unsignedIntValue] > text.length() - 1) - return nil; - - return [NSValue valueWithRange: NSMakeRange([number unsignedIntValue], 1)]; -} - -// The bounding rectangle of the text associated with this accessibility object that is -// specified by the given range. This is the bounding rectangle a sighted user would see -// on the display screen, in pixels. -- (id)doAXBoundsForRange: (NSRange) range -{ - return [self doAXBoundsForTextMarkerRange: [self textMarkerRangeForRange:range]]; -} - -// The CFAttributedStringType representation of the text associated with this accessibility -// object that is specified by the given range. -- (id)doAXAttributedStringForRange: (NSRange) range -{ - return [self doAXAttributedStringForTextMarkerRange: [self textMarkerRangeForRange:range]]; -} - -// The RTF representation of the text associated with this accessibility object that is -// specified by the given range. -- (id)doAXRTFForRange: (NSRange) range -{ - NSAttributedString* attrString = [self doAXAttributedStringForRange: range]; - return [attrString RTFFromRange: NSMakeRange(0, [attrString length]) documentAttributes: nil]; -} - -// Given a character index, the range of text associated with this accessibility object -// over which the style in effect at that character index applies. -- (id)doAXStyleRangeForIndex: (NSNumber*) index -{ - WebCoreTextMarkerRange* textMarkerRange = [self doAXStyleTextMarkerRangeForTextMarker: [self textMarkerForIndex: index lastIndexOK: NO]]; - return [self rangeForTextMarkerRange: textMarkerRange]; -} - -- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter -{ - WebCoreTextMarker* textMarker = nil; - WebCoreTextMarkerRange* textMarkerRange = nil; - NSNumber* number = nil; - NSArray* array = nil; - WebCoreAXObject* uiElement = nil; - NSPoint point = NSZeroPoint; - bool pointSet = false; - NSRange range = {0, 0}; - bool rangeSet = false; - - // basic parameter validation - if (!m_renderer || !attribute || !parameter) - return nil; - - // common parameter type check/casting. Nil checks in handlers catch wrong type case. - // NOTE: This assumes nil is not a valid parameter, because it is indistinguishable from - // a parameter of the wrong type. - if ([[WebCoreViewFactory sharedFactory] objectIsTextMarker:parameter]) - textMarker = (WebCoreTextMarker*) parameter; - - else if ([[WebCoreViewFactory sharedFactory] objectIsTextMarkerRange:parameter]) - textMarkerRange = (WebCoreTextMarkerRange*) parameter; - - else if ([parameter isKindOfClass:[WebCoreAXObject self]]) - uiElement = (WebCoreAXObject*) parameter; - - else if ([parameter isKindOfClass:[NSNumber self]]) - number = parameter; - - else if ([parameter isKindOfClass:[NSArray self]]) - array = parameter; - - else if ([parameter isKindOfClass:[NSValue self]] && strcmp([(NSValue*)parameter objCType], @encode(NSPoint)) == 0) { - pointSet = true; - point = [(NSValue*)parameter pointValue]; - - } else if ([parameter isKindOfClass:[NSValue self]] && strcmp([(NSValue*)parameter objCType], @encode(NSRange)) == 0) { - rangeSet = true; - range = [(NSValue*)parameter rangeValue]; - - } else { - // got a parameter of a type we never use - // NOTE: No ASSERT_NOT_REACHED because this can happen accidentally - // while using accesstool (e.g.), forcing you to start over - return nil; - } - - // dispatch - if ([attribute isEqualToString: @"AXUIElementForTextMarker"]) - return [self doAXUIElementForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXTextMarkerRangeForUIElement"]) - return [self doAXTextMarkerRangeForUIElement: uiElement]; - - if ([attribute isEqualToString: @"AXLineForTextMarker"]) - return [self doAXLineForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXTextMarkerRangeForLine"]) - return [self doAXTextMarkerRangeForLine: number]; - - if ([attribute isEqualToString: @"AXStringForTextMarkerRange"]) - return [self doAXStringForTextMarkerRange: textMarkerRange]; - - if ([attribute isEqualToString: @"AXTextMarkerForPosition"]) - return pointSet ? [self doAXTextMarkerForPosition: point] : nil; - - if ([attribute isEqualToString: @"AXBoundsForTextMarkerRange"]) - return [self doAXBoundsForTextMarkerRange: textMarkerRange]; - - if ([attribute isEqualToString: @"AXAttributedStringForTextMarkerRange"]) - return [self doAXAttributedStringForTextMarkerRange: textMarkerRange]; - - if ([attribute isEqualToString: @"AXTextMarkerRangeForUnorderedTextMarkers"]) - return [self doAXTextMarkerRangeForUnorderedTextMarkers: array]; - - if ([attribute isEqualToString: @"AXNextTextMarkerForTextMarker"]) - return [self doAXNextTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXPreviousTextMarkerForTextMarker"]) - return [self doAXPreviousTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXLeftWordTextMarkerRangeForTextMarker"]) - return [self doAXLeftWordTextMarkerRangeForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXRightWordTextMarkerRangeForTextMarker"]) - return [self doAXRightWordTextMarkerRangeForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXLeftLineTextMarkerRangeForTextMarker"]) - return [self doAXLeftLineTextMarkerRangeForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXRightLineTextMarkerRangeForTextMarker"]) - return [self doAXRightLineTextMarkerRangeForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXSentenceTextMarkerRangeForTextMarker"]) - return [self doAXSentenceTextMarkerRangeForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXParagraphTextMarkerRangeForTextMarker"]) - return [self doAXParagraphTextMarkerRangeForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXNextWordEndTextMarkerForTextMarker"]) - return [self doAXNextWordEndTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXPreviousWordStartTextMarkerForTextMarker"]) - return [self doAXPreviousWordStartTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXNextLineEndTextMarkerForTextMarker"]) - return [self doAXNextLineEndTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXPreviousLineStartTextMarkerForTextMarker"]) - return [self doAXPreviousLineStartTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXNextSentenceEndTextMarkerForTextMarker"]) - return [self doAXNextSentenceEndTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXPreviousSentenceStartTextMarkerForTextMarker"]) - return [self doAXPreviousSentenceStartTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXNextParagraphEndTextMarkerForTextMarker"]) - return [self doAXNextParagraphEndTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXPreviousParagraphStartTextMarkerForTextMarker"]) - return [self doAXPreviousParagraphStartTextMarkerForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXStyleTextMarkerRangeForTextMarker"]) - return [self doAXStyleTextMarkerRangeForTextMarker: textMarker]; - - if ([attribute isEqualToString: @"AXLengthForTextMarkerRange"]) - return [self doAXLengthForTextMarkerRange: textMarkerRange]; - - if ([self isTextControl]) { - if ([attribute isEqualToString: (NSString*)kAXLineForIndexParameterizedAttribute]) - return [self doAXLineForIndex: number]; - - if ([attribute isEqualToString: (NSString*)kAXRangeForLineParameterizedAttribute]) - return [self doAXRangeForLine: number]; - - if ([attribute isEqualToString: (NSString*)kAXStringForRangeParameterizedAttribute]) - return rangeSet ? [self doAXStringForRange: range] : nil; - - if ([attribute isEqualToString: (NSString*)kAXRangeForPositionParameterizedAttribute]) - return pointSet ? [self doAXRangeForPosition: point] : nil; - - if ([attribute isEqualToString: (NSString*)kAXRangeForIndexParameterizedAttribute]) - return [self doAXRangeForIndex: number]; - - if ([attribute isEqualToString: (NSString*)kAXBoundsForRangeParameterizedAttribute]) - return rangeSet ? [self doAXBoundsForRange: range] : nil; - - if ([attribute isEqualToString: (NSString*)kAXRTFForRangeParameterizedAttribute]) - return rangeSet ? [self doAXRTFForRange: range] : nil; - - if ([attribute isEqualToString: (NSString*)kAXAttributedStringForRangeParameterizedAttribute]) - return rangeSet ? [self doAXAttributedStringForRange: range] : nil; - - if ([attribute isEqualToString: (NSString*)kAXStyleRangeForIndexParameterizedAttribute]) - return [self doAXStyleRangeForIndex: number]; - } - - return nil; -} - -- (id)accessibilityHitTest:(NSPoint)point -{ - if (!m_renderer) - return NSAccessibilityUnignoredAncestor(self); - - HitTestRequest request(true, true); - HitTestResult result = HitTestResult(IntPoint(point)); - m_renderer->layer()->hitTest(request, result); - if (!result.innerNode()) - return NSAccessibilityUnignoredAncestor(self); - Node* node = result.innerNode()->shadowAncestorNode(); - RenderObject* obj = node->renderer(); - if (!obj) - return NSAccessibilityUnignoredAncestor(self); - - return NSAccessibilityUnignoredAncestor(obj->document()->axObjectCache()->get(obj)); -} - -- (RenderObject*)rendererForView:(NSView*)view -{ - // check for WebKit NSView that lets us find its bridge - WebCoreFrameBridge* bridge = nil; - if ([view conformsToProtocol:@protocol(WebCoreBridgeHolder)]) { - NSView<WebCoreBridgeHolder>* bridgeHolder = (NSView<WebCoreBridgeHolder>*)view; - bridge = [bridgeHolder webCoreBridge]; - } - - Frame* frame = [bridge _frame]; - if (!frame) - return nil; - - Document* document = frame->document(); - if (!document) - return nil; - - Node* node = document->ownerElement(); - if (!node) - return nil; - - return node->renderer(); -} - -// _accessibilityParentForSubview is called by AppKit when moving up the tree -// we override it so that we can return our WebCoreAXObject parent of an AppKit AX object -- (id)_accessibilityParentForSubview:(NSView*)subview -{ - RenderObject* renderer = [self rendererForView:subview]; - if (!renderer) - return nil; - - WebCoreAXObject* obj = renderer->document()->axObjectCache()->get(renderer); - return [obj parentObjectUnignored]; -} - -- (id)accessibilityFocusedUIElement -{ - // get the focused node in the page - Page* page = m_renderer->document()->page(); - if (!page) - return nil; - - Document* focusedDocument = page->focusController()->focusedOrMainFrame()->document(); - Node* focusedNode = focusedDocument->focusedNode(); - if (!focusedNode || !focusedNode->renderer()) - focusedNode = focusedDocument; - - WebCoreAXObject* obj = focusedNode->renderer()->document()->axObjectCache()->get(focusedNode->renderer()); - - // the HTML element, for example, is focusable but has an AX object that is ignored - if ([obj accessibilityIsIgnored]) - obj = [obj parentObjectUnignored]; - - return obj; -} - -- (void)doSetAXSelectedTextMarkerRange: (WebCoreTextMarkerRange*)textMarkerRange -{ - // extract the start and end VisiblePosition - VisiblePosition startVisiblePosition = [self visiblePositionForStartOfTextMarkerRange: textMarkerRange]; - if (startVisiblePosition.isNull()) - return; - - VisiblePosition endVisiblePosition = [self visiblePositionForEndOfTextMarkerRange: textMarkerRange]; - if (endVisiblePosition.isNull()) - return; - - // make selection and tell the document to use it - Selection newSelection = Selection(startVisiblePosition, endVisiblePosition); - m_renderer->document()->frame()->selectionController()->setSelection(newSelection); -} - -- (BOOL)canSetFocusAttribute -{ - // NOTE: It would be more accurate to ask the document whether setFocusedNode() would - // do anything. For example, it setFocusedNode() will do nothing if the current focused - // node will not relinquish the focus. - if (!m_renderer->element() || !m_renderer->element()->isEnabled()) - return NO; - - NSString* role = [self role]; - if ([role isEqualToString:@"AXLink"] || - [role isEqualToString:NSAccessibilityTextFieldRole] || - [role isEqualToString:NSAccessibilityTextAreaRole] || - [role isEqualToString:NSAccessibilityButtonRole] || - [role isEqualToString:NSAccessibilityPopUpButtonRole] || - [role isEqualToString:NSAccessibilityCheckBoxRole] || - [role isEqualToString:NSAccessibilityRadioButtonRole]) - return YES; - - return NO; -} - -- (BOOL)canSetValueAttribute -{ - return [self isTextControl]; -} - -- (BOOL)canSetTextRangeAttributes -{ - return [self isTextControl]; -} - -- (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName -{ - if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"]) - return YES; - - if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute]) - return [self canSetFocusAttribute]; - - if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) - return [self canSetValueAttribute]; - - if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute] || - [attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute] || - [attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute]) - return [self canSetTextRangeAttributes]; - - return NO; -} - -- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attributeName -{ - WebCoreTextMarkerRange* textMarkerRange = nil; - NSNumber* number = nil; - NSString* string = nil; - NSRange range = {0, 0}; - - // decode the parameter - if ([[WebCoreViewFactory sharedFactory] objectIsTextMarkerRange:value]) - textMarkerRange = (WebCoreTextMarkerRange*) value; - - else if ([value isKindOfClass:[NSNumber self]]) - number = value; - - else if ([value isKindOfClass:[NSString self]]) - string = value; - - else if ([value isKindOfClass:[NSValue self]]) - range = [value rangeValue]; - - // handle the command - if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"]) { - ASSERT(textMarkerRange); - [self doSetAXSelectedTextMarkerRange:textMarkerRange]; - - } else if ([attributeName isEqualToString: NSAccessibilityFocusedAttribute]) { - ASSERT(number); - if ([self canSetFocusAttribute] && number) { - if ([number intValue] == 0) - m_renderer->document()->setFocusedNode(0); - else { - if (m_renderer->element()->isElementNode()) - static_cast<Element*>(m_renderer->element())->focus(); - else - m_renderer->document()->setFocusedNode(m_renderer->element()); - } - } - } else if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) { - if (!string) - return; - if (m_renderer->isTextField()) { - HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element()); - input->setValue(string); - } else if (m_renderer->isTextArea()) { - HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(m_renderer->element()); - textArea->setValue(string); - } - } else if ([self isTextControl]) { - RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer); - if ([attributeName isEqualToString: NSAccessibilitySelectedTextAttribute]) { - // TODO: set selected text (ReplaceSelectionCommand). <rdar://problem/4712125> - } else if ([attributeName isEqualToString: NSAccessibilitySelectedTextRangeAttribute]) { - textControl->setSelectionRange(range.location, range.location + range.length); - } else if ([attributeName isEqualToString: NSAccessibilityVisibleCharacterRangeAttribute]) { - // TODO: make range visible (scrollRectToVisible). <rdar://problem/4712101> - } - } -} - -- (WebCoreAXObject*)observableObject -{ - for (RenderObject* renderer = m_renderer; renderer && renderer->element(); renderer = renderer->parent()) { - if (renderer->isTextField() || renderer->isTextArea()) - return renderer->document()->axObjectCache()->get(renderer); - } - - return nil; -} - -- (void)childrenChanged -{ - [self clearChildren]; - - if ([self accessibilityIsIgnored]) - [[self parentObject] childrenChanged]; -} - -- (void)clearChildren -{ - [m_children release]; - m_children = nil; -} - --(AXID)axObjectID -{ - return m_id; -} - --(void)setAXObjectID:(AXID) axObjectID -{ - m_id = axObjectID; -} - -- (void)removeAXObjectID -{ - if (!m_id) - return; - - m_renderer->document()->axObjectCache()->removeAXID(self); -} - -@end diff --git a/WebCore/page/mac/WebCoreFrameBridge.h b/WebCore/page/mac/WebCoreFrameBridge.h index 76315f7..a67f1b3 100644 --- a/WebCore/page/mac/WebCoreFrameBridge.h +++ b/WebCore/page/mac/WebCoreFrameBridge.h @@ -238,6 +238,8 @@ enum WebScrollGranularity { - (WebCore::KeyboardUIMode)keyboardUIMode; +- (NSString*)imageTitleForFilename:(NSString*)filename size:(NSSize)size; + @end // This interface definition allows those who hold a WebCoreFrameBridge * to call all the methods diff --git a/WebCore/page/mac/WebCoreFrameBridge.mm b/WebCore/page/mac/WebCoreFrameBridge.mm index 3f20706..d280bcb 100644 --- a/WebCore/page/mac/WebCoreFrameBridge.mm +++ b/WebCore/page/mac/WebCoreFrameBridge.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. * Copyright (C) 2005, 2006 Alexey Proskuryakov (ap@nypop.com) * Copyright (C) 2006 David Smith (catfish.man@gmail.com) * @@ -81,6 +81,7 @@ #import "TextIterator.h" #import "TextResourceDecoder.h" #import "TypingCommand.h" +#import "WebCoreSystemInterface.h" #import "WebCoreViewFactory.h" #import "XMLTokenizer.h" #import "htmlediting.h" @@ -626,11 +627,12 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element) - (NSURL *)URLWithAttributeString:(NSString *)string { - Document* doc = m_frame->document(); + Document *doc = m_frame->document(); if (!doc) return nil; // FIXME: is parseURL appropriate here? - return doc->completeURL(parseURL(string)); + DeprecatedString rel = parseURL(string).deprecatedString(); + return KURL(doc->completeURL(rel)).getNSURL(); } - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection @@ -745,7 +747,7 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element) - (NSURL *)baseURL { - return m_frame->document()->baseURL(); + return m_frame->loader()->completeURL(m_frame->document()->baseURL()).getNSURL(); } - (NSString *)stringWithData:(NSData *)data @@ -774,7 +776,7 @@ static HTMLFormElement *formElementFromDOMElement(DOMElement *element) - (NSString *)renderTreeAsExternalRepresentation { - return externalRepresentation(m_frame->renderer()); + return externalRepresentation(m_frame->renderer()).getNSString(); } - (void)setShouldCreateRenderers:(BOOL)f diff --git a/WebCore/page/mac/WebCoreScriptDebugger.h b/WebCore/page/mac/WebCoreScriptDebugger.h deleted file mode 100644 index fd56632..0000000 --- a/WebCore/page/mac/WebCoreScriptDebugger.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2005 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. - * 3. Neither the name of Apple Computer, 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. - */ - -@class WebScriptObject; // from JavaScriptCore -@class WebCoreScriptCallFrame; // below - -#ifdef __cplusplus -class WebCoreScriptDebuggerImp; -namespace KJS { class ExecState; } -using KJS::ExecState; -#else -@class WebCoreScriptDebuggerImp; -@class ExecState; -#endif - - - -// "WebScriptDebugger" protocol - must be implemented by a delegate - -@protocol WebScriptDebugger - -- (WebScriptObject *)globalObject; // return the WebView's windowScriptObject -- (id)newWrapperForFrame:(WebCoreScriptCallFrame *)frame; // return a (retained) stack-frame object - -// debugger callbacks -- (void)parsedSource:(NSString *)source fromURL:(NSURL *)url sourceId:(int)sid startLine:(int)startLine errorLine:(int)errorLine errorMessage:(NSString *)errorMessage; -- (void)enteredFrame:(WebCoreScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno; -- (void)hitStatement:(WebCoreScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno; -- (void)leavingFrame:(WebCoreScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno; -- (void)exceptionRaised:(WebCoreScriptCallFrame *)frame sourceId:(int)sid line:(int)lineno; - -@end - - - -@interface WebCoreScriptDebugger : NSObject -{ -@private - id<WebScriptDebugger> _delegate; // interface to WebKit (not retained) - WebScriptObject *_globalObj; // the global object's proxy (not retained) - WebCoreScriptCallFrame *_current; // top of stack - WebCoreScriptDebuggerImp *_debugger; // [KJS::Debugger] -} - -- (WebCoreScriptDebugger *)initWithDelegate:(id<WebScriptDebugger>)delegate; -- (id<WebScriptDebugger>)delegate; - -@end - - - -@interface WebCoreScriptCallFrame : NSObject -{ -@private - id _wrapper; // WebKit's version of this object - WebScriptObject *_globalObj; // the global object's proxy (not retained) - WebCoreScriptCallFrame *_caller; // previous stack frame - ExecState *_state; // [KJS::ExecState] -} - -- (id)wrapper; -- (WebCoreScriptCallFrame *)caller; - -- (NSArray *)scopeChain; -- (NSString *)functionName; -- (id)exception; -- (id)evaluateWebScript:(NSString *)script; - -@end diff --git a/WebCore/page/mac/WebCoreScriptDebugger.mm b/WebCore/page/mac/WebCoreScriptDebugger.mm deleted file mode 100644 index ae68a63..0000000 --- a/WebCore/page/mac/WebCoreScriptDebugger.mm +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (C) 2005, 2008 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 Computer, 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. - */ - -#import "config.h" -#import "WebCoreScriptDebugger.h" - -#import "KURL.h" -#import "PlatformString.h" -#import "WebCoreObjCExtras.h" -#import "WebScriptObjectPrivate.h" -#import <JavaScriptCore/ExecState.h> -#import <JavaScriptCore/JSGlobalObject.h> -#import <JavaScriptCore/debugger.h> -#import <JavaScriptCore/function.h> -#import <JavaScriptCore/interpreter.h> - -using namespace KJS; -using namespace WebCore; - -@interface WebCoreScriptDebugger (WebCoreScriptDebuggerInternal) - -- (WebCoreScriptCallFrame *)_enterFrame:(ExecState *)state; -- (WebCoreScriptCallFrame *)_leaveFrame; - -@end - -@interface WebCoreScriptCallFrame (WebCoreScriptDebuggerInternal) - -- (WebCoreScriptCallFrame *)_initWithGlobalObject:(WebScriptObject *)globalObj caller:(WebCoreScriptCallFrame *)caller state:(ExecState *)state; -- (void)_setWrapper:(id)wrapper; -- (id)_convertValueToObjcValue:(JSValue *)value; - -@end - -// convert UString to NSString -static NSString *toNSString(const UString& s) -{ - if (s.isEmpty()) - return nil; - return [NSString stringWithCharacters:reinterpret_cast<const unichar*>(s.data()) length:s.size()]; -} - -// convert UString to NSURL -static NSURL *toNSURL(const UString& s) -{ - if (s.isEmpty()) - return nil; - return KURL(s); -} - -// C++ interface to KJS debugger callbacks - -class WebCoreScriptDebuggerImp : public KJS::Debugger { - - private: - WebCoreScriptDebugger *_objc; // our ObjC half - bool _nested; // true => this is a nested call - WebCoreScriptCallFrame *_current; // top stack frame (copy of same field from ObjC side) - - public: - // constructor - WebCoreScriptDebuggerImp(WebCoreScriptDebugger *objc, JSGlobalObject* globalObject) : _objc(objc) { - _nested = true; - _current = [_objc _enterFrame:globalObject->globalExec()]; - attach(globalObject); - [[_objc delegate] enteredFrame:_current sourceId:-1 line:-1]; - _nested = false; - } - - // callbacks - relay to delegate - virtual bool sourceParsed(ExecState *state, int sid, const UString &url, const UString &source, int lineNumber, int errorLine, const UString &errorMsg) { - if (!_nested) { - _nested = true; - [[_objc delegate] parsedSource:toNSString(source) fromURL:toNSURL(url) sourceId:sid startLine:lineNumber errorLine:errorLine errorMessage:toNSString(errorMsg)]; - _nested = false; - } - return true; - } - virtual bool callEvent(ExecState *state, int sid, int lineno, JSObject *func, const List &args) { - if (!_nested) { - _nested = true; - _current = [_objc _enterFrame:state]; - [[_objc delegate] enteredFrame:_current sourceId:sid line:lineno]; - _nested = false; - } - return true; - } - virtual bool atStatement(ExecState *state, int sid, int lineno, int lastLine) { - if (!_nested) { - _nested = true; - [[_objc delegate] hitStatement:_current sourceId:sid line:lineno]; - _nested = false; - } - return true; - } - virtual bool returnEvent(ExecState *state, int sid, int lineno, JSObject *func) { - if (!_nested) { - _nested = true; - [[_objc delegate] leavingFrame:_current sourceId:sid line:lineno]; - _current = [_objc _leaveFrame]; - _nested = false; - } - return true; - } - virtual bool exception(ExecState *state, int sid, int lineno, JSValue *exception) { - if (!_nested) { - _nested = true; - [[_objc delegate] exceptionRaised:_current sourceId:sid line:lineno]; - _nested = false; - } - return true; - } - -}; - -// WebCoreScriptDebugger -// -// This is the main (behind-the-scenes) debugger class in WebCore. -// -// The WebCoreScriptDebugger has two faces, one for Objective-C (this class), and another (WebCoreScriptDebuggerImp) -// for C++. The ObjC side creates the C++ side, which does the real work of attaching to the global object and -// forwarding the KJS debugger callbacks to the delegate. - -@implementation WebCoreScriptDebugger - -#ifndef BUILDING_ON_TIGER -+ (void)initialize -{ - WebCoreObjCFinalizeOnMainThread(self); -} -#endif - -- (WebCoreScriptDebugger *)initWithDelegate:(id<WebScriptDebugger>)delegate -{ - if ((self = [super init])) { - _delegate = delegate; - _globalObj = [_delegate globalObject]; - _debugger = new WebCoreScriptDebuggerImp(self, [_globalObj _rootObject]->globalObject()); - } - return self; -} - -- (void)dealloc -{ - [_current release]; - delete _debugger; - [super dealloc]; -} - -- (void)finalize -{ - delete _debugger; - [super finalize]; -} - -- (id<WebScriptDebugger>)delegate -{ - return _delegate; -} - -@end - -@implementation WebCoreScriptDebugger (WebCoreScriptDebuggerInternal) - -- (WebCoreScriptCallFrame *)_enterFrame:(ExecState *)state; -{ - WebCoreScriptCallFrame *callee = [[WebCoreScriptCallFrame alloc] _initWithGlobalObject:_globalObj caller:_current state:state]; - [callee _setWrapper:[_delegate newWrapperForFrame:callee]]; - return _current = callee; -} - -- (WebCoreScriptCallFrame *)_leaveFrame; -{ - WebCoreScriptCallFrame *caller = [[_current caller] retain]; - [_current release]; - return _current = caller; -} - -@end - -// WebCoreScriptCallFrame -// -// One of these is created to represent each stack frame. Additionally, there is a "global" -// frame to represent the outermost scope. This global frame is always the last frame in -// the chain of callers. -// -// The delegate can assign a "wrapper" to each frame object so it can relay calls through its -// own exported interface. This class is private to WebCore (and the delegate). - -@implementation WebCoreScriptCallFrame (WebCoreScriptDebuggerInternal) - -- (WebCoreScriptCallFrame *)_initWithGlobalObject:(WebScriptObject *)globalObj caller:(WebCoreScriptCallFrame *)caller state:(ExecState *)state -{ - if ((self = [super init])) { - _globalObj = globalObj; - _caller = caller; // (already retained) - _state = state; - } - return self; -} - -- (void)_setWrapper:(id)wrapper -{ - _wrapper = wrapper; // (already retained) -} - -- (id)_convertValueToObjcValue:(JSValue *)value -{ - if (!value) - return nil; - - if (value == [_globalObj _imp]) - return _globalObj; - - Bindings::RootObject* root1 = [_globalObj _originRootObject]; - if (!root1) - return nil; - - Bindings::RootObject* root2 = [_globalObj _rootObject]; - if (!root2) - return nil; - - return [WebScriptObject _convertValueToObjcValue:value originRootObject:root1 rootObject:root2]; -} - -@end - -@implementation WebCoreScriptCallFrame - -- (void)dealloc -{ - [_wrapper release]; - [_caller release]; - [super dealloc]; -} - -- (id)wrapper -{ - return _wrapper; -} - -- (WebCoreScriptCallFrame *)caller -{ - return _caller; -} - -// Returns an array of scope objects (most local first). -// The properties of each scope object are the variables for that scope. -// Note that the last entry in the array will _always_ be the global object (windowScriptObject), -// whose properties are the global variables. - -- (NSArray *)scopeChain -{ - if (!_state->scopeNode()) { // global frame - return [NSArray arrayWithObject:_globalObj]; - } - - ScopeChain chain = _state->scopeChain(); - NSMutableArray *scopes = [[NSMutableArray alloc] init]; - - while (!chain.isEmpty()) { - [scopes addObject:[self _convertValueToObjcValue:chain.top()]]; - chain.pop(); - } - - NSArray *result = [NSArray arrayWithArray:scopes]; - [scopes release]; - return result; -} - -// Returns the name of the function for this frame, if available. -// Returns nil for anonymous functions and for the global frame. - -- (NSString *)functionName -{ - if (_state->scopeNode()) { - FunctionImp* func = _state->function(); - if (func) { - Identifier fn = func->functionName(); - return toNSString(fn.ustring()); - } - } - return nil; -} - -// Returns the pending exception for this frame (nil if none). - -- (id)exception -{ - if (!_state->hadException()) return nil; - return [self _convertValueToObjcValue:_state->exception()]; -} - -// Evaluate some JavaScript code in the context of this frame. -// The code is evaluated as if by "eval", and the result is returned. -// If there is an (uncaught) exception, it is returned as though _it_ were the result. -// Calling this method on the global frame is not quite the same as calling the WebScriptObject -// method of the same name, due to the treatment of exceptions. - -// FIXME: If "script" contains var declarations, the machinery to handle local variables -// efficiently in JavaScriptCore will not work properly. This could lead to crashes or -// incorrect variable values. So this is not appropriate for evaluating arbitrary script. -- (id)evaluateWebScript:(NSString *)script -{ - JSLock lock; - - UString code = String(script); - - ExecState* state = _state; - JSGlobalObject* globalObject = state->dynamicGlobalObject(); - - // find "eval" - JSObject *eval = NULL; - if (state->scopeNode()) { // "eval" won't work without context (i.e. at global scope) - JSValue *v = globalObject->get(state, "eval"); - if (v->isObject() && static_cast<JSObject *>(v)->implementsCall()) - eval = static_cast<JSObject *>(v); - else - // no "eval" - fallback operates on global exec state - state = globalObject->globalExec(); - } - - JSValue *savedException = state->exception(); - state->clearException(); - - // evaluate - JSValue *result; - if (eval) { - List args; - args.append(jsString(code)); - result = eval->call(state, NULL, args); - } else - // no "eval", or no context (i.e. global scope) - use global fallback - result = Interpreter::evaluate(state, UString(), 0, code.data(), code.size(), globalObject).value(); - - if (state->hadException()) - result = state->exception(); // (may be redundant depending on which eval path was used) - state->setException(savedException); - - return [self _convertValueToObjcValue:result]; -} - -@end diff --git a/WebCore/page/mac/WebCoreViewFactory.h b/WebCore/page/mac/WebCoreViewFactory.h index 4cf21e3..55514ed 100644 --- a/WebCore/page/mac/WebCoreViewFactory.h +++ b/WebCore/page/mac/WebCoreViewFactory.h @@ -98,8 +98,6 @@ - (NSString *)defaultLanguageCode; -- (NSString *)imageTitleForFilename:(NSString *)filename size:(NSSize)size; - - (BOOL)objectIsTextMarker:(id)object; - (BOOL)objectIsTextMarkerRange:(id)object; diff --git a/WebCore/page/win/FrameCGWin.cpp b/WebCore/page/win/FrameCGWin.cpp deleted file mode 100644 index eea6961..0000000 --- a/WebCore/page/win/FrameCGWin.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 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 "FrameWin.h" - -#include <windows.h> - -#include "FrameView.h" -#include "GraphicsContext.h" -#include "Settings.h" - -#include <CoreGraphics/CoreGraphics.h> - -using std::min; - -namespace WebCore { - -static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext* gc) -{ - IntSize offset = view->scrollOffset(); - rect.move(-offset.width(), -offset.height()); - rect = view->convertToContainingWindow(rect); - - gc->concatCTM(AffineTransform().translate(-rect.x(), -rect.y())); - - view->paint(gc, rect); -} - -HBITMAP imageFromSelection(Frame* frame, bool forceBlackText) -{ - frame->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly); - FloatRect fr = frame->selectionRect(); - IntRect ir(static_cast<int>(fr.x()), static_cast<int>(fr.y()), - static_cast<int>(fr.width()), static_cast<int>(fr.height())); - - void* bits; - HDC hdc = CreateCompatibleDC(0); - int w = ir.width(); - int h = ir.height(); - BITMAPINFO bmp = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32 } }; - - HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0); - HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp)); - CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB(); - CGContextRef context = CGBitmapContextCreate(static_cast<void*>(bits), w, h, - 8, w * sizeof(RGBQUAD), deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); - CGColorSpaceRelease(deviceRGB); - CGContextSaveGState(context); - - GraphicsContext gc(context); - - frame->document()->updateLayout(); - drawRectIntoContext(ir, frame->view(), &gc); - - CGContextRelease(context); - SelectObject(hdc, hbmpOld); - DeleteDC(hdc); - - frame->setPaintRestriction(PaintRestrictionNone); - - return hbmp; -} - -} // namespace WebCore diff --git a/WebCore/page/win/FrameCairoWin.cpp b/WebCore/page/win/FrameCairoWin.cpp deleted file mode 100644 index a645a10..0000000 --- a/WebCore/page/win/FrameCairoWin.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 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 "FrameWin.h" - -#include "EditorClient.h" -#include "NotImplemented.h" - -using std::min; - -namespace WebCore { - -HBITMAP imageFromSelection(Frame* frame, bool forceBlackText) -{ - notImplemented(); - return 0; -} - -} // namespace WebCore diff --git a/WebCore/page/win/FrameWin.cpp b/WebCore/page/win/FrameWin.cpp deleted file mode 100644 index 6599a88..0000000 --- a/WebCore/page/win/FrameWin.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 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 "FrameWin.h" - -#include <winsock2.h> -#include <windows.h> - -#include "AffineTransform.h" -#include "FloatRect.h" -#include "Document.h" -#include "EditorClient.h" -#include "FrameLoader.h" -#include "FrameLoadRequest.h" -#include "FramePrivate.h" -#include "FrameView.h" -#include "HTMLIFrameElement.h" -#include "HTMLNames.h" -#include "HTMLTableCellElement.h" -#include "KeyboardEvent.h" -#include "NP_jsobject.h" -#include "NotImplemented.h" -#include "Page.h" -#include "Plugin.h" -#include "PluginDatabase.h" -#include "PluginView.h" -#include "RegularExpression.h" -#include "RenderFrame.h" -#include "RenderTableCell.h" -#include "RenderView.h" -#include "ResourceHandle.h" -#include "TextResourceDecoder.h" -#include "kjs_proxy.h" -#include "kjs_window.h" -#include "npruntime_impl.h" -#include "runtime_root.h" -#include "GraphicsContext.h" -#include "Settings.h" - -using std::min; -using namespace KJS::Bindings; - -namespace WebCore { - -using namespace HTMLNames; - -void Frame::clearPlatformScriptObjects() -{ -} - -KJS::Bindings::Instance* Frame::createScriptInstanceForWidget(Widget* widget) -{ - // FIXME: Ideally we'd have an isPluginView() here but we can't add that to the open source tree right now. - if (widget->isFrameView()) - return 0; - - return static_cast<PluginView*>(widget)->bindingInstance(); -} - -void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor,Vector<IntRect>& pages, int& outPageHeight) -{ - ASSERT(frame); - - pages.clear(); - outPageHeight = 0; - - if (!frame->document() || !frame->view() || !frame->document()->renderer()) - return; - - RenderView* root = static_cast<RenderView *>(frame->document()->renderer()); - - if (!root) { - LOG_ERROR("document to be printed has no renderer"); - return; - } - - if (userScaleFactor <= 0) { - LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor); - return; - } - - float ratio = static_cast<float>(printRect.height()) / static_cast<float>(printRect.width()); - - float pageWidth = static_cast<float>(root->docWidth()); - float pageHeight = pageWidth * ratio; - outPageHeight = static_cast<int>(pageHeight); // this is the height of the page adjusted by margins - pageHeight -= (headerHeight + footerHeight); - - if (pageHeight <= 0) { - LOG_ERROR("pageHeight has bad value %.2f", pageHeight); - return; - } - - float currPageHeight = pageHeight / userScaleFactor; - float docHeight = root->layer()->height(); - float docWidth = root->layer()->width(); - float currPageWidth = pageWidth / userScaleFactor; - - - // always return at least one page, since empty files should print a blank page - float printedPagesHeight = 0.0f; - do { - float proposedBottom = min(docHeight, printedPagesHeight + pageHeight); - frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight); - currPageHeight = max(1.0f, proposedBottom - printedPagesHeight); - - pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight)); - printedPagesHeight += currPageHeight; - } while (printedPagesHeight < docHeight); -} - -DragImageRef Frame::dragImageForSelection() -{ - if (selectionController()->isRange()) - return imageFromSelection(this, false); - - return 0; -} - -void Frame::dashboardRegionsChanged() -{ -} - -} // namespace WebCore diff --git a/WebCore/page/win/FrameWin.h b/WebCore/page/win/FrameWin.h deleted file mode 100644 index 405c7b2..0000000 --- a/WebCore/page/win/FrameWin.h +++ /dev/null @@ -1,41 +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. - */ - -#ifndef FrameWin_H -#define FrameWin_H - -#include "Frame.h" - -// Forward declared so we don't need wingdi.h. -typedef struct HBITMAP__* HBITMAP; - -namespace WebCore { - - HBITMAP imageFromSelection(Frame* frame, bool forceWhiteText); - void computePageRectsForFrame(Frame*, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor,Vector<IntRect>& pages, int& pageHeight); - -} - -#endif diff --git a/WebCore/page/win/GlobalHistoryWin.cpp b/WebCore/page/win/GlobalHistoryWin.cpp deleted file mode 100644 index c81f09b..0000000 --- a/WebCore/page/win/GlobalHistoryWin.cpp +++ /dev/null @@ -1,39 +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 "GlobalHistory.h" - -#include "WebCoreHistory.h" - -namespace WebCore { - -bool historyContains(const UChar* characters, unsigned length) -{ - WebCoreHistoryProvider* provider = WebCoreHistory::historyProvider(); - return provider && provider->containsURL(characters, length); -} - -} // namespace WebCore |