/* * 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.uibinder.rebind.FieldManager; import com.google.gwt.uibinder.rebind.FieldWriter; import com.google.gwt.uibinder.client.LazyDomElement; import com.google.gwt.uibinder.rebind.UiBinderWriter; import com.google.gwt.uibinder.rebind.XMLElement; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * Used by {@link HTMLPanelParser} to interpret elements that call for widget * instances. Declares the appropriate widget, and replaces them in the markup * with a <span>. */ class WidgetInterpreter implements XMLElement.Interpreter<String> { private static final Map<String, String> LEGAL_CHILD_ELEMENTS; private static final String DEFAULT_CHILD_ELEMENT = "span"; static { // Other cases? HashMap<String, String> map = new HashMap<String, String>(); map.put("table", "tbody"); map.put("thead", "tr"); map.put("tbody", "tr"); map.put("tfoot", "tr"); map.put("ul", "li"); map.put("ol", "li"); map.put("dl", "dt"); LEGAL_CHILD_ELEMENTS = Collections.unmodifiableMap(map); } private static String getLegalPlaceholderTag(XMLElement elem) { XMLElement parent = elem.getParent(); String tag = null; if (parent != null) { tag = LEGAL_CHILD_ELEMENTS.get(parent.getLocalName()); } if (tag == null) { tag = DEFAULT_CHILD_ELEMENT; } return tag; } private final String fieldName; private final UiBinderWriter uiWriter; public WidgetInterpreter(String fieldName, UiBinderWriter writer) { this.fieldName = fieldName; this.uiWriter = writer; } public String interpretElement(XMLElement elem) throws UnableToCompleteException { if (!uiWriter.isWidgetElement(elem)) { return null; } FieldManager fieldManager = uiWriter.getFieldManager(); FieldWriter fieldWriter = fieldManager.require(fieldName); // Allocate a local variable to hold the dom id for this widget. Note // that idHolder is a local variable reference, not a string id. We // have to generate the ids at runtime, not compile time, or else // we'll reuse ids for any template rendered more than once. String idHolder = uiWriter.declareDomIdHolder(null); uiWriter.ensureCurrentFieldAttached(); FieldWriter childFieldWriter = uiWriter.parseElementToField(elem); String elementPointer = idHolder + "Element"; uiWriter.addInitStatement( "com.google.gwt.user.client.Element %s = " + "com.google.gwt.dom.client.Document.get().getElementById(%s).cast();", elementPointer, idHolder); if (uiWriter.useLazyWidgetBuilders()) { // Register a DOM id field. String lazyDomElementPath = LazyDomElement.class.getCanonicalName(); FieldWriter elementWriter = fieldManager.registerField(lazyDomElementPath, elementPointer); elementWriter.setInitializer(String.format("new %s<Element>(%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 { // Delay replacing the placeholders with the widgets until after // detachment so as not to end up attaching the widget to the DOM // unnecessarily uiWriter.addDetachStatement( "%1$s.addAndReplaceElement(%2$s, %3$s);", fieldName, childFieldWriter.getName(), elementPointer); } // Create an element to hold the widget. String tag = getLegalPlaceholderTag(elem); idHolder = fieldManager.convertFieldToGetter(idHolder); if (uiWriter.useSafeHtmlTemplates()) { idHolder = uiWriter.tokenForStringExpression(elem, idHolder); } else { idHolder = "\" + " + idHolder + " + \""; } return "<" + tag + " id='" + idHolder + "'></" + tag + ">"; } }