View Javadoc
1   /*
2    * Copyright (c) 2002-2025 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.html;
16  
17  import org.htmlunit.Page;
18  import org.htmlunit.StringWebResponse;
19  import org.htmlunit.WebResponse;
20  import org.htmlunit.WebWindow;
21  import org.htmlunit.WebWindowImpl;
22  
23  /**
24   * The web window for a frame or iframe.
25   *
26   * @author Brad Clarke
27   * @author Ahmed Ashour
28   * @author Ronald Brill
29   */
30  public class FrameWindow extends WebWindowImpl {
31  
32      /** The different deny states. */
33      public enum PageDenied {
34          /** NONE. */
35          NONE,
36  
37          /** BY_X_FRAME_OPTIONS. */
38          BY_X_FRAME_OPTIONS,
39  
40          /** BY_CONTENT_SECURIRY_POLICY. */
41          BY_CONTENT_SECURIRY_POLICY }
42  
43      private final BaseFrameElement frame_;
44      private PageDenied pageDenied_;
45  
46      /**
47       * Creates an instance for a given frame.
48       */
49      FrameWindow(final BaseFrameElement frame) {
50          super(frame.getPage().getWebClient());
51          frame_ = frame;
52          performRegistration();
53  
54          final WebWindowImpl parent = (WebWindowImpl) frame_.getPage().getEnclosingWindow();
55          parent.addChildWindow(this);
56      }
57  
58      /**
59       * {@inheritDoc}
60       * A FrameWindow shares it's name with it's containing frame.
61       */
62      @Override
63      public String getName() {
64          return frame_.getNameAttribute();
65      }
66  
67      /**
68       * {@inheritDoc}
69       * A FrameWindow shares it's name with it's containing frame.
70       */
71      @Override
72      public void setName(final String name) {
73          frame_.setNameAttribute(name);
74      }
75  
76      /**
77       * {@inheritDoc}
78       */
79      @Override
80      public WebWindow getParentWindow() {
81          return frame_.getPage().getEnclosingWindow();
82      }
83  
84      /**
85       * {@inheritDoc}
86       */
87      @Override
88      public WebWindow getTopWindow() {
89          return getParentWindow().getTopWindow();
90      }
91  
92      /**
93       * {@inheritDoc}
94       */
95      @Override
96      protected boolean isJavaScriptInitializationNeeded(final Page page) {
97          return getScriptableObject() == null
98              || !(page.getWebResponse() instanceof StringWebResponse
99                      && ((StringWebResponse) page.getWebResponse()).isFromJavascript());
100         // TODO: find a better way to distinguish content written by document.open(),...
101     }
102 
103     /**
104      * Returns the HTML page in which the <frame> or <iframe> tag is contained
105      * for this frame window.
106      * This is a facility method for <code>(HtmlPage) (getParentWindow().getEnclosedPage())</code>.
107      * @return the page in the parent window
108      */
109     public HtmlPage getEnclosingPage() {
110         return (HtmlPage) frame_.getPage();
111     }
112 
113     /**
114      * {@inheritDoc}
115      */
116     @Override
117     public void setEnclosedPage(final Page page) {
118         setPageDenied(PageDenied.NONE);
119         super.setEnclosedPage(page);
120 
121         // we have updated a frame window by javascript write();
122         // so we have to disable future updates during initialization
123         // see org.htmlunit.html.HtmlPage.loadFrames()
124         final WebResponse webResponse = page.getWebResponse();
125         if (webResponse instanceof StringWebResponse) {
126             final StringWebResponse response = (StringWebResponse) webResponse;
127             if (response.isFromJavascript()) {
128                 final BaseFrameElement frame = getFrameElement();
129                 frame.setContentLoaded();
130             }
131         }
132     }
133 
134     /**
135      * Gets the DOM node of the (i)frame containing this window.
136      * @return the DOM node
137      */
138     public BaseFrameElement getFrameElement() {
139         return frame_;
140     }
141 
142     /**
143      * Gives a basic representation for debugging purposes.
144      * @return a basic representation
145      */
146     @Override
147     public String toString() {
148         return "FrameWindow[name=\"" + getName() + "\"]";
149     }
150 
151     /**
152      * Closes this frame window.
153      */
154     public void close() {
155         final WebWindowImpl parent = (WebWindowImpl) getParentWindow();
156         parent.removeChildWindow(this);
157         getWebClient().deregisterWebWindow(this);
158     }
159 
160     /**
161      * Marks that the page content as denied.
162      * @param pageDenied the new state
163      */
164     public void setPageDenied(final PageDenied pageDenied) {
165         pageDenied_ = pageDenied;
166     }
167 
168     /**
169      * @return PageDenied if the page was denied
170      */
171     public PageDenied getPageDenied() {
172         return pageDenied_;
173     }
174 }