diff options
Diffstat (limited to 'WebCore/page/Frame.cpp')
| -rw-r--r-- | WebCore/page/Frame.cpp | 186 |
1 files changed, 145 insertions, 41 deletions
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp index 78cc25c..7e81b3d 100644 --- a/WebCore/page/Frame.cpp +++ b/WebCore/page/Frame.cpp @@ -25,6 +25,7 @@ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ + #include "config.h" #include "Frame.h" @@ -59,6 +60,7 @@ #include "Navigator.h" #include "NodeList.h" #include "Page.h" +#include "PageGroup.h" #include "RegularExpression.h" #include "RenderPart.h" #include "RenderTableCell.h" @@ -66,9 +68,12 @@ #include "RenderTheme.h" #include "RenderView.h" #include "ScriptController.h" +#include "ScriptSourceCode.h" +#include "ScriptValue.h" #include "Settings.h" #include "TextIterator.h" #include "TextResourceDecoder.h" +#include "UserContentURLPattern.h" #include "XMLNames.h" #include "htmlediting.h" #include "markup.h" @@ -77,15 +82,15 @@ #include <wtf/RefCountedLeakCounter.h> #include <wtf/StdLibExtras.h> +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) +#import <Carbon/Carbon.h> +#endif + #if USE(JSC) #include "JSDOMWindowShell.h" #include "runtime_root.h" #endif -#if FRAME_LOADS_USER_STYLESHEET -#include "UserStyleSheetLoader.h" -#endif - #if ENABLE(SVG) #include "SVGDocument.h" #include "SVGDocumentExtensions.h" @@ -101,6 +106,10 @@ #include "WMLNames.h" #endif +#if ENABLE(MATHML) +#include "MathMLNames.h" +#endif + using namespace std; namespace WebCore { @@ -122,6 +131,7 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* : m_page(page) , m_treeNode(this, parentFromOwnerElement(ownerElement)) , m_loader(this, frameLoaderClient) + , m_redirectScheduler(this) , m_ownerElement(ownerElement) , m_script(this) , m_selectionGranularity(CharacterGranularity) @@ -131,6 +141,9 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* , m_eventHandler(this) , m_animationController(this) , m_lifeSupportTimer(this, &Frame::lifeSupportTimerFired) +#if ENABLE(ORIENTATION_EVENTS) + , m_orientation(0) +#endif , m_caretVisible(false) , m_caretPaint(true) , m_highlightTextMatches(false) @@ -138,9 +151,6 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* , m_needsReapplyStyles(false) , m_isDisconnected(false) , m_excludeFromTextSearch(false) -#if FRAME_LOADS_USER_STYLESHEET - , m_userStyleSheetLoader(0) -#endif { Frame* parent = parentFromOwnerElement(ownerElement); m_zoomFactor = parent ? parent->m_zoomFactor : 1.0f; @@ -159,6 +169,10 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* WMLNames::init(); #endif +#if ENABLE(MATHML) + MathMLNames::init(); +#endif + XMLNames::init(); if (!ownerElement) @@ -192,6 +206,7 @@ Frame::~Frame() if (m_domWindow) m_domWindow->disconnectFrame(); + script()->clearWindowShell(); HashSet<DOMWindow*>::iterator end = m_liveFormerWindows.end(); for (HashSet<DOMWindow*>::iterator it = m_liveFormerWindows.begin(); it != end; ++it) @@ -203,10 +218,6 @@ Frame::~Frame() } ASSERT(!m_lifeSupportTimer.isActive()); - -#if FRAME_LOADS_USER_STYLESHEET - delete m_userStyleSheetLoader; -#endif } void Frame::init() @@ -219,6 +230,11 @@ FrameLoader* Frame::loader() const return &m_loader; } +RedirectScheduler* Frame::redirectScheduler() const +{ + return &m_redirectScheduler; +} + FrameView* Frame::view() const { return m_view.get(); @@ -226,6 +242,12 @@ FrameView* Frame::view() const void Frame::setView(PassRefPtr<FrameView> view) { + // We the custom scroll bars as early as possible to prevent m_doc->detach() + // from messing with the view such that its scroll bars won't be torn down. + // FIXME: We should revisit this. + if (m_view) + m_view->detachCustomScrollbars(); + // Detach the document now, so any onUnload handlers get run - if // we wait until the view is destroyed, then things won't be // hooked up enough for some JavaScript calls to work. @@ -273,6 +295,15 @@ void Frame::setDocument(PassRefPtr<Document> newDoc) m_script.updateDocument(); } +#if ENABLE(ORIENTATION_EVENTS) +void Frame::sendOrientationChangeEvent(int orientation) +{ + m_orientation = orientation; + if (Document* doc = document()) + doc->dispatchWindowEvent(Event::create(eventNames().orientationchangeEvent, false, false)); +} +#endif // ENABLE(ORIENTATION_EVENTS) + Settings* Frame::settings() const { return m_page ? m_page->settings() : 0; @@ -829,14 +860,6 @@ void Frame::reapplyStyles() // We should probably eventually move it into its own function. m_doc->docLoader()->setAutoLoadImages(m_page && m_page->settings()->loadsImagesAutomatically()); -#if FRAME_LOADS_USER_STYLESHEET - const KURL userStyleSheetLocation = m_page ? m_page->settings()->userStyleSheetLocation() : KURL(); - if (!userStyleSheetLocation.isEmpty()) - setUserStyleSheetLocation(userStyleSheetLocation); - else - setUserStyleSheet(String()); -#endif - // FIXME: It's not entirely clear why the following is needed. // The document automatically does this as required when you set the style sheet. // But we had problems when this code was removed. Details are in @@ -844,6 +867,38 @@ void Frame::reapplyStyles() m_doc->updateStyleSelector(); } +void Frame::injectUserScripts(UserScriptInjectionTime injectionTime) +{ + if (!m_page) + return; + + // Walk the hashtable. Inject by world. + const UserScriptMap* userScripts = m_page->group().userScripts(); + if (!userScripts) + return; + UserScriptMap::const_iterator end = userScripts->end(); + for (UserScriptMap::const_iterator it = userScripts->begin(); it != end; ++it) + injectUserScriptsForWorld(it->first.get(), *it->second, injectionTime); +} + +void Frame::injectUserScriptsForWorld(DOMWrapperWorld* world, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime) +{ + if (userScripts.isEmpty()) + return; + + Document* doc = document(); + if (!doc) + return; + + Vector<ScriptSourceCode> sourceCode; + unsigned count = userScripts.size(); + for (unsigned i = 0; i < count; ++i) { + UserScript* script = userScripts[i].get(); + if (script->injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(doc->url(), script->whitelist(), script->blacklist())) + m_script.evaluateInWorld(ScriptSourceCode(script->source(), script->url()), world); + } +} + bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const { return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false); @@ -867,13 +922,36 @@ bool Frame::isContentEditable() const return m_doc->inDesignMode(); } -#if !PLATFORM(MAC) - -void Frame::setUseSecureKeyboardEntry(bool) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) +const short enableRomanKeyboardsOnly = -23; +#endif +void Frame::setUseSecureKeyboardEntry(bool enable) { -} - +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) + if (enable == IsSecureEventInputEnabled()) + return; + if (enable) { + EnableSecureEventInput(); +#ifdef BUILDING_ON_TIGER + KeyScript(enableRomanKeyboardsOnly); +#else + // WebKit substitutes nil for input context when in password field, which corresponds to null TSMDocument. So, there is + // no need to call TSMGetActiveDocument(), which may return an incorrect result when selection hasn't been yet updated + // after focusing a node. + CFArrayRef inputSources = TISCreateASCIICapableInputSourceList(); + TSMSetDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag, sizeof(CFArrayRef), &inputSources); + CFRelease(inputSources); +#endif + } else { + DisableSecureEventInput(); +#ifdef BUILDING_ON_TIGER + KeyScript(smKeyEnableKybds); +#else + TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag); #endif + } +#endif +} void Frame::updateSecureKeyboardEntryIfActive() { @@ -1192,7 +1270,7 @@ FloatRect Frame::selectionBounds(bool clipToVisibleContent) const return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect; } -void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleContent) const +void Frame::selectionTextRects(Vector<FloatRect>& rects, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent) const { RenderView* root = contentRenderer(); if (!root) @@ -1200,19 +1278,36 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte RefPtr<Range> selectedRange = selection()->toNormalizedRange(); - Vector<IntRect> intRects; - selectedRange->textRects(intRects, true); - - unsigned size = intRects.size(); FloatRect visibleContentRect = m_view->visibleContentRect(); - for (unsigned i = 0; i < size; ++i) - if (clipToVisibleContent) - rects.append(intersection(intRects[i], visibleContentRect)); - else - rects.append(intRects[i]); + + // FIMXE: we are appending empty rects to the list for those that fall outside visibleContentRect. + // We may not want to do that. + if (respectTransforms) { + Vector<FloatQuad> quads; + selectedRange->textQuads(quads, true); + + unsigned size = quads.size(); + for (unsigned i = 0; i < size; ++i) { + IntRect currRect = quads[i].enclosingBoundingBox(); + if (clipToVisibleContent) + rects.append(intersection(currRect, visibleContentRect)); + else + rects.append(currRect); + } + } else { + Vector<IntRect> intRects; + selectedRange->textRects(intRects, true); + + unsigned size = intRects.size(); + for (unsigned i = 0; i < size; ++i) { + if (clipToVisibleContent) + rects.append(intersection(intRects[i], visibleContentRect)); + else + rects.append(intRects[i]); + } + } } - // Scans logically forward from "start", including any child frames static HTMLFormElement *scanForForm(Node *start) { @@ -1559,6 +1654,11 @@ Page* Frame::page() const return m_page; } +void Frame::detachFromPage() +{ + m_page = 0; +} + EventHandler* Frame::eventHandler() const { return &m_eventHandler; @@ -1575,11 +1675,10 @@ void Frame::pageDestroyed() page()->focusController()->setFocusedFrame(0); script()->clearWindowShell(); - script()->clearScriptObjects(); script()->updatePlatformScriptObjects(); - m_page = 0; + detachFromPage(); } void Frame::disconnectOwnerElement() @@ -1609,7 +1708,13 @@ void Frame::focusWindow() // If we're a top level window, bring the window to the front. if (!tree()->parent()) +#ifdef ANDROID_USER_GESTURE + // FrameLoader::isProcessingUserGesture() will be false when a + // different frame tries to focus this frame through javascript. + page()->chrome()->focus(m_loader.isProcessingUserGesture()); +#else page()->chrome()->focus(); +#endif eventHandler()->focusDocumentView(); } @@ -1624,7 +1729,7 @@ void Frame::unfocusWindow() page()->chrome()->unfocus(); } -bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners) +bool Frame::shouldClose() { Chrome* chrome = page() ? page()->chrome() : 0; if (!chrome || !chrome->canRunBeforeUnloadConfirmPanel()) @@ -1638,7 +1743,8 @@ bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners) if (!body) return true; - RefPtr<BeforeUnloadEvent> beforeUnloadEvent = m_domWindow->dispatchBeforeUnloadEvent(alternateEventListeners); + RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create(); + m_domWindow->dispatchEvent(beforeUnloadEvent.get(), m_domWindow->document()); if (!beforeUnloadEvent->defaultPrevented()) doc->defaultEventHandler(beforeUnloadEvent.get()); @@ -1649,7 +1755,6 @@ bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners) return chrome->runBeforeUnloadConfirmPanel(text, this); } - void Frame::scheduleClose() { if (!shouldClose()) @@ -1759,7 +1864,6 @@ void Frame::createView(const IntSize& viewportSize, frameView = FrameView::create(this); frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode); - frameView->updateDefaultScrollbarState(); setView(frameView); |
