Chrome.cpp 18.5 KB
Newer Older
ggaren's avatar
ggaren committed
1
/*
2
 * Copyright (C) 2006, 2007, 2009, 2011 Apple Inc. All rights reserved.
3
 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
4
 * Copyright (C) 2012, Samsung Electronics. All rights reserved.
ggaren's avatar
ggaren committed
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
ddkilzer's avatar
ddkilzer committed
18 19
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
ggaren's avatar
ggaren committed
20 21 22 23 24
 */

#include "config.h"
#include "Chrome.h"

ggaren's avatar
ggaren committed
25
#include "ChromeClient.h"
26
#include "DNS.h"
27
#include "DateTimeChooser.h"
28
#include "Document.h"
29
#include "DocumentType.h"
30
#include "FileIconLoader.h"
31
#include "FileChooser.h"
adele@apple.com's avatar
adele@apple.com committed
32
#include "FileList.h"
ggaren's avatar
ggaren committed
33
#include "FloatRect.h"
andersca's avatar
andersca committed
34
#include "FrameTree.h"
35
#include "Geolocation.h"
36 37 38
#include "HTMLFormElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
darin's avatar
darin committed
39
#include "HitTestResult.h"
40
#include "Icon.h"
41
#include "InspectorInstrumentation.h"
darin@apple.com's avatar
darin@apple.com committed
42
#include "MainFrame.h"
ggaren's avatar
ggaren committed
43
#include "Page.h"
44
#include "PageGroupLoadDeferrer.h"
45
#include "PopupOpeningObserver.h"
46
#include "RenderObject.h"
andersca's avatar
andersca committed
47
#include "ResourceHandle.h"
weinig@apple.com's avatar
weinig@apple.com committed
48
#include "SecurityOrigin.h"
49
#include "Settings.h"
50
#include "StorageNamespace.h"
tristan's avatar
qt:  
tristan committed
51
#include "WindowFeatures.h"
ggaren's avatar
ggaren committed
52 53
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
ggaren's avatar
ggaren committed
54
#include <wtf/Vector.h>
55
#include <wtf/text/StringBuilder.h>
ggaren's avatar
ggaren committed
56

57
#if ENABLE(INPUT_TYPE_COLOR)
58 59 60
#include "ColorChooser.h"
#endif

