public void flushCharacters(boolean finalFlush, boolean topLevel) throws SAXException { if (currentCharacters.length() > 0) { final String currentString = currentCharacters.toString(); final char[] chars = currentString.toCharArray(); if (StringUtils.isBlank(currentString) || !topLevel) { // Just output whitespace as is super.characters(chars, 0, chars.length); } else { // The first element received determines the type of separator checkDelimiters(XMLConstants.XHTML_NAMESPACE_URI, spanQName, topLevel); // Wrap any other text within an xhtml:span super.startElement( XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName, getAttributesWithClass(XMLUtils.EMPTY_ATTRIBUTES)); super.characters(chars, 0, chars.length); super.endElement(XMLConstants.XHTML_NAMESPACE_URI, "span", spanQName); } isCharacters = false; currentCharacters.setLength(0); } if (finalFlush) checkDelimiters(XMLConstants.XHTML_NAMESPACE_URI, spanQName, topLevel); }
public void flushCharacters(boolean finalFlush, boolean topLevelCharacters) throws SAXException { final String currentString = currentCharacters.toString(); if (topLevelCharacters && !isAroundTableOrListElement) { // We handle top-level characters specially and wrap them in a span so we can hide them generateTopLevelSpanWithCharacters(currentCharacters.toString()); } else { // Just output characters as is in deeper levels, or when around at table or list element final char[] chars = currentString.toCharArray(); super.characters(chars, 0, chars.length); } currentCharacters.setLength(0); if (finalFlush) generateFirstDelimitersIfNeeded(); }
@Override protected void addCustomClasses(StringBuilder classes, XFormsControl control) { // Ask super first super.addCustomClasses(classes, control); if (control != null) { final XFormsTriggerControl triggerControl = (XFormsTriggerControl) control; if (triggerControl.isReadonly()) { // Add a special class to facilitate styling of readonly links with IE 6 classes.append(" xforms-trigger-readonly"); } } }
public void handleControlStart( String uri, String localname, String qName, Attributes attributes, final String effectiveId, XFormsControl control) throws SAXException { final String groupElementName = getContainingElementName(); final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); final String groupElementQName = XMLUtils.buildQName(xhtmlPrefix, groupElementName); final ElementHandlerController controller = handlerContext.getController(); // Place interceptor on output // NOTE: Strictly, we should be able to do without the interceptor. We use it here because it // automatically handles ids and element names currentSavedOutput = controller.getOutput(); if (!handlerContext.isNoScript()) { final boolean isMustGenerateBeginEndDelimiters = !handlerContext.isFullUpdateTopLevelControl(effectiveId); // Classes on top-level elements and characters and on the first delimiter final String elementClasses; { final StringBuilder classes = new StringBuilder(); appendControlUserClasses(attributes, control, classes); // NOTE: Could also use getInitialClasses(uri, localname, attributes, control), but then we // get the // xforms-group-appearance-xxforms-separator class. Is that desirable? handleMIPClasses( classes, getPrefixedId(), control); // as of August 2009, actually only need the marker class as well as // xforms-disabled if the group is non-relevant elementClasses = classes.toString(); } outputInterceptor = new OutputInterceptor( currentSavedOutput, groupElementQName, new OutputInterceptor.Listener() { // Classes on first delimiter private final String firstDelimiterClasses; { final StringBuilder classes = new StringBuilder("xforms-group-begin-end"); if (elementClasses.length() > 0) { classes.append(' '); classes.append(elementClasses); } firstDelimiterClasses = classes.toString(); } public void generateFirstDelimiter(OutputInterceptor outputInterceptor) throws SAXException { // Delimiter: begin group if (isMustGenerateBeginEndDelimiters) { outputInterceptor.outputDelimiter( currentSavedOutput, outputInterceptor.getDelimiterNamespaceURI(), outputInterceptor.getDelimiterPrefix(), outputInterceptor.getDelimiterLocalName(), firstDelimiterClasses, "group-begin-" + XFormsUtils.namespaceId(containingDocument, effectiveId)); } } }); controller.setOutput(new DeferredXMLReceiverImpl(outputInterceptor)); // Set control classes outputInterceptor.setAddedClasses(elementClasses); } else if (isNonRelevant(control)) { // In noscript, if the group not visible, set output to a black hole controller.setOutput(new DeferredXMLReceiverAdapter()); } // Don't support label, help, alert, or hint and other appearances, only the content! }
public void characters(char[] chars, int start, int length) { currentCharacters.append(chars, start, length); }
@Override protected void handleControlStart( String uri, String localname, String qName, Attributes attributes, String staticId, final String effectiveId, XFormsControl control) throws SAXException { final String xhtmlPrefix = handlerContext.findXHTMLPrefix(); final String spanQName = XMLUtils.buildQName(xhtmlPrefix, "span"); // Determine whether this case is visible final XFormsCaseControl caseControl = (XFormsCaseControl) containingDocument.getControls().getObjectByEffectiveId(effectiveId); if (!handlerContext.isTemplate() && caseControl != null) { // This case is visible if it is selected or if the switch is read-only and we display // read-only as static isVisible = caseControl.isVisible(); } else { isVisible = false; } final ElementHandlerController controller = handlerContext.getController(); currentSavedOutput = controller.getOutput(); // Place interceptor if needed if (!handlerContext.isNoScript()) { final boolean isMustGenerateBeginEndDelimiters = !handlerContext.isFullUpdateTopLevelControl(effectiveId); // Classes on top-level elements and characters and on the first delimiter final String elementClasses; { final StringBuilder classes = new StringBuilder(); appendControlUserClasses(attributes, control, classes); // Don't add MIP classes as they can conflict with classes of nested content if used outside // <tr>, etc. elementClasses = classes.toString(); } currentOutputInterceptor = new OutputInterceptor( currentSavedOutput, spanQName, new OutputInterceptor.Listener() { // Classes on first delimiter private final String firstDelimiterClasses; { final StringBuilder classes = new StringBuilder("xforms-case-begin-end"); if (elementClasses.length() > 0) { classes.append(' '); classes.append(elementClasses); } firstDelimiterClasses = classes.toString(); } public void generateFirstDelimiter(OutputInterceptor outputInterceptor) throws SAXException { if (isMustGenerateBeginEndDelimiters) { // Delimiter: begin case outputInterceptor.outputDelimiter( currentSavedOutput, outputInterceptor.getDelimiterNamespaceURI(), outputInterceptor.getDelimiterPrefix(), outputInterceptor.getDelimiterLocalName(), firstDelimiterClasses, "xforms-case-begin-" + XFormsUtils.namespaceId(containingDocument, effectiveId)); } } }); final String controlClasses; { final StringBuilder classes = new StringBuilder(isVisible ? "xforms-case-selected" : "xforms-case-deselected"); if (elementClasses.length() > 0) { classes.append(' '); classes.append(elementClasses); } controlClasses = classes.toString(); } currentOutputInterceptor.setAddedClasses(controlClasses); controller.setOutput(new DeferredXMLReceiverImpl(currentOutputInterceptor)); } else if (!isVisible) { // Case not visible, set output to a black hole controller.setOutput(new DeferredXMLReceiverAdapter()); } handlerContext.pushCaseContext(isVisible); }