/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2013, MPL CodeInside http://codeinside.ru */ package ru.codeinside.gses.vaadin.client; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.ButtonElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.IFrameElement; import com.google.gwt.dom.client.InputElement; import com.google.gwt.dom.client.NodeList; import com.google.gwt.dom.client.SelectElement; import com.google.gwt.dom.client.TextAreaElement; import com.google.gwt.event.dom.client.DomEvent.Type; import com.google.gwt.event.dom.client.LoadEvent; import com.google.gwt.event.dom.client.LoadHandler; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Frame; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.RootPanel; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.ui.ClickEventHandler; public class VJsonFormIntegration extends HTML implements Paintable { public static final String CLICK_EVENT_IDENTIFIER = "click"; private static String CLASSNAME = "v-embedded"; private Element browserElement; private Frame frame; private String src = "about:blank"; private boolean fixRequired; private boolean validationMode; private ApplicationConnection client; private final ClickEventHandler clickEventHandler = new ClickEventHandler(this, CLICK_EVENT_IDENTIFIER) { @Override protected <H extends EventHandler> HandlerRegistration registerHandler(H handler, Type<H> type) { return addDomHandler(handler, type); } }; public VJsonFormIntegration() { setStyleName(CLASSNAME); setHTML("Загрузка..."); } public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { if (client.updateComponent(this, uidl, true)) { return; } this.client = client; clickEventHandler.handleEventHandlerRegistration(client); if (uidl.hasAttribute("src")) { if (browserElement == null) { addStyleName(CLASSNAME + "-browser"); setHTML("<iframe width=\"100%\" height=\"100%\" frameborder=\"0\"" + " allowTransparency=\"true\" src=\"\"" + " name=\"" + uidl.getId() + "\"></iframe>"); browserElement = DOM.getFirstChild(getElement()); } String newSrc = getSrc(uidl, client); if (!newSrc.equals(src)) { if (uidl.hasAttribute("fixArchiveSupport")) { fixRequired = true; frame = createFrameWrap(); } src = newSrc; DOM.setElementAttribute(browserElement, "src", src); } } if (uidl.hasAttribute("validationMode")) { validationMode = uidl.getBooleanAttribute("validationMode"); } if (uidl.hasAttribute("go")) { Scheduler.get().scheduleDeferred(new JsonValueGetter(uidl.getId())); } } /** * Helper to return translated src-attribute from embedded's UIDL * * @param uidl * @param client * @return */ private String getSrc(UIDL uidl, ApplicationConnection client) { String url = client.translateVaadinUri(uidl.getStringAttribute("src")); if (url == null) { return ""; } return url; } @Override protected void onDetach() { if (frame != null) { RootPanel.detachNow(frame); } if (browserElement != null) { browserElement.setAttribute("src", "about:blank"); } super.onDetach(); } @Override protected void onAttach() { super.onAttach(); if (fixRequired) { frame = createFrameWrap(); } if (browserElement != null && src != null && !src.equals(browserElement.getAttribute("src"))) { browserElement.setAttribute("src", src); } } @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); if (DOM.eventGetType(event) == Event.ONLOAD) { Util.notifyParentOfSizeChange(this, true); } client.handleTooltipEvent(event, this); } final class JsonValueGetter implements Command { private final String id; public JsonValueGetter(String id) { this.id = id; } public void execute() { try { String value = validationMode ? isFormPosted(browserElement) : getJsonValue(browserElement); client.updateVariable(id, "jsonValue", value, true); } catch (Exception e) { client.updateVariable(id, "jsonError", e.getMessage(), true); } } native String getJsonValue(Element element) /*-{ var json = element.contentWindow.getOepJsonString(); return json == null ? "" : ("" + json); }-*/; native String isFormPosted(Element element) /*-{ var json = element.contentWindow.isFormPosted(); return json == null ? "" : ("" + json); }-*/; } private Frame createFrameWrap() { if (browserElement == null) { return null; } Frame frameWrap = Frame.wrap(browserElement); frameWrap.addLoadHandler(new LoadHandler() { @Override public void onLoad(LoadEvent event) { Scheduler.get().scheduleFixedDelay(new Scheduler.RepeatingCommand() { @Override public boolean execute() { IFrameElement formFrame = IFrameElement.as(browserElement); Document formDoc = formFrame.getContentDocument(); if (formDoc == null) { return true; } NodeList<com.google.gwt.dom.client.Element> elements; elements = formDoc.getElementsByTagName("input"); for (int i = 0; i < elements.getLength(); i++) { InputElement input = InputElement.as(elements.getItem(i)); if ("button".equalsIgnoreCase(input.getType())) { input.setDisabled(true); } else { input.setReadOnly(true); } } elements = formDoc.getElementsByTagName("button"); for (int i = 0; i < elements.getLength(); i++) { ButtonElement button = ButtonElement.as(elements.getItem(i)); button.setDisabled(true); } elements = formDoc.getElementsByTagName("select"); for (int i = 0; i < elements.getLength(); i++) { SelectElement select = SelectElement.as(elements.getItem(i)); select.setDisabled(true); } elements = formDoc.getElementsByTagName("textarea"); for (int i = 0; i < elements.getLength(); i++) { TextAreaElement textArea = TextAreaElement.as(elements.getItem(i)); textArea.setReadOnly(true); } return false; } }, 99); } }); return frameWrap; } }