/*
* � Copyright IBM Corp. 2010, 2013
*
* 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.ibm.xsp.extlib.renderkit.dojo.layout;
import java.io.IOException;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.component.UIScriptCollector;
import com.ibm.xsp.component.UIViewRootEx;
import com.ibm.xsp.context.FacesContextEx;
import com.ibm.xsp.dojo.FacesDojoComponent;
import com.ibm.xsp.extlib.component.dojo.layout.UIDojoContentPane;
import com.ibm.xsp.extlib.renderkit.dojo.DojoRendererUtil;
import com.ibm.xsp.extlib.resources.ExtLibResources;
import com.ibm.xsp.resource.DojoModuleResource;
import com.ibm.xsp.util.FacesUtil;
import com.ibm.xsp.util.HtmlUtil;
import com.ibm.xsp.util.JavaScriptUtil;
public class DojoContentPaneRenderer extends DojoLayoutRenderer {
@Override
protected String getDefaultDojoType(FacesContext context,
FacesDojoComponent component) {
return "extlib.dijit.ContentPane"; // $NON-NLS-1$
}
@Override
protected DojoModuleResource getDefaultDojoModule(FacesContext context,
FacesDojoComponent component) {
return ExtLibResources.extlibContentPane;
}
// This panel can render different things
// NOTHING- nothing
// FULL- the panel and its content as is
// FRAME- itself as a Dojo content pane, without its children (rendered with
// an href attr)
// AJXCONTENT- its content as part of a Ajax partial refresh, so only the
// children
private static final Integer NOTHING = Integer.valueOf(0);
private static final Integer FULL = Integer.valueOf(1);
private static final Integer FRAME = Integer.valueOf(2);
private static final Integer AJXCONTENT = Integer.valueOf(3);
@Override
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException {
Integer mode = NOTHING;
if (component.isRendered()) {
FacesContextEx contextEx = (FacesContextEx) context;
UIDojoContentPane c = (UIDojoContentPane) component;
// If the request is a partial refresh
if (contextEx.isAjaxPartialRefresh()) {
String refreshId = contextEx.getPartialRefreshId();
// If it targets the current component, then it might be
// - for a full refresh of the panel
// - for a refresh of only its children (from an href attribute)
if (StringUtil.equals(refreshId, c.getClientId(contextEx))) {
// Detect if it is a url to only refresh the content of the
// panel
// If not, the this is a partial refresh for the entire
// panel
String ajaxInner = (String)context.getExternalContext().getRequestParameterMap().get("$$ajaxinner"); //$NON-NLS-1$
if (StringUtil.equals(ajaxInner,"content")) { // $NON-NLS-1$
mode = AJXCONTENT;
} else if (StringUtil.equals(ajaxInner,"frame")) { // $NON-NLS-1$
if (c.isPartialRefresh()) {
mode = FRAME;
} else {
mode = FULL;
}
}
}
}
// Else, if it wasn't for the children of this panel
if (mode == NOTHING) {
// If the panel uses partial refresh
if (c.isPartialRefresh()) {
// Only render the frame, unless is is a partial refresh of
// one of its children
if (contextEx.isAjaxPartialRefresh()
&& FacesUtil.isClientIdChildOf(contextEx,
component, contextEx.getPartialRefreshId())) {
mode = AJXCONTENT;
} else {
mode = FRAME;
}
} else {
// The full panel should be rendered
mode = FULL;
}
}
}
HtmlUtil.storeEncodeParameter(context, component, mode);
if ((mode == FULL) || (mode == FRAME)) {
super.encodeBegin(context, component);
newLine(context.getResponseWriter());
}
}
@Override
public void encodeEnd(FacesContext context, UIComponent component)
throws IOException {
Integer mode = (Integer) HtmlUtil.readEncodeParameter(context,
component);
//
// Script handling
// The refresh is not done through a regular partialRefresh code from
// the XPages JS library, but through standard dojo code.
// Because of this, the <script> tags emitted by the ScriptCollector are
// not properly executed, because XSP.addOnLoad() requires
// a call to XSP._loaded().
// More then that, the scripts are in fact only loaded on FireFox when
// dynamically inserted into the DOM. To detect if they have
// been loaded (executed) or not, we use the '_cpOnLoadScript' flag.
// All of this is done in the 'XSP._cpOnLoad' function. To ensure that
// it is called once the panel content is loaded, we define
// a handler on the onLoad event. And because the script are not loaded
// in some browsers, we cannot emit a dojo.connect() JS
// statement, but we use a dojo/connect markup piece.
//
if (mode == AJXCONTENT) {
// We are refreshing the content of the panel
// We set the flag that defines if the script had been loaded
UIScriptCollector c = UIScriptCollector.find();
c.addScript("XSP._cpOnLoadScript=true"); // $NON-NLS-1$
}
if (mode == FRAME) {
ExtLibResources.addEncodeResource((UIViewRootEx) context
.getViewRoot(), ExtLibResources.extlibExtLib);
// When we only emit the tag of the content pane, we define an event
// handler on onLoad()
// to ensure that the script are properly loaded, and XSP._loaded()
// called once the panel
// is ready.
ResponseWriter w = context.getResponseWriter();
w.startElement("script", null); // $NON-NLS-1$
w.writeAttribute("type", "dojo/connect", null); // $NON-NLS-1$ $NON-NLS-2$
w.writeAttribute("event", "onLoad", null); // $NON-NLS-1$ $NON-NLS-2$
StringBuilder b = new StringBuilder();
b.append("XSP._cpOnLoad("); // $NON-NLS-1$
JavaScriptUtil.addString(b, component.getClientId(context));
b.append(");"); //$NON-NLS-1$
w.write(b.toString());
w.endElement("script"); // $NON-NLS-1$
}
if ((mode == FULL) || (mode == FRAME)) {
super.encodeEnd(context, component);
newLine(context.getResponseWriter());
}
HtmlUtil.removeEncodeParameter(context, component);
}
@Override
public boolean getRendersChildren() {
return true;
}
@Override
public void encodeChildren(FacesContext context, UIComponent component)
throws IOException {
Integer mode = (Integer) HtmlUtil.readEncodeParameter(context,
component, false);
if ((mode == FULL) || (mode == AJXCONTENT)) {
FacesUtil.renderChildren(context, component);
}
// if(mode==FRAME) {
// context.getResponseWriter().write("IN FRAME!");
// }
}
@Override
protected void initDojoAttributes(FacesContext context,
FacesDojoComponent dojoComponent, Map<String, String> attrs)
throws IOException {
super.initDojoAttributes(context, dojoComponent, attrs);
if (dojoComponent instanceof UIDojoContentPane) {
UIDojoContentPane c = (UIDojoContentPane) dojoComponent;
// Check the url
String href = c.getHref();
if (c.isPartialRefresh()) {
// Encode the URL
href = context.getExternalContext().encodeActionURL(
c.getAjaxUrl(context));
}
DojoRendererUtil.addDojoHtmlAttributes(attrs, "href", href); // $NON-NLS-1$
DojoRendererUtil.addDojoHtmlAttributes(attrs, "extractContent", c // $NON-NLS-1$
.isExtractContent());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "parseOnLoad", c // $NON-NLS-1$
.isParseOnLoad(), true);
DojoRendererUtil.addDojoHtmlAttributes(attrs, "preventCache", c // $NON-NLS-1$
.isPreventCache());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "preload", c // $NON-NLS-1$
.isPreload());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "refreshOnShow", c // $NON-NLS-1$
.isRefreshOnShow());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "loadingMessage", c // $NON-NLS-1$
.getLoadingMessage());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "errorMessage", c // $NON-NLS-1$
.getErrorMessage());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "onLoad", c // $NON-NLS-1$
.getOnLoad());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "onUnload", c // $NON-NLS-1$
.getOnUnload());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "onDownloadStart", c // $NON-NLS-1$
.getOnDownloadStart());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "onContentError", c // $NON-NLS-1$
.getOnContentError());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "onDownloadError", c // $NON-NLS-1$
.getOnDownloadError());
DojoRendererUtil.addDojoHtmlAttributes(attrs, "onDownloadEnd", c // $NON-NLS-1$
.getOnDownloadEnd());
}
}
}