ggaren's avatar
ggaren committed
61 62
namespace WebCore {

63 64
using namespace HTMLNames;

65
Chrome::Chrome(Page& page, ChromeClient& client)
ggaren's avatar
ggaren committed
66
    : m_page(page)
67
    , m_client(client)
68
    , m_displayID(0)
69 70 71
#if PLATFORM(IOS)
    , m_isDispatchViewportDataDidChangeSuppressed(false)
#endif
ggaren's avatar
ggaren committed
72 73 74
{
}

ggaren's avatar
ggaren committed
75 76
Chrome::~Chrome()
{
77
    m_client.chromeDestroyed();
ggaren's avatar
ggaren committed
78 79
}

80
void Chrome::invalidateRootView(const IntRect& updateRect, bool immediate)
81
{
82
    m_client.invalidateRootView(updateRect, immediate);
83 84
}

85
void Chrome::invalidateContentsAndRootView(const IntRect& updateRect, bool immediate)
86
{
87
    m_client.invalidateContentsAndRootView(updateRect, immediate);
88 89 90 91
}

void Chrome::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
{
92
    m_client.invalidateContentsForSlowScroll(updateRect, immediate);
hyatt@apple.com's avatar
hyatt@apple.com committed
93 94 95 96
}

void Chrome::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
{
97
    m_client.scroll(scrollDelta, rectToScroll, clipRect);
98
    InspectorInstrumentation::didScroll(&m_page);
99 100
}

101
#if USE(TILED_BACKING_STORE)
102
void Chrome::delegatedScrollRequested(const IntPoint& scrollPoint)
103
{
104
    m_client.delegatedScrollRequested(scrollPoint);
105 106 107
}
#endif

108
IntPoint Chrome::screenToRootView(const IntPoint& point) const
hyatt@apple.com's avatar
hyatt@apple.com committed
109
{
110
    return m_client.screenToRootView(point);
hyatt@apple.com's avatar
hyatt@apple.com committed
111 112
}

113
IntRect Chrome::rootViewToScreen(const IntRect& rect) const
hyatt@apple.com's avatar
hyatt@apple.com committed
114
{
115
    return m_client.rootViewToScreen(rect);
hyatt@apple.com's avatar
hyatt@apple.com committed
116 117
}

118
PlatformPageClient Chrome::platformPageClient() const
119
{
120
    return m_client.platformPageClient();
121 122
}

123 124
void Chrome::contentsSizeChanged(Frame* frame, const IntSize& size) const
{
125
    m_client.contentsSizeChanged(frame, size);
126 127
}

128 129
void Chrome::layoutUpdated(Frame* frame) const
{
130
    m_client.layoutUpdated(frame);
131 132
}

133
void Chrome::scrollRectIntoView(const IntRect& rect) const
hyatt@apple.com's avatar
hyatt@apple.com committed
134
{
135
    m_client.scrollRectIntoView(rect);
hyatt@apple.com's avatar
hyatt@apple.com committed
136 137
}

138 139
void Chrome::scrollbarsModeDidChange() const
{
140
    m_client.scrollbarsModeDidChange();
141 142
}

ggaren's avatar
ggaren committed
143 144
void Chrome::setWindowRect(const FloatRect& rect) const
{
145
    m_client.setWindowRect(rect);
ggaren's avatar
ggaren committed
146 147 148 149
}

FloatRect Chrome::windowRect() const
{
150
    return m_client.windowRect();
ggaren's avatar
ggaren committed
151 152 153 154
}

FloatRect Chrome::pageRect() const
{
155
    return m_client.pageRect();
ggaren's avatar
ggaren committed
156
}
157

ggaren's avatar
ggaren committed
158 159
void Chrome::focus() const
{
160
    m_client.focus();
ggaren's avatar
ggaren committed
161 162 163 164
}

void Chrome::unfocus() const
{
165
    m_client.unfocus();
ggaren's avatar
ggaren committed
166 167
}

aroben's avatar
aroben committed
168 169
bool Chrome::canTakeFocus(FocusDirection direction) const
{
170
    return m_client.canTakeFocus(direction);
aroben's avatar
aroben committed
171 172 173 174
}

void Chrome::takeFocus(FocusDirection direction) const
{
175
    m_client.takeFocus(direction);
aroben's avatar
aroben committed
176
}
177

178
void Chrome::focusedElementChanged(Element* element) const
179
{
180
    m_client.focusedElementChanged(element);
181 182
}

ap@apple.com's avatar
ap@apple.com committed
183 184
void Chrome::focusedFrameChanged(Frame* frame) const
{
185
    m_client.focusedFrameChanged(frame);
ap@apple.com's avatar
ap@apple.com committed
186 187
}

188
Page* Chrome::createWindow(Frame* frame, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction& action) const
ggaren's avatar
ggaren committed
189
{
190
    Page* newPage = m_client.createWindow(frame, request, features, action);
191 192
    if (!newPage)
        return 0;
darin@apple.com's avatar
darin@apple.com committed
193

194
    if (StorageNamespace* oldSessionStorage = m_page.sessionStorage(false))
195
        newPage->setSessionStorage(oldSessionStorage->copy(newPage));
darin@apple.com's avatar
darin@apple.com committed
196

197
    return newPage;
ggaren's avatar
ggaren committed
198 199 200 201
}

void Chrome::show() const
{
202
    m_client.show();
ggaren's avatar
ggaren committed
203 204 205
}

bool Chrome::canRunModal() const
ggaren's avatar
ggaren committed
206
{
207
    return m_client.canRunModal();
ggaren's avatar
ggaren committed
208 209
}

210
static bool canRunModalIfDuringPageDismissal(Page& page, ChromeClient::DialogType dialog, const String& message)
211
{
212
    for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
213
        FrameLoader::PageDismissalType dismissal = frame->loader().pageDismissalEventBeingDispatched();
214
        if (dismissal != FrameLoader::NoDismissal)
215
            return page.chrome().client().shouldRunModalDialogDuringPageDismissal(dialog, message, dismissal);
216 217 218 219
    }
    return true;
}

ggaren's avatar
ggaren committed
220
bool Chrome::canRunModalNow() const
ggaren's avatar
ggaren committed
221 222 223
{
    // If loads are blocked, we can't run modal because the contents
    // of the modal dialog will never show up!
224 225
    return canRunModal() && !ResourceHandle::loadsBlocked()
           && canRunModalIfDuringPageDismissal(m_page, ChromeClient::HTMLDialog, String());
ggaren's avatar
ggaren committed
226 227
}

