summaryrefslogtreecommitdiffstats
path: root/WebCore/page/Frame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/page/Frame.cpp')
-rw-r--r--WebCore/page/Frame.cpp186
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);