View Javadoc
1   /*
2    * Copyright (c) 2002-2017 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    * http://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 com.gargoylesoftware.htmlunit.javascript.host.html;
16  
17  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CANVAS_DATA_URL_CHROME_PNG;
18  import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CANVAS_DATA_URL_IE_PNG;
19  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
20  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
21  import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
22  
23  import com.gargoylesoftware.htmlunit.html.HtmlCanvas;
24  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
25  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
26  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
27  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
28  import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter;
29  import com.gargoylesoftware.htmlunit.javascript.host.canvas.CanvasRenderingContext2D;
30  
31  import net.sourceforge.htmlunit.corejs.javascript.Undefined;
32  
33  /**
34   * The JavaScript object {@code HTMLCanvasElement}.
35   *
36   * @author Ahmed Ashour
37   * @author Ronald Brill
38   * @author Frank Danek
39   */
40  @JsxClass(domClass = HtmlCanvas.class)
41  public class HTMLCanvasElement extends HTMLElement {
42  
43      private Object context_;
44  
45      /**
46       * Creates an instance.
47       */
48      @JsxConstructor({CHROME, FF, EDGE})
49      public HTMLCanvasElement() {
50      }
51  
52      /**
53       * Returns the {@code width} property.
54       * @return the {@code width} property
55       */
56      @Override
57      @JsxGetter
58      public int getWidth() {
59          final String value = getDomNodeOrDie().getAttribute("width");
60          final Integer intValue = getValue(value);
61          if (intValue != null) {
62              return intValue;
63          }
64          return 300;
65      }
66  
67      static Integer getValue(final String value) {
68          int index = -1;
69          while (index + 1 < value.length() && Character.isDigit(value.charAt(index + 1))) {
70              index++;
71          }
72          if (index != -1) {
73              return Integer.parseInt(value.substring(0, index + 1));
74          }
75          return null;
76      }
77  
78      /**
79       * Sets the {@code width} property.
80       * @param width the {@code width} property
81       */
82      @JsxSetter
83      public void setWidth(final int width) {
84          getDomNodeOrDie().setAttribute("width", Integer.toString(width));
85      }
86  
87      /**
88       * Returns the {@code height} property.
89       * @return the {@code height} property
90       */
91      @Override
92      @JsxGetter
93      public int getHeight() {
94          final String value = getDomNodeOrDie().getAttribute("height");
95          final Integer intValue = getValue(value);
96          if (intValue != null) {
97              return intValue;
98          }
99          return 150;
100     }
101 
102     /**
103      * Sets the {@code height} property.
104      * @param height the {@code height} property
105      */
106     @JsxSetter
107     public void setHeight(final int height) {
108         getDomNodeOrDie().setAttribute("height", Integer.toString(height));
109     }
110 
111     /**
112      * Gets the context.
113      * @param contextId the context id
114      * @return Returns an object that exposes an API for drawing on the canvas,
115      * or null if the given context ID is not supported
116      */
117     @JsxFunction
118     public Object getContext(final String contextId) {
119         if ("2d".equals(contextId)) {
120             final CanvasRenderingContext2D context = new CanvasRenderingContext2D(this);
121             context.setParentScope(getParentScope());
122             context.setPrototype(getPrototype(context.getClass()));
123             context_ = context;
124             return context;
125         }
126         return null;
127     }
128 
129     /**
130      * Get the data: URL representation of the Canvas element.
131      * Here we return an empty image.
132      * @param type the type (optional)
133      * @return the data URL
134      */
135     @JsxFunction
136     public String toDataURL(final Object type) {
137         if (context_ instanceof CanvasRenderingContext2D) {
138             String typeInUse = type.toString();
139             if (type == Undefined.instance) {
140                 typeInUse = null;
141             }
142             return ((CanvasRenderingContext2D) context_).toDataURL(typeInUse);
143         }
144         if (getBrowserVersion().hasFeature(JS_CANVAS_DATA_URL_IE_PNG)) {
145             return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAARnQU1BAA"
146                 + "Cxjwv8YQUAAADGSURBVHhe7cExAQAAAMKg9U9tCF8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
147                 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
148                 + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAONUAv9QAAcDhjokAAAAASUV"
149                 + "ORK5CYII=";
150         }
151 
152         if (getBrowserVersion().hasFeature(JS_CANVAS_DATA_URL_CHROME_PNG)) {
153             return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAEYklEQVR4Xu3UAQkAAAwCwdm/"
154                 + "9HI83BLIOdw5AgQIRAQWySkmAQIEzmB5AgIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYO"
155                 + "VqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1"
156                 + "OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamK"
157                 + "kEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWC"
158                 + "EiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCV"
159                 + "AwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgI"
160                 + "DB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg"
161                 + "+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbL"
162                 + "DxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8"
163                 + "gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QI"
164                 + "BARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAg"
165                 + "YyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZ"
166                 + "AYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDFamKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgI"
167                 + "GK1OVoAQIGCw/QIBARsBgZaoSlAABg+UHCBDICBisTFWCEiBgsPwAAQIZAYOVqUpQAgQMlh8gQCAjYLAyVQlKgIDB8gMECGQEDF"
168                 + "amKkEJEDBYfoAAgYyAwcpUJSgBAgbLDxAgkBEwWJmqBCVAwGD5AQIEMgIGK1OVoAQIGCw/QIBARsBgZaoSlACBB1YxAJfjJb2jA"
169                 + "AAAAElFTkSuQmCC";
170         }
171 
172         return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAxUlEQVR4nO3BMQEAAADCoPVPbQhf"
173             + "oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
174             + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
175             + "AAAAAAAAAAAAAAAAAAAAAAAAAAAOA1v9QAATX68/0AAAAASUVORK5CYII=";
176     }
177 }