ggaren's avatar
ggaren committed
228
void Chrome::runModal() const
ggaren's avatar
ggaren committed
229
{
aroben's avatar
aroben committed
230
    // Defer callbacks in all the other pages in this group, so we don't try to run JavaScript
ggaren's avatar
ggaren committed
231
    // in a way that could interact with this view.
232
    PageGroupLoadDeferrer deferrer(m_page, false);
ggaren's avatar
ggaren committed
233

darin's avatar
darin committed
234
    TimerBase::fireTimersInNestedEventLoop();
235
    m_client.runModal();
ggaren's avatar
ggaren committed
236 237
}

ggaren's avatar
ggaren committed
238 239
void Chrome::setToolbarsVisible(bool b) const
{
240
    m_client.setToolbarsVisible(b);
ggaren's avatar
ggaren committed
241 242 243 244
}

bool Chrome::toolbarsVisible() const
{
245
    return m_client.toolbarsVisible();
ggaren's avatar
ggaren committed
246 247 248 249
}

void Chrome::setStatusbarVisible(bool b) const
{
250
    m_client.setStatusbarVisible(b);
ggaren's avatar
ggaren committed
251 252 253 254
}

bool Chrome::statusbarVisible() const
{
255
    return m_client.statusbarVisible();
ggaren's avatar
ggaren committed
256 257 258 259
}

void Chrome::setScrollbarsVisible(bool b) const
{
260
    m_client.setScrollbarsVisible(b);
ggaren's avatar
ggaren committed
261 262 263 264
}

bool Chrome::scrollbarsVisible() const
{
265
    return m_client.scrollbarsVisible();
ggaren's avatar
ggaren committed
266 267 268 269
}

void Chrome::setMenubarVisible(bool b) const
{
270
    m_client.setMenubarVisible(b);
ggaren's avatar
ggaren committed
271 272 273 274
}

bool Chrome::menubarVisible() const
{
275
    return m_client.menubarVisible();
ggaren's avatar
ggaren committed
276 277 278 279
}

void Chrome::setResizable(bool b) const
{
280
    m_client.setResizable(b);
ggaren's avatar
ggaren committed
281 282
}

283 284
bool Chrome::canRunBeforeUnloadConfirmPanel()
{
285
    return m_client.canRunBeforeUnloadConfirmPanel();
286 287 288 289
}

bool Chrome::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
{
290
    // Defer loads in case the client method runs a new event loop that would
andersca's avatar
andersca committed
291
    // otherwise cause the load to continue while we're in the middle of executing JavaScript.
292
    PageGroupLoadDeferrer deferrer(m_page, true);
andersca's avatar
andersca committed
293

294
    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, message);
295
    bool ok = m_client.runBeforeUnloadConfirmPanel(message, frame);
296 297
    InspectorInstrumentation::didRunJavaScriptDialog(cookie);
    return ok;
298 299 300 301
}

void Chrome::closeWindowSoon()
{
302
    m_client.closeWindowSoon();
303 304
}

andersca's avatar
andersca committed
305 306
void Chrome::runJavaScriptAlert(Frame* frame, const String& message)
{
307 308
    if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::AlertDialog, message))
        return;
309

310
    // Defer loads in case the client method runs a new event loop that would
andersca's avatar
andersca committed
311
    // otherwise cause the load to continue while we're in the middle of executing JavaScript.
312
    PageGroupLoadDeferrer deferrer(m_page, true);
andersca's avatar
andersca committed
313

andersca's avatar
andersca committed
314
    ASSERT(frame);
315
    notifyPopupOpeningObservers();
316 317
    String displayMessage = frame->displayStringModifiedByEncoding(message);

318
    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, displayMessage);
319
    m_client.runJavaScriptAlert(frame, displayMessage);
320
    InspectorInstrumentation::didRunJavaScriptDialog(cookie);
andersca's avatar
andersca committed
321 322 323 324
}

bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
{
325 326
    if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::ConfirmDialog, message))
        return false;
327

328
    // Defer loads in case the client method runs a new event loop that would
andersca's avatar
andersca committed
329
    // otherwise cause the load to continue while we're in the middle of executing JavaScript.
330
    PageGroupLoadDeferrer deferrer(m_page, true);
andersca's avatar
andersca committed
331

andersca's avatar
andersca committed
332
    ASSERT(frame);
333
    notifyPopupOpeningObservers();
334 335
    String displayMessage = frame->displayStringModifiedByEncoding(message);

336
    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, displayMessage);
337
    bool ok = m_client.runJavaScriptConfirm(frame, displayMessage);
338 339
    InspectorInstrumentation::didRunJavaScriptDialog(cookie);
    return ok;
andersca's avatar
andersca committed
340 341 342 343
}

bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultValue, String& result)
{
344 345
    if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::PromptDialog, prompt))
        return false;
346

347
    // Defer loads in case the client method runs a new event loop that would
andersca's avatar
andersca committed
348
    // otherwise cause the load to continue while we're in the middle of executing JavaScript.
349
    PageGroupLoadDeferrer deferrer(m_page, true);
andersca's avatar
andersca committed
350

andersca's avatar
andersca committed
351
    ASSERT(frame);
352
    notifyPopupOpeningObservers();
353 354
    String displayPrompt = frame->displayStringModifiedByEncoding(prompt);

355
    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(&m_page, displayPrompt);
356
    bool ok = m_client.runJavaScriptPrompt(frame, displayPrompt, frame->displayStringModifiedByEncoding(defaultValue), result);
357
    InspectorInstrumentation::didRunJavaScriptDialog(cookie);
358

andersca's avatar
andersca committed
359
    if (ok)
hyatt@apple.com's avatar
hyatt@apple.com committed
360
        result = frame->displayStringModifiedByEncoding(result);
361

andersca's avatar
andersca committed
362 363 364 365 366 367
    return ok;
}

void Chrome::setStatusbarText(Frame* frame, const String& status)
{
    ASSERT(frame);
368
    m_client.setStatusbarText(frame->displayStringModifiedByEncoding(status));
andersca's avatar
andersca committed
369 370
}

andersca's avatar
andersca committed
371 372
bool Chrome::shouldInterruptJavaScript()
{
373
    // Defer loads in case the client method runs a new event loop that would
andersca's avatar
andersca committed
374
    // otherwise cause the load to continue while we're in the middle of executing JavaScript.
375
    PageGroupLoadDeferrer deferrer(m_page, true);
andersca's avatar
andersca committed
376

377
    return m_client.shouldInterruptJavaScript();
andersca's avatar
andersca committed
378 379
}

mjs's avatar
mjs committed
380 381
IntRect Chrome::windowResizerRect() const
{
382
    return m_client.windowResizerRect();
mjs's avatar
mjs committed
383 384
}

aroben's avatar
aroben committed
385 386
void Chrome::mouseDidMoveOverElement(const HitTestResult& result, unsigned modifierFlags)
{
387 388
    if (result.innerNode() && result.innerNode()->document().isDNSPrefetchEnabled())
        prefetchDNS(result.absoluteLinkURL().host());
389
    m_client.mouseDidMoveOverElement(result, modifierFlags);
390

391
    InspectorInstrumentation::mouseDidMoveOverElement(&m_page, result, modifierFlags);
aroben's avatar
aroben committed
392 393
}

