All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.uibinder.elementparsers.WidgetPlaceholderInterpreter Maven / Gradle / Ivy

/*
 * Copyright 2008 Google Inc.
 *
 * 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.google.gwt.uibinder.elementparsers;

import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.uibinder.client.LazyDomElement;
import com.google.gwt.uibinder.rebind.FieldManager;
import com.google.gwt.uibinder.rebind.FieldWriter;
import com.google.gwt.uibinder.rebind.UiBinderWriter;
import com.google.gwt.uibinder.rebind.XMLElement;
import com.google.gwt.uibinder.rebind.messages.MessageWriter;
import com.google.gwt.uibinder.rebind.messages.MessagesWriter;
import com.google.gwt.user.client.ui.HasHTML;
import com.google.gwt.user.client.ui.HasText;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Used by {@link HTMLPanelParser}. Refines {@link HtmlPlaceholderInterpreter}
 * to allow widgets to appear inside msg elements in an HTMLPanel.
 * 

* HasText and HasHTML get special treatment, where their innerText or innerHTML * become part of the {@literal @}Default value of the message being generated. * E.g., this markup in an HTMLPanel: * *

 * Hello <gwt:HyperLink>click here</gwt:HyperLink> thank you.
* * becomes a message like this:
 * {@literal @}Default("Hello {0}click here{1} thank you.")
 * String getMessage1(
 *   {@literal @}Example("<span>") String widget1Begin,
 *   {@literal @}Example("</span>") String widget1End
 * );
* *

* The contents of other widget types are opaque to the message, and are covered * by a single placeholder. One implication of this is that the content of an * HTMLPanel inside a msg in another HTMLPanel must always be in a separate * message. */ class WidgetPlaceholderInterpreter extends HtmlPlaceholderInterpreter { /* * Could break this up into three further classes, for HasText, HasHTML and * Other, but that seems more trouble than it's worth. */ private final FieldManager fieldManager; private int serial = 0; private final String ancestorExpression; private final String fieldName; private final Map idToWidgetElement = new HashMap(); private final Set idIsHasHTML = new HashSet(); private final Set idIsHasText = new HashSet(); WidgetPlaceholderInterpreter(String fieldName, UiBinderWriter writer, MessageWriter message, String ancestorExpression) { super(writer, message, ancestorExpression); this.fieldName = fieldName; this.ancestorExpression = ancestorExpression; this.fieldManager = uiWriter.getFieldManager(); } @Override public String interpretElement(XMLElement elem) throws UnableToCompleteException { if (!uiWriter.isWidgetElement(elem)) { return super.interpretElement(elem); } JClassType type = uiWriter.findFieldType(elem); TypeOracle oracle = uiWriter.getOracle(); MessagesWriter mw = uiWriter.getMessages(); String name = mw.consumeMessageAttribute("ph", elem); if ("".equals(name)) { name = "widget" + (++serial); } String idHolder = uiWriter.declareDomIdHolder(null); idToWidgetElement.put(idHolder, elem); if (oracle.findType(HasHTML.class.getName()).isAssignableFrom(type)) { return handleHasHTMLPlaceholder(elem, name, idHolder); } if (oracle.findType(HasText.class.getName()).isAssignableFrom(type)) { return handleHasTextPlaceholder(elem, name, idHolder); } return handleOpaqueWidgetPlaceholder(elem, name, idHolder); } /** * Called by {@link XMLElement#consumeInnerHtml} after all elements * have been handed to {@link #interpretElement}. */ @Override public String postProcess(String consumed) throws UnableToCompleteException { FieldWriter fieldWriter = fieldManager.require(fieldName); for (String idHolder : idToWidgetElement.keySet()) { XMLElement childElem = idToWidgetElement.get(idHolder); FieldWriter childFieldWriter = uiWriter.parseElementToField(childElem); genSetWidgetTextCall(idHolder, childFieldWriter.getName()); if (uiWriter.useLazyWidgetBuilders()) { // Register a DOM id field. String lazyDomElementPath = LazyDomElement.class.getCanonicalName(); String elementPointer = idHolder + "Element"; FieldWriter elementWriter = fieldManager.registerField( lazyDomElementPath, elementPointer); elementWriter.setInitializer(String.format("new %s(%s)", lazyDomElementPath, fieldManager.convertFieldToGetter(idHolder))); // Add attach/detach sections for this element. fieldWriter.addAttachStatement("%s.get();", fieldManager.convertFieldToGetter(elementPointer)); fieldWriter.addDetachStatement( "%s.addAndReplaceElement(%s, %s.get());", fieldName, fieldManager.convertFieldToGetter(childFieldWriter.getName()), fieldManager.convertFieldToGetter(elementPointer)); } else { uiWriter.addInitStatement( "%1$s.addAndReplaceElement(%2$s, %3$s);", fieldName, childFieldWriter.getName(), idHolder); } } /* * We get used recursively, so this will be called again. Empty the map * or else we'll re-register things. */ idToWidgetElement.clear(); return super.postProcess(consumed); } private String genCloseTag(String name) { String closePlaceholder = nextClosePlaceholder(name + "End", ""); return closePlaceholder; } private String genOpenTag(XMLElement source, String name, String idHolder) { idHolder = fieldManager.convertFieldToGetter(idHolder); if (uiWriter.useSafeHtmlTemplates()) { idHolder = uiWriter.tokenForStringExpression(source, idHolder); } else { idHolder = "\" + " + idHolder + " + \""; } String openTag = String.format("", idHolder); String openPlaceholder = nextOpenPlaceholder(name + "Begin", openTag); return openPlaceholder; } private void genSetWidgetTextCall(String idHolder, String childField) { if (uiWriter.useLazyWidgetBuilders()) { if (idIsHasText.contains(idHolder)) { fieldManager.require(fieldName).addAttachStatement( "%s.setText(%s.getElementById(%s).getInnerText());", fieldManager.convertFieldToGetter(childField), fieldName, fieldManager.convertFieldToGetter(idHolder)); } else if (idIsHasHTML.contains(idHolder)) { fieldManager.require(fieldName).addAttachStatement( "%s.setHTML(%s.getElementById(%s).getInnerHTML());", fieldManager.convertFieldToGetter(childField), fieldName, fieldManager.convertFieldToGetter(idHolder)); } } else { if (idIsHasText.contains(idHolder)) { uiWriter.addInitStatement( "%s.setText(%s.getElementById(%s).getInnerText());", childField, fieldName, idHolder); } if (idIsHasHTML.contains(idHolder)) { uiWriter.addInitStatement( "%s.setHTML(%s.getElementById(%s).getInnerHTML());", childField, fieldName, idHolder); } } } private String handleHasHTMLPlaceholder(XMLElement elem, String name, String idHolder) throws UnableToCompleteException { idIsHasHTML.add(idHolder); String openPlaceholder = genOpenTag(elem, name, idHolder); String body = elem.consumeInnerHtml(new HtmlPlaceholderInterpreter(uiWriter, message, ancestorExpression)); String bodyToken = tokenator.nextToken(body); String closePlaceholder = genCloseTag(name); return openPlaceholder + bodyToken + closePlaceholder; } private String handleHasTextPlaceholder(XMLElement elem, String name, String idHolder) throws UnableToCompleteException { idIsHasText.add(idHolder); String openPlaceholder = genOpenTag(elem, name, idHolder); String body = elem.consumeInnerText(new TextPlaceholderInterpreter(uiWriter, message)); String bodyToken = tokenator.nextToken(body); String closePlaceholder = genCloseTag(name); return openPlaceholder + bodyToken + closePlaceholder; } private String handleOpaqueWidgetPlaceholder(XMLElement source, String name, String idHolder) { idHolder = fieldManager.convertFieldToGetter(idHolder); if (uiWriter.useSafeHtmlTemplates()) { idHolder = uiWriter.tokenForStringExpression(source, idHolder); } else { idHolder = "\" + " + idHolder + " + \""; } String tag = String.format("", idHolder); String placeholder = nextPlaceholder(name, "", tag); return placeholder; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy