diff --git a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.domino.das/src/com/ibm/domino/das/servlet/DasHttpResponseWrapper.java b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.domino.das/src/com/ibm/domino/das/servlet/DasHttpResponseWrapper.java index 0205bf7..861e6bf 100644 --- a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.domino.das/src/com/ibm/domino/das/servlet/DasHttpResponseWrapper.java +++ b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.domino.das/src/com/ibm/domino/das/servlet/DasHttpResponseWrapper.java @@ -186,7 +186,7 @@ private EncodedOutputStream getEncodedOutputStream() throws IOException{ /** * Inner class EncodedOutputStream used to support encodings like gzip and deflate. - * Cache is require to emit the Conent-Length and used to support persistent connections. + * Cache is require to emit the Content-Length and used to support persistent connections. **/ private static class EncodedOutputStream extends ServletOutputStream { diff --git a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/resources/web/extlib/dijit/DynamicContent.js b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/resources/web/extlib/dijit/DynamicContent.js index 61618df..cd1d1f7 100644 --- a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/resources/web/extlib/dijit/DynamicContent.js +++ b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/resources/web/extlib/dijit/DynamicContent.js @@ -1,5 +1,5 @@ /* - * © Copyright IBM Corp. 2010 + * © Copyright IBM Corp. 2010 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,24 @@ dojo.provide("extlib.dijit.DynamicContent"); XSP.showContent = function xe_sct(panelid,content,params) { - params = dojo.mixin(params,{content:content}) - if(XSP._hashContentId==panelid) { + params = dojo.mixin(params, dojo.queryToObject(dojo.hash())); + + var mixParams = {}; + var elem = dojo.byId(panelid); + var contentParam = "content"; + if(elem != null) { + var elemContentParam = elem.getAttribute("data-param"); + if(elemContentParam) { + contentParam = elemContentParam; + } + } + mixParams[contentParam] = content; + + params = dojo.mixin(params,mixParams) + // If the param is set up for useHash, update the hash as well. + // This doesn't check the id property in order to maintain consistency with + // previous behavior. + if(XSP._hashContent && XSP._hashContent[contentParam]) { XSP.updateHash(dojo.objectToQuery(params)) XSP.partialRefreshGet(panelid,{params:XSP._hash}) } else { @@ -26,14 +42,48 @@ XSP.showContent = function xe_sct(panelid,content,params) { } XSP.registerHash = function xe_rhs(panelid) { - XSP._hashContentId=panelid + if(!XSP._hashContent) { + XSP._hashContent = {}; + } + + var elem = dojo.byId(panelid); + if(!elem) { return; } + var contentParam = elem.getAttribute("data-param"); + + if(!XSP._hashContent[contentParam]) { + XSP._hashContent[contentParam] = { + id: panelid, + value: "" + }; + } + if(!XSP._hashCallback) { dojo.require("dojo.hash"); XSP._hashCallback = function(hash) { - // Only refresh if the has is different from the last one - if(XSP._hash!=hash) { - XSP._hash=hash - XSP.partialRefreshGet(XSP._hashContentId,{params:hash}) + var hashObj = dojo.queryToObject(hash); + var refreshIds = []; + for(var paramName in hashObj) { + // Only refresh if the hash is different from the last one for that panel + if(XSP._hashContent[paramName] && XSP._hashContent[paramName].value != hashObj[paramName]) { + refreshIds.push(XSP._hashContent[paramName].id); + XSP._hashContent[paramName].value = hashObj[paramName]; + } + } + + // Cycle through IDs needing an update in sequence + if(refreshIds.length > 0) { + XSP._hash=hash; + + var refresh = function() { + var id = refreshIds.pop(); + if(id) { + XSP.partialRefreshGet(id, { + params: hash, + onComplete: refresh + }); + } + } + refresh(); } } dojo.addOnLoad( function() { @@ -47,6 +97,16 @@ XSP.registerHash = function xe_rhs(panelid) { // Update the copy of the hash while preventing the event processing XSP.updateHash = function xs_uhs(h) { + // Split it apart to update only the specific part of the hash + var updateObj = dojo.queryToObject(h); + var hashObj = dojo.queryToObject(dojo.hash()); + + for(var updateKey in updateObj) { + hashObj[updateKey] = updateObj[updateKey]; + } + + h = dojo.objectToQuery(hashObj); + XSP._hash=h dojo.hash(h) } diff --git a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/component/dynamiccontent/UIDynamicContent.java b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/component/dynamiccontent/UIDynamicContent.java index 4f23f30..ff89b6d 100644 --- a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/component/dynamiccontent/UIDynamicContent.java +++ b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/component/dynamiccontent/UIDynamicContent.java @@ -45,18 +45,18 @@ */ public class UIDynamicContent extends UIDynamicControl { - public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.dynamiccontent.DynamicContent"; // $NON-NLS-1$ + public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.dynamiccontent.DynamicContent"; //$NON-NLS-1$ public static final String RENDERER_TYPE = "com.ibm.xsp.extlib.dynamiccontent.DynamicContent"; //$NON-NLS-1$ - public static final String XSPCONTENT_PARAM = "content"; // $NON-NLS-1$ - public static final String PSEUDO_FACET_EMPTY = "-empty-"; // $NON-NLS-1$ - public static final String PSEUDO_FACET_CHILDREN = "-children-"; // $NON-NLS-1$ - public static final String PSEUDO_FACET_DEFAULT = "-default-"; // $NON-NLS-1$ + public static final String PSEUDO_FACET_EMPTY = "-empty-"; //$NON-NLS-1$ + public static final String PSEUDO_FACET_CHILDREN = "-children-"; //$NON-NLS-1$ + public static final String PSEUDO_FACET_DEFAULT = "-default-"; //$NON-NLS-1$ private Boolean partialEvents; private Boolean useHash; private String defaultFacet; + private String contentParam; // The currently displayed facet, not a property in the All Properties. // This does not vary for different clientIds, as it reflects the // structure of the UIComponent tree. @@ -140,6 +140,27 @@ public void setDefaultFacet(String defaultFacet) { this.defaultFacet = defaultFacet; } + /** + * @return the user-specified content parameter name, if specified and non-empty, or + * {@link UIDynamicControl#XSPCONTENT_PARAM} otherwise + */ + @Override + public String getContentParam() { + if(StringUtil.isNotEmpty(this.contentParam)) { + return this.contentParam; + } + ValueBinding _vb = getValueBinding("defaultFacet"); //$NON-NLS-1$ + if(_vb != null) { + return (String)_vb.getValue(getFacesContext()); + } else { + return XSPCONTENT_PARAM; + } + } + + public void setContentParam(String contentParam) { + this.contentParam = contentParam; + } + @Override public MethodBinding getBeforeContentLoad() { @@ -197,7 +218,7 @@ public void show(String facet, Map parameters) { // facet is non-empty here if( !StringUtil.equals(PSEUDO_FACET_EMPTY, facet) ) { pushParameters(context, parameters); - TypedUtil.getRequestMap(context.getExternalContext()).put(XSPCONTENT_PARAM,facet); + TypedUtil.getRequestMap(context.getExternalContext()).put(getContentParam(),facet); createContent(context); } else { deleteContent(context); @@ -210,15 +231,15 @@ protected void updateHash(String facet, Map parameters) { StringBuilder b = new StringBuilder(); if(StringUtil.isNotEmpty(facet)) { try { - b.append(XSPCONTENT_PARAM); + b.append(getContentParam()); b.append('='); - b.append(URLEncoder.encode(facet,"UTF-8")); // $NON-NLS-1$ + b.append(URLEncoder.encode(facet,"UTF-8")); //$NON-NLS-1$ if(parameters!=null) { for(Map.Entry e: parameters.entrySet()) { b.append('&'); - b.append(URLEncoder.encode(e.getKey().toString(), "UTF-8")); // $NON-NLS-1$ + b.append(URLEncoder.encode(e.getKey().toString(), "UTF-8")); //$NON-NLS-1$ b.append('='); - b.append(URLEncoder.encode(e.getValue().toString(),"UTF-8")); // $NON-NLS-1$ + b.append(URLEncoder.encode(e.getValue().toString(),"UTF-8")); //$NON-NLS-1$ } } } catch(UnsupportedEncodingException ex) {} @@ -250,7 +271,7 @@ public boolean isCreateRequest(FacesContextEx ctx) { String id = ctx.getPartialRefreshId(); if(StringUtil.equals(id, getClientId(ctx))) { // We should check that this is the initial request - String xspContent = (String)ctx.getExternalContext().getRequestParameterMap().get(XSPCONTENT_PARAM); + String xspContent = (String)ctx.getExternalContext().getRequestParameterMap().get(getContentParam()); return StringUtil.isNotEmpty(xspContent); } } @@ -285,7 +306,7 @@ public void buildDefaultContents(FacesContext context, FacesComponentBuilder bui @Override protected void buildDynamicContents(FacesContext context, FacesComponentBuilder builder) throws FacesException { // Build the facet if passed as a parameter - String xspFacet = ExtLibUtil.readParameter(context,XSPCONTENT_PARAM); + String xspFacet = ExtLibUtil.readParameter(context,getContentParam()); // the pseudo-facet will have been pre-processed by the show(..) method, // so it will not be "", -empty- or -default-, but it may still be -children- buildFacet(context, builder, xspFacet); @@ -354,11 +375,12 @@ public void restoreState(FacesContext _context, Object _state) { currentFacet = (String)_values[4]; beforeContentLoad = StateHolderUtil.restoreMethodBinding(_context, this, _values[5]); afterContentLoad = StateHolderUtil.restoreMethodBinding(_context, this, _values[6]); + contentParam = (String)_values[7]; } @Override public Object saveState(FacesContext _context) { - Object _values[] = new Object[7]; + Object _values[] = new Object[8]; _values[0] = super.saveState(_context); _values[1] = partialEvents; _values[2] = useHash; @@ -366,6 +388,7 @@ public Object saveState(FacesContext _context) { _values[4] = currentFacet; _values[5] = StateHolderUtil.saveMethodBinding(_context, beforeContentLoad); _values[6] = StateHolderUtil.saveMethodBinding(_context, afterContentLoad); + _values[7] = contentParam; return _values; } } \ No newline at end of file diff --git a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/component/dynamiccontent/UIDynamicControl.java b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/component/dynamiccontent/UIDynamicControl.java index d259f60..6cf1e76 100644 --- a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/component/dynamiccontent/UIDynamicControl.java +++ b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/component/dynamiccontent/UIDynamicControl.java @@ -44,8 +44,11 @@ public abstract class UIDynamicControl extends AbstractDynamicContent implements // the execId control to be a NamingContainer, and otherwise will not validate // the content of that control. - public static final String COMPONENT_FAMILY = "com.ibm.xsp.extlib.dynamiccontent.Dynamic"; // $NON-NLS-1$ - public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.dynamiccontent.Dynamic"; // $NON-NLS-1$ + public static final String COMPONENT_FAMILY = "com.ibm.xsp.extlib.dynamiccontent.Dynamic"; //$NON-NLS-1$ + public static final String COMPONENT_TYPE = "com.ibm.xsp.extlib.dynamiccontent.Dynamic"; //$NON-NLS-1$ + + + public static final String XSPCONTENT_PARAM = "content"; //$NON-NLS-1$ // FacesDynamicContainer private String sourcePageName; @@ -69,6 +72,10 @@ public boolean isAutoCreate() { public String getFamily() { return COMPONENT_FAMILY; } + + public String getContentParam() { + return XSPCONTENT_PARAM; + } // ======================================================== @@ -99,7 +106,7 @@ public void buildContents(FacesContext context, FacesComponentBuilder builder) t //[dc] If the content parameter is present as parameter that means the URL was of the form http://my.web/myxsp.xsp?content=key // in this case we build the actual "key" facet, so the whole page with the correct content will be returned to the client. // This is needed when a web crawler visit the page following the link. - String xspFacet = ExtLibUtil.readParameter(context,UIDynamicContent.XSPCONTENT_PARAM); + String xspFacet = ExtLibUtil.readParameter(context,getContentParam()); if(xspFacet != null && builder.isFacetAvailable(context, this, xspFacet)) { buildDynamicContents(context, builder); }else { @@ -129,6 +136,7 @@ protected void buildDynamicContents(FacesContext context, FacesComponentBuilder // FacesDynamicContainer implementation // ======================================================== + @Override public String getSourcePageName() { return sourcePageName; } diff --git a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/extlib-dynamiccontent.xsp-config b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/extlib-dynamiccontent.xsp-config index 5c8004d..a2e2db4 100644 --- a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/extlib-dynamiccontent.xsp-config +++ b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/extlib-dynamiccontent.xsp-config @@ -143,6 +143,20 @@ + + %property.contentParam.component.dynamicContent.descr% + %property.contentParam.component.dynamicContent.name% + contentParam + java.lang.String + + + basics + + todo + + + + %property.defaultFacet.component.dynamicContent.descr% %property.defaultFacet.component.dynamicContent.name% diff --git a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/extlib-dynamiccontent_en.properties b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/extlib-dynamiccontent_en.properties index 05acce8..5a4f5d0 100644 --- a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/extlib-dynamiccontent_en.properties +++ b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/extlib-dynamiccontent_en.properties @@ -60,3 +60,5 @@ property.for.complex-type.inPlaceFormAction.name= For property.for.complex-type.inPlaceFormAction.descr= ID of the In Place Form control whose state will be changed by this action. If empty, it uses the closest In Place Form Control in the parent hierarchy. property.formAction.name= Form Action property.formAction.descr= The Action to perform on the In Place Form: show, hide or toggle. +property.contentParam.component.dynamicContent.name= Content Parameter Name +property.contentParam.component.dynamicContent.descr= The URL/hash parameter name to use when determining the current facet. If empty, it defaults to "content". diff --git a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/raw-extlib-dynamiccontent.xsp-config b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/raw-extlib-dynamiccontent.xsp-config index 2c2e128..56c8e53 100644 --- a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/raw-extlib-dynamiccontent.xsp-config +++ b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/config/raw-extlib-dynamiccontent.xsp-config @@ -201,11 +201,8 @@ - - Indicate that the control should manage its state using a URL hash, that is some text after a "#" symbol in the URL, like: /page1.xsp#detail + + Indicate that the control should manage its state using a URL hash, that is some text after a "#" symbol in the URL, like: /page1.xsp#content=detail Use URL Hash useHash boolean @@ -235,6 +232,20 @@ + + The URL/hash parameter name to use when determining the current facet. If empty, it defaults to "content". + Content Parameter Name + contentParam + java.lang.String + + + basics + + todo + + + + com.ibm.xsp.extlib.dynamiccontent.Dynamic diff --git a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/renderkit/html_extended/dynamiccontent/DynamicControlRenderer.java b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/renderkit/html_extended/dynamiccontent/DynamicControlRenderer.java index bc61042..180b1f4 100644 --- a/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/renderkit/html_extended/dynamiccontent/DynamicControlRenderer.java +++ b/extlib/lwp/product/runtime/eclipse/plugins/com.ibm.xsp.extlib.controls/src/com/ibm/xsp/extlib/renderkit/html_extended/dynamiccontent/DynamicControlRenderer.java @@ -26,6 +26,7 @@ import com.ibm.commons.util.StringUtil; import com.ibm.xsp.component.UIViewRootEx; import com.ibm.xsp.extlib.component.dynamiccontent.AbstractDynamicContent; +import com.ibm.xsp.extlib.component.dynamiccontent.UIDynamicControl; import com.ibm.xsp.extlib.controls.ExtlibControlsLogger; import com.ibm.xsp.extlib.renderkit.html_extended.FacesRendererEx; import com.ibm.xsp.resource.Resource; @@ -50,6 +51,10 @@ public void encodeBegin(FacesContext context, UIComponent component) w.writeAttribute("id", clientId, "id"); // $NON-NLS-1$ $NON-NLS-2$ //w.writeAttribute("style", "display: none", "style"); + if(component instanceof UIDynamicControl) { + w.writeAttribute("data-param", ((UIDynamicControl) component).getContentParam(), null); //$NON-NLS-1$ + } + // Add the newly added resources, if some if(AbstractDynamicContent.USE_DYNAMIC_RESOURCES) { Integer rc = (Integer)context.getExternalContext().getRequestMap().get(AbstractDynamicContent.DYNAMIC_RESOURCES);