394 395 396
void Chrome::setToolTip(const HitTestResult& result)
{
    // First priority is a potential toolTip representing a spelling or grammar error
397 398
    TextDirection toolTipDirection;
    String toolTip = result.spellingToolTip(toolTipDirection);
399 400

    // Next priority is a toolTip from a URL beneath the mouse (if preference is set to show those).
401
    if (toolTip.isEmpty() && m_page.settings().showsURLsInToolTips()) {
402
        if (Element* element = result.innerNonSharedElement()) {
403
            // Get tooltip representing form action, if relevant
404 405 406
            if (isHTMLInputElement(element)) {
                HTMLInputElement* input = toHTMLInputElement(element);
                if (input->isSubmitButton()) {
407
                    if (HTMLFormElement* form = input->form()) {
408
                        toolTip = form->action();
409
                        if (form->renderer())
410
                            toolTipDirection = form->renderer()->style().direction();
411 412 413
                        else
                            toolTipDirection = LTR;
                    }
414
                }
415 416 417 418
            }
        }

        // Get tooltip representing link's URL
419
        if (toolTip.isEmpty()) {
420
            // FIXME: Need to pass this URL through userVisibleString once that's in WebCore
weinig@apple.com's avatar
weinig@apple.com committed
421
            toolTip = result.absoluteLinkURL().string();
422 423 424
            // URL always display as LTR.
            toolTipDirection = LTR;
        }
425 426
    }

adele@apple.com's avatar
adele@apple.com committed
427
    // Next we'll consider a tooltip for element with "title" attribute
428
    if (toolTip.isEmpty())
429
        toolTip = result.title(toolTipDirection);
430

431
    if (toolTip.isEmpty() && m_page.settings().showsToolTipOverTruncatedText())
432 433
        toolTip = result.innerTextIfTruncated(toolTipDirection);

adele@apple.com's avatar
adele@apple.com committed
434 435
    // Lastly, for <input type="file"> that allow multiple files, we'll consider a tooltip for the selected filenames
    if (toolTip.isEmpty()) {
436 437 438
        if (Element* element = result.innerNonSharedElement()) {
            if (isHTMLInputElement(element)) {
                toolTip = toHTMLInputElement(element)->defaultToolTip();
439 440 441 442 443 444 445

                // FIXME: We should obtain text direction of tooltip from
                // ChromeClient or platform. As of October 2011, all client
                // implementations don't use text direction information for
                // ChromeClient::setToolTip. We'll work on tooltip text
                // direction during bidi cleanup in form inputs.
                toolTipDirection = LTR;
adele@apple.com's avatar
adele@apple.com committed
446 447 448
            }
        }
    }
449

450
    m_client.setToolTip(toolTip, toolTipDirection);
451 452
}

453
void Chrome::print(Frame* frame)
aliceli1's avatar
aliceli1 committed
454
{
455
    // FIXME: This should have PageGroupLoadDeferrer, like runModal() or runJavaScriptAlert(), becasue it's no different from those.
456
    m_client.print(frame);
aliceli1's avatar
aliceli1 committed
457 458
}

459 460
void Chrome::enableSuddenTermination()
{
461
    m_client.enableSuddenTermination();
462 463 464 465
}

void Chrome::disableSuddenTermination()
{
466
    m_client.disableSuddenTermination();
467 468
}

469
#if ENABLE(DIRECTORY_UPLOAD)
470
void Chrome::enumerateChosenDirectory(FileChooser* fileChooser)
471
{
472
    m_client.enumerateChosenDirectory(fileChooser);
473 474 475
}
#endif

476
#if ENABLE(INPUT_TYPE_COLOR)
477
PassOwnPtr<ColorChooser> Chrome::createColorChooser(ColorChooserClient* client, const Color& initialColor)
478
{
479
    notifyPopupOpeningObservers();
480
    return m_client.createColorChooser(client, initialColor);
481 482 483
}
#endif

484
#if ENABLE(DATE_AND_TIME_INPUT_TYPES) && !PLATFORM(IOS)
485 486 487
PassRefPtr<DateTimeChooser> Chrome::openDateTimeChooser(DateTimeChooserClient* client, const DateTimeChooserParameters& parameters)
{
    notifyPopupOpeningObservers();
488
    return m_client.openDateTimeChooser(client, parameters);
489 490 491
}
#endif

weinig@apple.com's avatar
weinig@apple.com committed
492 493
void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
{
494
    notifyPopupOpeningObservers();
495
    m_client.runOpenPanel(frame, fileChooser);
weinig@apple.com's avatar
weinig@apple.com committed
496
}
497

498
void Chrome::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* loader)
499
{
500
    m_client.loadIconForFiles(filenames, loader);
501 502
}

503
void Chrome::dispatchViewportPropertiesDidChange(const ViewportArguments& arguments) const
504
{
505 506 507 508
#if PLATFORM(IOS)
    if (m_isDispatchViewportDataDidChangeSuppressed)
        return;
#endif
509
    m_client.dispatchViewportPropertiesDidChange(arguments);
510 511
}

512
void Chrome::setCursor(const Cursor& cursor)
513
{
514
#if ENABLE(CURSOR_SUPPORT)
515
    m_client.setCursor(cursor);
516 517 518
#else
    UNUSED_PARAM(cursor);
#endif
519 520
}

521 522
void Chrome::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
{
523
#if ENABLE(CURSOR_SUPPORT)
524
    m_client.setCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves);
525 526 527
#else
    UNUSED_PARAM(hiddenUntilMouseMoves);
#endif
528 529
}

530 531 532
#if ENABLE(REQUEST_ANIMATION_FRAME)
void Chrome::scheduleAnimation()
{
533
#if !USE(REQUEST_ANIMATION_FRAME_TIMER)
534
    m_client.scheduleAnimation();
535
#endif
536 537 538
}
#endif

