1 /*
2 * Copyright (c) 2002-2026 Gargoyle Software Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 * https://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.htmlunit.javascript.host.html;
16
17 import static org.htmlunit.BrowserVersionFeatures.JS_IFRAME_ALWAYS_EXECUTE_ONLOAD;
18
19 import org.htmlunit.html.BaseFrameElement;
20 import org.htmlunit.html.FrameWindow;
21 import org.htmlunit.html.FrameWindow.PageDenied;
22 import org.htmlunit.html.HtmlInlineFrame;
23 import org.htmlunit.javascript.configuration.JsxClass;
24 import org.htmlunit.javascript.configuration.JsxConstructor;
25 import org.htmlunit.javascript.configuration.JsxGetter;
26 import org.htmlunit.javascript.configuration.JsxSetter;
27 import org.htmlunit.javascript.host.Window;
28 import org.htmlunit.javascript.host.WindowProxy;
29 import org.htmlunit.javascript.host.event.Event;
30
31 /**
32 * A JavaScript object for {@link HtmlInlineFrame}.
33 *
34 * @author Marc Guillemot
35 * @author Chris Erskine
36 * @author Ahmed Ashour
37 * @author Ronald Brill
38 *
39 * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement">MDN Documentation</a>
40 */
41 @JsxClass(domClass = HtmlInlineFrame.class)
42 public class HTMLIFrameElement extends HTMLElement {
43
44 /** During {@link #setOnload(Object)}, was the element attached to the page. */
45 private boolean isAttachedToPageDuringOnload_;
46
47 /**
48 * JavaScript constructor.
49 */
50 @Override
51 @JsxConstructor
52 public void jsConstructor() {
53 super.jsConstructor();
54 }
55
56 /**
57 * Returns the value of the URL loaded in the frame.
58 * @return the value of this attribute
59 */
60 @JsxGetter
61 public String getSrc() {
62 return getFrame().getSrcAttribute();
63 }
64
65 /**
66 * Sets the value of the source of the contained frame.
67 * @param src the new value
68 */
69 @JsxSetter
70 public void setSrc(final String src) {
71 getFrame().setSrcAttribute(src);
72 isAttachedToPageDuringOnload_ = false;
73 }
74
75 /**
76 * Returns the document the frame contains, if any.
77 * @return {@code null} if no document is contained
78 * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_frame_ref4.html">Gecko DOM Reference</a>
79 */
80 @JsxGetter
81 public DocumentProxy getContentDocument() {
82 final FrameWindow frameWindow = getFrame().getEnclosedWindow();
83 if (PageDenied.NONE != frameWindow.getPageDenied()) {
84 return null;
85 }
86 return ((Window) frameWindow.getScriptableObject()).getDocument_js();
87 }
88
89 /**
90 * Returns the window the frame contains, if any.
91 * @return the window
92 * @see <a href="http://www.mozilla.org/docs/dom/domref/dom_frame_ref5.html">Gecko DOM Reference</a>
93 * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/contentWindow">MDN Documentation</a>
94 */
95 @JsxGetter
96 public WindowProxy getContentWindow() {
97 final FrameWindow frameWin = getFrame().getEnclosedWindow();
98 if (frameWin.isClosed()) {
99 return null;
100 }
101 return Window.getProxy(frameWin);
102 }
103
104 /**
105 * Returns the value of the name attribute.
106 * @return the value of this attribute
107 */
108 @JsxGetter
109 @Override
110 public String getName() {
111 return getFrame().getNameAttribute();
112 }
113
114 /**
115 * Sets the value of the name attribute.
116 * @param name the new value
117 */
118 @JsxSetter
119 @Override
120 public void setName(final String name) {
121 getFrame().setNameAttribute(name);
122 }
123
124 private BaseFrameElement getFrame() {
125 return (BaseFrameElement) getDomNodeOrDie();
126 }
127
128 /**
129 * {@inheritDoc}
130 */
131 @Override
132 public void setOnload(final Object eventHandler) {
133 super.setOnload(eventHandler);
134 isAttachedToPageDuringOnload_ = getDomNodeOrDie().isAttachedToPage();
135 }
136
137 /**
138 * Returns the value of the {@code align} property.
139 * @return the value of the {@code align} property
140 */
141 @JsxGetter
142 public String getAlign() {
143 return getAlign(true);
144 }
145
146 /**
147 * Sets the value of the {@code align} property.
148 * @param align the value of the {@code align} property
149 */
150 @JsxSetter
151 public void setAlign(final String align) {
152 setAlign(align, false);
153 }
154
155 /**
156 * Returns the value of the {@code width} property.
157 * @return the value of the {@code width} property
158 */
159 @JsxGetter(propertyName = "width")
160 public String getWidth_js() {
161 return getWidthOrHeight("width", Boolean.TRUE);
162 }
163
164 /**
165 * Sets the value of the {@code width} property.
166 * @param width the value of the {@code width} property
167 */
168 @JsxSetter(propertyName = "width")
169 public void setWidth_js(final String width) {
170 setWidthOrHeight("width", width, true);
171 }
172
173 /**
174 * Returns the value of the {@code height} property.
175 * @return the value of the {@code height} property
176 */
177 @JsxGetter(propertyName = "height")
178 public String getHeight_js() {
179 return getWidthOrHeight("height", Boolean.TRUE);
180 }
181
182 /**
183 * Sets the value of the {@code height} property.
184 * @param height the value of the {@code height} property
185 */
186 @JsxSetter(propertyName = "height")
187 public void setHeight_js(final String height) {
188 setWidthOrHeight("height", height, true);
189 }
190
191 /**
192 * {@inheritDoc}
193 */
194 @Override
195 public void executeEventLocally(final Event event) {
196 if (Event.TYPE_LOAD != event.getType()
197 || !isAttachedToPageDuringOnload_ || getBrowserVersion().hasFeature(JS_IFRAME_ALWAYS_EXECUTE_ONLOAD)) {
198 super.executeEventLocally(event);
199 }
200 }
201
202 /**
203 * To be called when the frame is being refreshed.
204 */
205 public void onRefresh() {
206 isAttachedToPageDuringOnload_ = false;
207 }
208 }