Reviewed by Adam.
[WebKit-https.git] / WebCore / page / DOMWindow.cpp
1 /*
2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DOMWindow.h"
28
29 #include "BarInfo.h"
30 #include "CSSComputedStyleDeclaration.h"
31 #include "CSSRuleList.h"
32 #include "CSSStyleSelector.h"
33 #include "Chrome.h"
34 #include "DOMSelection.h"
35 #include "Document.h"
36 #include "Element.h"
37 #include "Frame.h"
38 #include "FrameLoader.h"
39 #include "FrameTree.h"
40 #include "FrameView.h"
41 #include "History.h"
42 #include "Page.h"
43 #include "PlatformScreen.h"
44 #include "PlatformString.h"
45 #include "Screen.h"
46
47 namespace WebCore {
48
49 DOMWindow::DOMWindow(Frame* frame)
50     : m_frame(frame)
51 {
52 }
53
54 DOMWindow::~DOMWindow()
55 {
56 }
57
58 void DOMWindow::disconnectFrame()
59 {
60     m_frame = 0;
61     clear();
62 }
63
64 void DOMWindow::clear()
65 {
66     if (m_screen)
67         m_screen->disconnectFrame();
68     m_screen = 0;
69
70     if (m_selection)
71         m_selection->disconnectFrame();
72     m_selection = 0;
73
74     if (m_history)
75         m_history->disconnectFrame();
76     m_history = 0;
77
78     if (m_locationbar)
79         m_locationbar->disconnectFrame();
80     m_locationbar = 0;
81
82     if (m_menubar)
83         m_menubar->disconnectFrame();
84     m_menubar = 0;
85
86     if (m_personalbar)
87         m_personalbar->disconnectFrame();
88     m_personalbar = 0;
89
90     if (m_scrollbars)
91         m_scrollbars->disconnectFrame();
92     m_scrollbars = 0;
93
94     if (m_statusbar)
95         m_statusbar->disconnectFrame();
96     m_statusbar = 0;
97
98     if (m_toolbar)
99         m_toolbar->disconnectFrame();
100     m_toolbar = 0;
101 }
102
103 Screen* DOMWindow::screen() const
104 {
105     if (!m_screen)
106         m_screen = new Screen(m_frame);
107     return m_screen.get();
108 }
109
110 History* DOMWindow::history() const
111 {
112     if (!m_history)
113         m_history = new History(m_frame);
114     return m_history.get();
115 }
116
117 BarInfo* DOMWindow::locationbar() const
118 {
119     if (!m_locationbar)
120         m_locationbar = new BarInfo(m_frame, BarInfo::Locationbar);
121     return m_locationbar.get();
122 }
123
124 BarInfo* DOMWindow::menubar() const
125 {
126     if (!m_menubar)
127         m_menubar = new BarInfo(m_frame, BarInfo::Menubar);
128     return m_menubar.get();
129 }
130
131 BarInfo* DOMWindow::personalbar() const
132 {
133     if (!m_personalbar)
134         m_personalbar = new BarInfo(m_frame, BarInfo::Personalbar);
135     return m_personalbar.get();
136 }
137
138 BarInfo* DOMWindow::scrollbars() const
139 {
140     if (!m_scrollbars)
141         m_scrollbars = new BarInfo(m_frame, BarInfo::Scrollbars);
142     return m_scrollbars.get();
143 }
144
145 BarInfo* DOMWindow::statusbar() const
146 {
147     if (!m_statusbar)
148         m_statusbar = new BarInfo(m_frame, BarInfo::Statusbar);
149     return m_statusbar.get();
150 }
151
152 BarInfo* DOMWindow::toolbar() const
153 {
154     if (!m_toolbar)
155         m_toolbar = new BarInfo(m_frame, BarInfo::Toolbar);
156     return m_toolbar.get();
157 }
158
159 DOMSelection* DOMWindow::getSelection()
160 {
161     if (!m_selection)
162         m_selection = new DOMSelection(m_frame);
163     return m_selection.get();
164 }
165
166 Element* DOMWindow::frameElement() const
167 {
168     if (!m_frame)
169         return 0;
170
171     Document* doc = m_frame->document();
172     ASSERT(doc);
173     if (!doc)
174         return 0;
175
176     // FIXME: could this use m_frame->ownerElement() instead of going through the Document.
177     return doc->ownerElement();
178 }
179
180 void DOMWindow::focus()
181 {
182     if (!m_frame)
183         return;
184
185     m_frame->focusWindow();
186 }
187
188 void DOMWindow::blur()
189 {
190     if (!m_frame)
191         return;
192
193     m_frame->unfocusWindow();
194 }
195
196 void DOMWindow::close()
197 {
198     if (!m_frame)
199         return;
200
201     if (m_frame->loader()->openedByDOM() || m_frame->loader()->getHistoryLength() <= 1)
202         m_frame->scheduleClose();
203 }
204
205 void DOMWindow::print()
206 {
207     if (!m_frame)
208         return;
209
210     Page* page = m_frame->page();
211     if (!page)
212         return;
213
214     page->chrome()->print(m_frame);
215 }
216
217 void DOMWindow::stop()
218 {
219     if (!m_frame)
220         return;
221
222     m_frame->loader()->stopForUserCancel();
223 }
224
225 void DOMWindow::alert(const String& message)
226 {
227     if (!m_frame)
228         return;
229
230     Document* doc = m_frame->document();
231     ASSERT(doc);
232     if (doc)
233         doc->updateRendering();
234
235     Page* page = m_frame->page();
236     if (!page)
237         return;
238
239     page->chrome()->runJavaScriptAlert(m_frame, message);
240 }
241
242 bool DOMWindow::confirm(const String& message)
243 {
244     if (!m_frame)
245         return false;
246
247     Document* doc = m_frame->document();
248     ASSERT(doc);
249     if (doc)
250         doc->updateRendering();
251
252     Page* page = m_frame->page();
253     if (!page)
254         return false;
255
256     return page->chrome()->runJavaScriptConfirm(m_frame, message);
257 }
258
259 String DOMWindow::prompt(const String& message, const String& defaultValue)
260 {
261     if (!m_frame)
262         return String();
263
264     Document* doc = m_frame->document();
265     ASSERT(doc);
266     if (doc)
267         doc->updateRendering();
268
269     Page* page = m_frame->page();
270     if (!page)
271         return String();
272
273     String returnValue;
274     if (page->chrome()->runJavaScriptPrompt(m_frame, message, defaultValue, returnValue))
275         return returnValue;
276
277     return String();
278 }
279
280 bool DOMWindow::find(const String& string, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const
281 {
282     if (!m_frame)
283         return false;
284
285     // FIXME (13016): Support wholeWord, searchInFrames and showDialog
286     return m_frame->findString(string, !backwards, caseSensitive, wrap, false);
287 }
288
289 bool DOMWindow::offscreenBuffering() const
290 {
291     return true;
292 }
293
294 int DOMWindow::outerHeight() const
295 {
296     if (!m_frame)
297         return 0;
298
299     Page* page = m_frame->page();
300     if (!page)
301         return 0;
302
303     return static_cast<int>(page->chrome()->windowRect().height());
304 }
305
306 int DOMWindow::outerWidth() const
307 {
308     if (!m_frame)
309         return 0;
310
311     Page* page = m_frame->page();
312     if (!page)
313         return 0;
314
315     return static_cast<int>(page->chrome()->windowRect().width());
316 }
317
318 int DOMWindow::innerHeight() const
319 {
320     if (!m_frame)
321         return 0;
322
323     FrameView* view = m_frame->view();
324     if (!view)
325         return 0;
326
327     return view->height();
328 }
329
330 int DOMWindow::innerWidth() const
331 {
332     if (!m_frame)
333         return 0;
334
335     FrameView* view = m_frame->view();
336     if (!view)
337         return 0;
338
339     return view->width();
340 }
341
342 int DOMWindow::screenX() const
343 {
344     if (!m_frame)
345         return 0;
346
347     Page* page = m_frame->page();
348     if (!page)
349         return 0;
350
351     return static_cast<int>(page->chrome()->windowRect().x());
352 }
353
354 int DOMWindow::screenY() const
355 {
356     if (!m_frame)
357         return 0;
358
359     Page* page = m_frame->page();
360     if (!page)
361         return 0;
362
363     return static_cast<int>(page->chrome()->windowRect().y());
364 }
365
366 int DOMWindow::scrollX() const
367 {
368     if (!m_frame)
369         return 0;
370
371     FrameView* view = m_frame->view();
372     if (!view)
373         return 0;
374
375     Document* doc = m_frame->document();
376     ASSERT(doc);
377     if (doc)
378         doc->updateLayoutIgnorePendingStylesheets();
379
380     return view->contentsX();
381 }
382
383 int DOMWindow::scrollY() const
384 {
385     if (!m_frame)
386         return 0;
387
388     FrameView* view = m_frame->view();
389     if (!view)
390         return 0;
391
392     Document* doc = m_frame->document();
393     ASSERT(doc);
394     if (doc)
395         doc->updateLayoutIgnorePendingStylesheets();
396
397     return view->contentsY();
398 }
399
400 bool DOMWindow::closed() const
401 {
402     return !m_frame;
403 }
404
405 unsigned DOMWindow::length() const
406 {
407     if (!m_frame)
408         return 0;
409
410     return m_frame->tree()->childCount();
411 }
412
413 String DOMWindow::name() const
414 {
415     if (!m_frame)
416         return String();
417
418     return m_frame->tree()->name();
419 }
420
421 void DOMWindow::setName(const String& string)
422 {
423     if (!m_frame)
424         return;
425
426     m_frame->tree()->setName(string);
427 }
428
429 String DOMWindow::status() const
430 {
431     if (!m_frame)
432         return String();
433
434     return m_frame->jsStatusBarText();
435 }
436
437 void DOMWindow::setStatus(const String& string)
438 {
439     if (!m_frame)
440         return;
441
442     m_frame->setJSStatusBarText(string);
443 }
444
445 String DOMWindow::defaultStatus() const
446 {
447     if (!m_frame)
448         return String();
449
450     return m_frame->jsDefaultStatusBarText();
451 }
452
453 void DOMWindow::setDefaultStatus(const String& string)
454 {
455     if (!m_frame)
456         return;
457
458     m_frame->setJSDefaultStatusBarText(string);
459 }
460
461 DOMWindow* DOMWindow::self() const
462 {
463     if (!m_frame)
464         return 0;
465
466     return m_frame->domWindow();
467 }
468
469 DOMWindow* DOMWindow::opener() const
470 {
471     if (!m_frame)
472         return 0;
473
474     Frame* opener = m_frame->loader()->opener();
475     if (!opener)
476         return 0;
477
478     return opener->domWindow();
479 }
480
481 DOMWindow* DOMWindow::parent() const
482 {
483     if (!m_frame)
484         return 0;
485
486     Frame* parent = m_frame->tree()->parent();
487     if (parent)
488         return parent->domWindow();
489
490     return m_frame->domWindow();
491 }
492
493 DOMWindow* DOMWindow::top() const
494 {
495     if (!m_frame)
496         return 0;
497
498     Page* page = m_frame->page();
499     if (!page)
500         return 0;
501
502     return page->mainFrame()->domWindow();
503 }
504
505 Document* DOMWindow::document() const
506 {
507     if (!m_frame)
508         return 0;
509
510     ASSERT(m_frame->document());
511     return m_frame->document();
512 }
513
514 PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* elt, const String&) const
515 {
516     if (!elt)
517         return 0;
518
519     // FIXME: This needs to work with pseudo elements.
520     return new CSSComputedStyleDeclaration(elt);
521 }
522
523 PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* elt, const String& pseudoElt, bool authorOnly) const
524 {
525     if (!m_frame)
526         return 0;
527
528     Document* doc = m_frame->document();
529     ASSERT(doc);
530     if (!doc)
531         return 0;
532
533     if (!pseudoElt.isEmpty())
534         return doc->styleSelector()->pseudoStyleRulesForElement(elt, pseudoElt.impl(), authorOnly);
535     return doc->styleSelector()->styleRulesForElement(elt, authorOnly);
536 }
537
538 double DOMWindow::devicePixelRatio() const
539 {
540     if (!m_frame)
541         return 0.0;
542
543     Page* page = m_frame->page();
544     if (!page)
545         return 0.0;
546
547     return page->chrome()->scaleFactor();
548 }
549
550 } // namespace WebCore