539 540 541 542 543 544 545 546 547 548 549 550
PlatformDisplayID Chrome::displayID() const
{
    return m_displayID;
}

void Chrome::windowScreenDidChange(PlatformDisplayID displayID)
{
    if (displayID == m_displayID)
        return;

    m_displayID = displayID;

551
    for (Frame* frame = &m_page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
552 553 554 555 556
        if (frame->document())
            frame->document()->windowScreenDidChange(displayID);
    }
}

darin@apple.com's avatar
darin@apple.com committed
557 558
// --------

559
#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
560
void ChromeClient::annotatedRegionsChanged()
darin@apple.com's avatar
darin@apple.com committed
561 562
{
}
ddkilzer@apple.com's avatar
ddkilzer@apple.com committed
563
#endif
darin@apple.com's avatar
darin@apple.com committed
564

darin@apple.com's avatar
darin@apple.com committed
565 566 567 568
void ChromeClient::populateVisitedLinks()
{
}

darin@apple.com's avatar
darin@apple.com committed
569 570 571 572 573 574 575 576 577
FloatRect ChromeClient::customHighlightRect(Node*, const AtomicString&, const FloatRect&)
{
    return FloatRect();
}

void ChromeClient::paintCustomHighlight(Node*, const AtomicString&, const FloatRect&, const FloatRect&, bool, bool)
{
}

adele@apple.com's avatar
adele@apple.com committed
578 579 580 581 582 583 584 585
bool ChromeClient::shouldReplaceWithGeneratedFileForUpload(const String&, String&)
{
    return false;
}

String ChromeClient::generateReplacementFile(const String&)
{
    ASSERT_NOT_REACHED();
586
    return String();
adele@apple.com's avatar
adele@apple.com committed
587 588
}

589 590
bool Chrome::selectItemWritingDirectionIsNatural()
{
591
    return m_client.selectItemWritingDirectionIsNatural();
592 593
}

594 595
bool Chrome::selectItemAlignmentFollowsMenuWritingDirection()
{
596
    return m_client.selectItemAlignmentFollowsMenuWritingDirection();
597 598
}

599 600
bool Chrome::hasOpenedPopup() const
{
601
    return m_client.hasOpenedPopup();
602 603
}

604 605
PassRefPtr<PopupMenu> Chrome::createPopupMenu(PopupMenuClient* client) const
{
606
    notifyPopupOpeningObservers();
607
    return m_client.createPopupMenu(client);
608 609 610 611
}

PassRefPtr<SearchPopupMenu> Chrome::createSearchPopupMenu(PopupMenuClient* client) const
{
612
    notifyPopupOpeningObservers();
613
    return m_client.createSearchPopupMenu(client);
614
}
andersca's avatar
andersca committed
615

616 617
bool Chrome::requiresFullscreenForVideoPlayback()
{
618
    return m_client.requiresFullscreenForVideoPlayback();
619 620
}

621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
#if PLATFORM(IOS)
// FIXME: Make argument, frame, a reference.
void Chrome::didReceiveDocType(Frame* frame)
{
    ASSERT(frame);
    if (!frame->isMainFrame())
        return;

    DocumentType* documentType = frame->document()->doctype();
    if (!documentType) {
        // FIXME: We should notify the client when <!DOCTYPE> is removed so that
        // it can adjust the viewport accordingly. See <rdar://problem/15417894>.
        return;
    }

    if (documentType->publicId().contains("xhtml mobile", false))
        m_client.didReceiveMobileDocType();
}
#endif

641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
void Chrome::registerPopupOpeningObserver(PopupOpeningObserver* observer)
{
    ASSERT(observer);
    m_popupOpeningObservers.append(observer);
}

void Chrome::unregisterPopupOpeningObserver(PopupOpeningObserver* observer)
{
    size_t index = m_popupOpeningObservers.find(observer);
    ASSERT(index != notFound);
    m_popupOpeningObservers.remove(index);
}

void Chrome::notifyPopupOpeningObservers() const
{
    const Vector<PopupOpeningObserver*> observers(m_popupOpeningObservers);
    for (size_t i = 0; i < observers.size(); ++i)
        observers[i]->willOpenPopup();
}

ggaren's avatar
ggaren committed
661
} // namespace WebCore