tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / html / HTMLBodyElement.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Simon Hausmann (hausmann@kde.org)
5  *           (C) 2001 Dirk Mueller (mueller@kde.org)
6  * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include "config.h"
25 #include "HTMLBodyElement.h"
26
27 #include "Attribute.h"
28 #include "CSSParser.h"
29 #include "CSSValueKeywords.h"
30 #include "EventNames.h"
31 #include "Frame.h"
32 #include "FrameView.h"
33 #include "HTMLFrameElementBase.h"
34 #include "HTMLNames.h"
35 #include "HTMLParserIdioms.h"
36 #include "Page.h"
37 #include "ScriptEventListener.h"
38
39 namespace WebCore {
40
41 using namespace HTMLNames;
42
43 HTMLBodyElement::HTMLBodyElement(const QualifiedName& tagName, Document* document)
44     : HTMLElement(tagName, document)
45 {
46     ASSERT(hasTagName(bodyTag));
47 }
48
49 PassRefPtr<HTMLBodyElement> HTMLBodyElement::create(Document* document)
50 {
51     return adoptRef(new HTMLBodyElement(bodyTag, document));
52 }
53
54 PassRefPtr<HTMLBodyElement> HTMLBodyElement::create(const QualifiedName& tagName, Document* document)
55 {
56     return adoptRef(new HTMLBodyElement(tagName, document));
57 }
58
59 HTMLBodyElement::~HTMLBodyElement()
60 {
61 }
62
63 bool HTMLBodyElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
64 {
65     if (attrName == backgroundAttr) {
66         result = (MappedAttributeEntry)(eLastEntry + document()->docID());
67         return false;
68     } 
69     
70     if (attrName == bgcolorAttr ||
71         attrName == textAttr ||
72         attrName == marginwidthAttr ||
73         attrName == leftmarginAttr ||
74         attrName == marginheightAttr ||
75         attrName == topmarginAttr ||
76         attrName == bgpropertiesAttr) {
77         result = eUniversal;
78         return false;
79     }
80
81     return HTMLElement::mapToEntry(attrName, result);
82 }
83
84 void HTMLBodyElement::parseMappedAttribute(Attribute* attr)
85 {
86     if (attr->name() == backgroundAttr) {
87         String url = stripLeadingAndTrailingHTMLSpaces(attr->value());
88         if (!url.isEmpty())
89             addCSSImageProperty(attr, CSSPropertyBackgroundImage, document()->completeURL(url).string());
90     } else if (attr->name() == marginwidthAttr || attr->name() == leftmarginAttr) {
91         addCSSLength(attr, CSSPropertyMarginRight, attr->value());
92         addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
93     } else if (attr->name() == marginheightAttr || attr->name() == topmarginAttr) {
94         addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
95         addCSSLength(attr, CSSPropertyMarginTop, attr->value());
96     } else if (attr->name() == bgcolorAttr) {
97         addCSSColor(attr, CSSPropertyBackgroundColor, attr->value());
98     } else if (attr->name() == textAttr) {
99         addCSSColor(attr, CSSPropertyColor, attr->value());
100     } else if (attr->name() == bgpropertiesAttr) {
101         if (equalIgnoringCase(attr->value(), "fixed"))
102             addCSSProperty(attr, CSSPropertyBackgroundAttachment, CSSValueFixed);
103     } else if (attr->name() == vlinkAttr ||
104                attr->name() == alinkAttr ||
105                attr->name() == linkAttr) {
106         if (attr->isNull()) {
107             if (attr->name() == linkAttr)
108                 document()->resetLinkColor();
109             else if (attr->name() == vlinkAttr)
110                 document()->resetVisitedLinkColor();
111             else
112                 document()->resetActiveLinkColor();
113         } else {
114             RGBA32 color;
115             if (CSSParser::parseColor(color, attr->value(), !document()->inQuirksMode())) {
116                 if (attr->name() == linkAttr)
117                     document()->setLinkColor(color);
118                 else if (attr->name() == vlinkAttr)
119                     document()->setVisitedLinkColor(color);
120                 else
121                     document()->setActiveLinkColor(color);
122             }
123         }
124         
125         if (attached())
126             document()->recalcStyle(Force);
127     } else if (attr->name() == onloadAttr)
128         document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), attr));
129     else if (attr->name() == onbeforeunloadAttr)
130         document()->setWindowAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(document()->frame(), attr));
131     else if (attr->name() == onunloadAttr)
132         document()->setWindowAttributeEventListener(eventNames().unloadEvent, createAttributeEventListener(document()->frame(), attr));
133     else if (attr->name() == onpagehideAttr)
134         document()->setWindowAttributeEventListener(eventNames().pagehideEvent, createAttributeEventListener(document()->frame(), attr));
135     else if (attr->name() == onpageshowAttr)
136         document()->setWindowAttributeEventListener(eventNames().pageshowEvent, createAttributeEventListener(document()->frame(), attr));
137     else if (attr->name() == onpopstateAttr)
138         document()->setWindowAttributeEventListener(eventNames().popstateEvent, createAttributeEventListener(document()->frame(), attr));
139     else if (attr->name() == onblurAttr)
140         document()->setWindowAttributeEventListener(eventNames().blurEvent, createAttributeEventListener(document()->frame(), attr));
141     else if (attr->name() == onfocusAttr)
142         document()->setWindowAttributeEventListener(eventNames().focusEvent, createAttributeEventListener(document()->frame(), attr));
143 #if ENABLE(ORIENTATION_EVENTS)
144     else if (attr->name() == onorientationchangeAttr)
145         document()->setWindowAttributeEventListener(eventNames().orientationchangeEvent, createAttributeEventListener(document()->frame(), attr));
146 #endif
147     else if (attr->name() == onhashchangeAttr)
148         document()->setWindowAttributeEventListener(eventNames().hashchangeEvent, createAttributeEventListener(document()->frame(), attr));
149     else if (attr->name() == onresizeAttr)
150         document()->setWindowAttributeEventListener(eventNames().resizeEvent, createAttributeEventListener(document()->frame(), attr));
151     else if (attr->name() == onscrollAttr)
152         document()->setWindowAttributeEventListener(eventNames().scrollEvent, createAttributeEventListener(document()->frame(), attr));
153     else if (attr->name() == onselectionchangeAttr)
154         document()->setAttributeEventListener(eventNames().selectionchangeEvent, createAttributeEventListener(document()->frame(), attr));
155     else if (attr->name() == onstorageAttr)
156         document()->setWindowAttributeEventListener(eventNames().storageEvent, createAttributeEventListener(document()->frame(), attr));
157     else if (attr->name() == ononlineAttr)
158         document()->setWindowAttributeEventListener(eventNames().onlineEvent, createAttributeEventListener(document()->frame(), attr));
159     else if (attr->name() == onofflineAttr)
160         document()->setWindowAttributeEventListener(eventNames().offlineEvent, createAttributeEventListener(document()->frame(), attr));
161     else
162         HTMLElement::parseMappedAttribute(attr);
163 }
164
165 void HTMLBodyElement::insertedIntoDocument()
166 {
167     HTMLElement::insertedIntoDocument();
168
169     // FIXME: Perhaps this code should be in attach() instead of here.
170     Element* ownerElement = document()->ownerElement();
171     if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
172         HTMLFrameElementBase* ownerFrameElement = static_cast<HTMLFrameElementBase*>(ownerElement);
173         int marginWidth = ownerFrameElement->marginWidth();
174         if (marginWidth != -1)
175             setAttribute(marginwidthAttr, String::number(marginWidth));
176         int marginHeight = ownerFrameElement->marginHeight();
177         if (marginHeight != -1)
178             setAttribute(marginheightAttr, String::number(marginHeight));
179     }
180
181     // FIXME: This call to scheduleRelayout should not be needed here.
182     // But without it we hang during WebKit tests; need to fix that and remove this.
183     if (FrameView* view = document()->view())
184         view->scheduleRelayout();
185
186     if (document() && document()->page())
187         document()->page()->updateViewportArguments();
188 }
189
190 bool HTMLBodyElement::isURLAttribute(Attribute *attr) const
191 {
192     return attr->name() == backgroundAttr || HTMLElement::isURLAttribute(attr);
193 }
194
195 bool HTMLBodyElement::supportsFocus() const
196 {
197     return rendererIsEditable() || HTMLElement::supportsFocus();
198 }
199
200 String HTMLBodyElement::aLink() const
201 {
202     return getAttribute(alinkAttr);
203 }
204
205 void HTMLBodyElement::setALink(const String& value)
206 {
207     setAttribute(alinkAttr, value);
208 }
209
210 String HTMLBodyElement::bgColor() const
211 {
212     return getAttribute(bgcolorAttr);
213 }
214
215 void HTMLBodyElement::setBgColor(const String& value)
216 {
217     setAttribute(bgcolorAttr, value);
218 }
219
220 String HTMLBodyElement::link() const
221 {
222     return getAttribute(linkAttr);
223 }
224
225 void HTMLBodyElement::setLink(const String& value)
226 {
227     setAttribute(linkAttr, value);
228 }
229
230 String HTMLBodyElement::text() const
231 {
232     return getAttribute(textAttr);
233 }
234
235 void HTMLBodyElement::setText(const String& value)
236 {
237     setAttribute(textAttr, value);
238 }
239
240 String HTMLBodyElement::vLink() const
241 {
242     return getAttribute(vlinkAttr);
243 }
244
245 void HTMLBodyElement::setVLink(const String& value)
246 {
247     setAttribute(vlinkAttr, value);
248 }
249
250 static int adjustForZoom(int value, Document* document)
251 {
252     Frame* frame = document->frame();
253     float zoomFactor = frame->pageZoomFactor() * frame->frameScaleFactor();
254     if (zoomFactor == 1)
255         return value;
256     // Needed because of truncation (rather than rounding) when scaling up.
257     if (zoomFactor > 1)
258         value++;
259     return static_cast<int>(value / zoomFactor);
260 }
261
262 int HTMLBodyElement::scrollLeft()
263 {
264     // Update the document's layout.
265     Document* document = this->document();
266     document->updateLayoutIgnorePendingStylesheets();
267     FrameView* view = document->view();
268     return view ? adjustForZoom(view->scrollX(), document) : 0;
269 }
270
271 void HTMLBodyElement::setScrollLeft(int scrollLeft)
272 {
273     Document* document = this->document();
274     document->updateLayoutIgnorePendingStylesheets();
275     Frame* frame = document->frame();
276     if (!frame)
277         return;
278     FrameView* view = frame->view();
279     if (!view)
280         return;
281     view->setScrollPosition(IntPoint(static_cast<int>(scrollLeft * frame->pageZoomFactor() * frame->frameScaleFactor()), view->scrollY()));
282 }
283
284 int HTMLBodyElement::scrollTop()
285 {
286     // Update the document's layout.
287     Document* document = this->document();
288     document->updateLayoutIgnorePendingStylesheets();
289     FrameView* view = document->view();
290     return view ? adjustForZoom(view->scrollY(), document) : 0;
291 }
292
293 void HTMLBodyElement::setScrollTop(int scrollTop)
294 {
295     Document* document = this->document();
296     document->updateLayoutIgnorePendingStylesheets();
297     Frame* frame = document->frame();
298     if (!frame)
299         return;
300     FrameView* view = frame->view();
301     if (!view)
302         return;
303     view->setScrollPosition(IntPoint(view->scrollX(), static_cast<int>(scrollTop * frame->pageZoomFactor() * frame->frameScaleFactor())));
304 }
305
306 int HTMLBodyElement::scrollHeight()
307 {
308     // Update the document's layout.
309     Document* document = this->document();
310     document->updateLayoutIgnorePendingStylesheets();
311     FrameView* view = document->view();
312     return view ? adjustForZoom(view->contentsHeight(), document) : 0;    
313 }
314
315 int HTMLBodyElement::scrollWidth()
316 {
317     // Update the document's layout.
318     Document* document = this->document();
319     document->updateLayoutIgnorePendingStylesheets();
320     FrameView* view = document->view();
321     return view ? adjustForZoom(view->contentsWidth(), document) : 0;    
322 }
323
324 void HTMLBodyElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
325 {
326     HTMLElement::addSubresourceAttributeURLs(urls);
327
328     addSubresourceURL(urls, document()->completeURL(getAttribute(backgroundAttr)));
329 }
330
331 } // namespace WebCore