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.javascript.polyfill;
16  
17  import java.io.IOException;
18  import java.nio.charset.StandardCharsets;
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import org.apache.commons.io.IOUtils;
23  import org.htmlunit.corejs.javascript.Context;
24  import org.htmlunit.corejs.javascript.Script;
25  import org.htmlunit.corejs.javascript.Scriptable;
26  
27  /**
28   * Support to use polyfills for js features not implemented so far
29   * (idea from Colin Alworth).
30   *
31   * @author Ronald Brill
32   */
33  public class Polyfill {
34  
35      private static final Map<String, Polyfill> CACHE = new HashMap<>();
36  
37      private String url_;
38      private String source_;
39      private Script script_;
40  
41      /**
42       * @return the build in fetch polyfill
43       * @throws IOException in case of error
44       */
45      public static Polyfill getFetchPolyfill() throws IOException {
46          return getPolyfill("fetch/fetch.umd.js");
47      }
48  
49      private static Polyfill getPolyfill(final String resouceName) throws IOException {
50          Polyfill poly = CACHE.get(resouceName);
51          if (poly != null) {
52              return poly;
53          }
54  
55          poly = new Polyfill();
56          poly.source_ = IOUtils.toString(poly.getClass().getResourceAsStream(resouceName), StandardCharsets.UTF_8);
57          poly.url_ = poly.getClass().getResource(resouceName).toExternalForm();
58  
59          CACHE.put(resouceName, poly);
60          return poly;
61      }
62  
63      /**
64       * Compile the script if needed and exec to setup the context.
65       *
66       * @param context the context
67       * @param scriptable the scriptable
68       */
69      public void apply(final Context context, final Scriptable scriptable) {
70          if (script_ == null) {
71              script_ = context.compileString(source_, url_, 0, null);
72          }
73  
74          if (script_ != null) {
75              script_.exec(context, scriptable);
76          }
77      }
78  }