/* * Copyright 2000-2016 Vaadin Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.vaadin.client.ui; import java.util.HashMap; import java.util.Map; import com.google.gwt.user.client.ui.HTML; import com.vaadin.client.WidgetUtil; public class VFlash extends HTML { public static final String CLASSNAME = "v-flash"; protected String source; protected String altText; protected String classId; protected String codebase; protected String codetype; protected String standby; protected String archive; protected Map<String, String> embedParams = new HashMap<>(); protected boolean needsRebuild = false; protected String width; protected String height; private int slotOffsetHeight = -1; private int slotOffsetWidth = -1; public VFlash() { setStyleName(CLASSNAME); } public void setSource(String source) { if (this.source != source) { this.source = source; needsRebuild = true; } } public void setAlternateText(String altText) { if (this.altText != altText) { this.altText = altText; needsRebuild = true; } } public void setClassId(String classId) { if (this.classId != classId) { this.classId = classId; needsRebuild = true; } } public void setCodebase(String codebase) { if (this.codebase != codebase) { this.codebase = codebase; needsRebuild = true; } } public void setCodetype(String codetype) { if (this.codetype != codetype) { this.codetype = codetype; needsRebuild = true; } } public void setStandby(String standby) { if (this.standby != standby) { this.standby = standby; needsRebuild = true; } } public void setArchive(String archive) { if (this.archive != archive) { this.archive = archive; needsRebuild = true; } } /** * Call this after changing values of widget. It will rebuild embedding * structure if needed. */ public void rebuildIfNeeded() { if (needsRebuild) { needsRebuild = false; this.setHTML(createFlashEmbed()); } } @Override public void setWidth(String width) { // explicitly not calling super here if (this.width != width) { this.width = width; needsRebuild = true; } } @Override public void setHeight(String height) { // explicitly not calling super here if (this.height != height) { this.height = height; needsRebuild = true; } } public void setEmbedParams(Map<String, String> params) { if (params == null) { if (!embedParams.isEmpty()) { embedParams.clear(); needsRebuild = true; } return; } if (!embedParams.equals(params)) { embedParams = new HashMap<>(params); needsRebuild = true; } } /** * Set dimensions of the containing layout slot so that the size of the * embed object can be calculated from percentages if needed. * * Triggers embed resizing if percentage sizes are in use. * * @since 7.7.8 * @param slotOffsetHeight * offset height of the layout slot * @param slotOffsetWidth * offset width of the layout slot */ public void setSlotHeightAndWidth(int slotOffsetHeight, int slotOffsetWidth) { this.slotOffsetHeight = slotOffsetHeight; this.slotOffsetWidth = slotOffsetWidth; if (hasPercentageHeight() || hasPercentageWidth()) { resizeEmbedElement(); } } protected String createFlashEmbed() { /* * To ensure cross-browser compatibility we are using the twice-cooked * method to embed flash i.e. we add a OBJECT tag for IE ActiveX and * inside it a EMBED for all other browsers. */ StringBuilder html = new StringBuilder(); // Start the object tag html.append("<object "); /* * Add classid required for ActiveX to recognize the flash. This is a * predefined value which ActiveX recognizes and must be the given * value. More info can be found on * http://kb2.adobe.com/cps/415/tn_4150.html. Allow user to override * this by setting his own classid. */ if (classId != null) { html.append( "classid=\"" + WidgetUtil.escapeAttribute(classId) + "\" "); } else { html.append( "classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" "); } /* * Add codebase required for ActiveX and must be exactly this according * to http://kb2.adobe.com/cps/415/tn_4150.html to work with the above * given classid. Again, see more info on * http://kb2.adobe.com/cps/415/tn_4150.html. Limiting Flash version to * 6.0.0.0 and above. Allow user to override this by setting his own * codebase */ if (codebase != null) { html.append("codebase=\"" + WidgetUtil.escapeAttribute(codebase) + "\" "); } else { html.append( "codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0\" "); } // Add width and height html.append("width=\"" + WidgetUtil.escapeAttribute(width) + "\" "); html.append("height=\"" + WidgetUtil.escapeAttribute(height) + "\" "); html.append("type=\"application/x-shockwave-flash\" "); // Codetype if (codetype != null) { html.append("codetype=\"" + WidgetUtil.escapeAttribute(codetype) + "\" "); } // Standby if (standby != null) { html.append( "standby=\"" + WidgetUtil.escapeAttribute(standby) + "\" "); } // Archive if (archive != null) { html.append( "archive=\"" + WidgetUtil.escapeAttribute(archive) + "\" "); } // End object tag html.append(">"); // Ensure we have an movie parameter if (embedParams.get("movie") == null) { embedParams.put("movie", source); } // Add parameters to OBJECT for (String name : embedParams.keySet()) { html.append("<param "); html.append("name=\"" + WidgetUtil.escapeAttribute(name) + "\" "); html.append("value=\"" + WidgetUtil.escapeAttribute(embedParams.get(name)) + "\" "); html.append("/>"); } // Build inner EMBED tag html.append("<embed "); html.append("src=\"" + WidgetUtil.escapeAttribute(source) + "\" "); if (hasPercentageWidth() && slotOffsetWidth >= 0) { html.append("width=\"" + getRelativePixelWidth() + "\" "); } else { html.append("width=\"" + WidgetUtil.escapeAttribute(width) + "\" "); } if (hasPercentageHeight() && slotOffsetHeight >= 0) { html.append("height=\"" + getRelativePixelHeight() + "px\" "); } else { html.append( "height=\"" + WidgetUtil.escapeAttribute(height) + "\" "); } html.append("type=\"application/x-shockwave-flash\" "); // Add the parameters to the Embed for (String name : embedParams.keySet()) { html.append(WidgetUtil.escapeAttribute(name)); html.append("="); html.append("\"" + WidgetUtil.escapeAttribute(embedParams.get(name)) + "\""); } // End embed tag html.append("></embed>"); if (altText != null) { html.append("<noembed>"); html.append(altText); html.append("</noembed>"); } // End object tag html.append("</object>"); return html.toString(); } private void resizeEmbedElement() { // find <embed> element com.google.gwt.dom.client.Element objectElem = getElement() .getFirstChildElement(); com.google.gwt.dom.client.Element objectChild = objectElem .getFirstChildElement(); while (!"EMBED".equalsIgnoreCase(objectChild.getTagName())) { objectChild = objectChild.getNextSiblingElement(); if (objectChild == null) { return; } } // update height & width from slot offset, if percentage size is given if (hasPercentageHeight() && slotOffsetHeight >= 0) { objectChild.setAttribute("height", getRelativePixelHeight()); } if (hasPercentageWidth() && slotOffsetWidth >= 0) { objectChild.setAttribute("width", getRelativePixelWidth()); } } private String getRelativePixelWidth() { float relative = WidgetUtil.parseRelativeSize(width); int widthInPixels = (int) (relative / 100) * slotOffsetWidth; return widthInPixels + "px"; } private String getRelativePixelHeight() { float relative = WidgetUtil.parseRelativeSize(height); int heightInPixels = (int) (relative / 100) * slotOffsetHeight; return heightInPixels + "px"; } private boolean hasPercentageHeight() { return ((height != null) && (height.indexOf('%') > 0)); } private boolean hasPercentageWidth() { return ((width != null) && (width.indexOf('%') > 0)); } }