/** Licensed Materials - Property of IBM, 5724-E76 and 5724-E77, (C) Copyright IBM Corp. 2009, 2010, 2011 - All Rights reserved. **/
dojo.i18n._preloadLocalizations("contentmapping.nls.contentmapping_picker_layer", ["ROOT","ar","ca","cs","da","de","el","en","es","fi","fr","he","hr","hu","it","ja","kk","ko","nl","no","pl","pt","pt-br","ro","ru","sk","sl","sv","th","tr","uk","xx","zh","zh-tw"]);
if(!dojo._hasResource["com.ibm.wps.contentmapping.menucontribution.CMContextMenuLoadDeferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.menucontribution.CMContextMenuLoadDeferred"] = true;
/** Licensed Materials - Property of IBM, 5724-U69, (C) Copyright IBM Corp. 2011 - All Rights reserved. **/
dojo.provide("com.ibm.wps.contentmapping.menucontribution.CMContextMenuLoadDeferred");
dojo.registerModulePath("com.ibm.wps.contentmapping.menucontribution","../com/ibm/wps/contentmapping/menucontribution");
dojo.require("com.ibm.widgets._Traceable");
/**
* Class for executing the retrieval of action menu items, concerning the administration
* of content mappings, asynchronously. It implements the Deferred interface
* allowing to trigger a callback after the entire action is finished.
*/
dojo.declare( "com.ibm.wps.contentmapping.menucontribution.CMContextMenuLoadDeferred", [com.ibm.mashups.enabler.Deferred, com.ibm.widgets._Traceable], {
/**
* Public constructor of this class.
*
* @param {Object} context the context (this) for start function
* @param {Object} startfn the function to execute when 'start' is called on this Deffered object
* @param {Object} params the parameters to pass to the start function
*/
constructor: function(context, startfn, params){
// set instance trace support flag
this._isTracing = this.isTracing();
this.context = context;
this.startfn = startfn;
this.params = params;
},
/**
* Sets the handler of the deferred action. It is called when the entire
* action has finished.
* Please note that the status of the action is transported only with
* callbacks, even if you use synchronous mode. If you need to check the status,
* you must use callback functions.
* @param {Object} callback the callback funtion in the format of Function(Object resource, int statusCode, Object[] params)
.
* Must not be null
* Callbackparameters
* resource
- resource object or id string
* of the related resource.
* May be null
in case the action does not relate
* to a particular resource. In case multiple resources are involved in the
* action, the DeferredOperation interface may be used to obtain the resource
* objects or string id
s of those resources.
* statusCode
- the overall HTTP status
* code of the action (the highest status code of the involved operations).
* params
- the parameters
* passed into the callback
* @param {Object[]} parameters optional array of parameters to be
* passed on to the callback function. May be null
* @return {com.ibm.mashups.enabler.Deferred} the deferred object
*/
setFinishedCallback: function(callback, parameters) {
// entry trace
var m = "setFinishedCallback(callback, parameters)";
if (this._isTracing) {
this.traceEntry(m, [callback, parameters]);
}
this.callbackFn = callback;
this.callbackParams = parameters;
// exit trace
if (this._isTracing) {
this.traceExit(m, this);
}
return this;
},
/**
* Executes the deferred action and invokes the callback functions set
* with the deferred object.
* @param {Boolean} sync indicates if the deferred action is executed
* synchronously or asynchronously. Optional, defaults to true.
* @return {Object} resource if called asynchronously, the return value is
* undefined
, otherwise a resource object or id string of the
* related resource is returned.
In order to obtain information on
* the resource as well as on the status code of the operation, you
* must use the callback functions of the deferred object.
*/
start: function(sync) {
// entry trace
var m = "start(sync)";
if (this._isTracing) {
this.traceEntry(m, sync);
}
var mode = (sync || typeof(sync) == 'undefined') ? true : false;
var result = dojo.hitch(this.context, this.startfn)(this, mode, this.params);
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
},
/**
* Calls the callback function set on this Deferred object after the retrieval
* of action menu items, concerning the administration of content mappings, has finished.
* This function should be called at the end of the start function.
*
* @param {Object} res the result of the action executed by this Deferred object
* @param {Object} status the return status of the action executed by this Deferred object
*/
finish: function(res, status) {
// entry trace
var m = "finish(res, status)";
if (this._isTracing) {
this.traceEntry(m, [res, status]);
}
var callBack = this.getFinishedCallback(), callBackParams = this.getFinishedCallbackParameters();
if(callBack && !this._finished) {
this._finished = true;
callBack(res, status, callBackParams);
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
/**
* Private getter of property callbackFn
*/
getFinishedCallback: function(){
return this.callbackFn;
},
/**
* Private getter of property callbackParams
*/
getFinishedCallbackParameters: function(){
return this.callbackParams;
}
});
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.utils.CMPickerConfig"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.utils.CMPickerConfig"] = true;
/** ****************************************************************** */
/* Licensed Materials - Property of IBM */
/* */
/* 5724Z67 */
/* */
/* Copyright IBM Corp. 2011 All Rights Reserved. */
/* */
/* US Government Users Restricted Rights - Use, duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/** ****************************************************************** */
dojo.provide("com.ibm.wps.contentmapping.utils.CMPickerConfig");
dojo.registerModulePath("com.ibm.wps.contentmapping.utils.", "../com/ibm/wps/contentmapping/utils");
dojo.require("com.ibm.widgets._Traceable");
dojo.declare("com.ibm.wps.contentmapping.utils.CMPickerConfig",
[com.ibm.widgets._Traceable], {
// the portal navigation model
_navModel: null,
// override of the current page id
_pageIDOverride: null,
// summary:
// Provides configuration settings for the CMPickerDialog
constructor: function(/*Object*/p_params){
// summary:
// Constructs an object instance
// tags:
// public
// set instance trace support flag
this._isTracing = this.isTracing();
// entry trace
var m = "constructor()";
if (this._isTracing) {
this.traceEntry(m, dojo.toJson(p_params));
}
if (p_params){
this._pageIDOverride = p_params.pageID;
}
this._navModel = com.ibm.mashups.enabler.navigation.Factory.getNavigationModel();
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
getMyContentHandlerBaseUrl: function() {
// summary:
// Constructs a fully qualified Url for mycontenthandler, which can be used for sending
// requests to the handler
// returns:
// String Returns an empty string, if the ibmPortalConfig object is not available
// tags:
// public
// entry trace
var m = "getMyContentHandlerBaseUrl()";
if (this._isTracing) {
this.traceEntry(m);
}
var result = "";
if (location && location.protocol && location.host &&
ibmPortalConfig && ibmPortalConfig.contentHandlerURI) {
result = (location.protocol + "//" + location.host + ibmPortalConfig.contentHandlerURI);
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // String
},
getCMAtomDataSourceBaseUrl: function() {
// summary:
// Constructs a fully qualified base Url for sending AJAX requests to the contentmapping
// REST API
// returns:
// String
// tags:
// public
// entry trace
var m = "getCMAtomDataSourceBaseUrl()";
if (this._isTracing) {
this.traceEntry(m);
}
var result = this.addParamToURL(this.getMyContentHandlerBaseUrl(), "uri", com.ibm.wps.contentmapping.utils.CMPickerConfig.CONTENTMAPPING_ATOM_DATASOURCE_PREFIX);
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // String
},
addParamToURL: function(/* String */url, /* String */name, /* String[]? | String?*/ value) {
// summary:
// Adds a parameter to the passed URL and returns the new URL string
// url:
// The URL to add the parameter to
// value:
// A single or multi value of the parameter
//
if (url && name) {
var newUrl = null;
var fragmentPos = url.lastIndexOf("#");
var fragment = null;
if (fragmentPos > -1) {
fragment = url.substring(fragmentPos);
newUrl = url.substring(0, fragmentPos);
} else {
newUrl = url;
}
var protocolExtParam = null;
var queryPos = newUrl.indexOf("?");
if (queryPos != -1) {
var protocolExtParamPos = newUrl.lastIndexOf(";", queryPos);
if (protocolExtParamPos != -1) {
protocolExtParam = newUrl.substring(protocolExtParamPos);
newUrl = newUrl.substring(0, protocolExtParamPos);
}
if (newUrl.length - 1 > queryPos) {
newUrl = newUrl + "&";
}
} else {
newUrl = newUrl + "?";
}
if (value) {
if (value instanceof Array) {
for (i = 0; i < value.length; i++) {
newUrl = newUrl + encodeURIComponent(name) + "=" + encodeURIComponent(value[i]);
if (i + 1 < value.length) {
newUrl = newUrl + "&";
}
}
} else {
newUrl = newUrl + encodeURIComponent(name) + "=" + encodeURIComponent(value);
}
} else {
newUrl = newUrl + encodeURIComponent(name) + "=";
}
if (protocolExtParam) {
newUrl = newUrl + protocolExtParam;
}
if (fragment) {
newUrl = newUrl + fragment;
}
return newUrl;
} else {
return url;
}
},
getCurrentPage: function() {
// summary:
// Returns the page as JSON object
// returns:
// JSON object Returns an empty string, if the navigation model is not available
// tags:
// public
// entry trace
var m = "getCurrentPage()";
if (this._isTracing) {
this.traceEntry(m);
}
var result = "";
if (this._navModel) {
this._navModel.addStrategy(new com.ibm.mashups.enabler.strategy.AdminModelStrategy());
result = this._navModel.find(this.getCurrentPageID()).start();
this._navModel.removeStrategy("com.ibm.mashups.enabler.strategy.AdminModelStrategy");
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // Object
},
getCurrentResourceID: function() {
// summary:
// Returns the resourceID of the current page as a string. For shared pages this is the id of the real
// content node, for normal pages this is the same as returned by getCurrentPageID().
// returns:
// String Returns an empty string, if the navigation model is not available
// tags:
// public
// entry trace
var m = "getCurrentResourceID()";
if (this._isTracing) {
this.traceEntry(m);
}
var result = "";
var currentpage = this.getCurrentPage();
if (currentpage) {
this._navModel.addStrategy(new com.ibm.mashups.enabler.strategy.AdminModelStrategy());
var contentNode = currentpage.getContent().start();
result = contentNode.getID();
this._navModel.removeStrategy("com.ibm.mashups.enabler.strategy.AdminModelStrategy");
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // String
},
hasPageEditorRights: function() {
// summary:
// Returns true if the current user has EDITOR access rights to the current page
// returns:
// boolean Returns true if the current user has EDITOR access rights to the current page
// tags:
// public
// entry trace
var m = "hasPageEditorRights()";
if (this._isTracing) {
this.traceEntry(m);
}
var result;
var currentpage = this.getCurrentPage();
if (currentpage) {
result = currentpage.hasRole(com.ibm.mashups.enabler.ac.RoleType.EDITOR);
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // boolean
},
getCurrentPageID: function() {
// summary:
// Returns the pageID of the current page as a string
// returns:
// String Returns an empty string, if the ibmPortalConfig object is not available
// tags:
// public
// entry trace
var m = "getCurrentPageID()";
if (this._isTracing) {
this.traceEntry(m);
}
var result = "";
if (this._pageIDOverride){
result = this._pageIDOverride;
}
else if (ibmPortalConfig) {
result = ibmPortalConfig.currentPageOID;
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // String
}
});
com.ibm.wps.contentmapping.utils.CMPickerConfig.COMMUNITY_DATASOURCE_URL = "iccmty/all";
com.ibm.wps.contentmapping.utils.CMPickerConfig.CONTENTMAPPING_ATOM_DATASOURCE_PREFIX = "contentmapping:oid:";
com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDER_WCM = "ibm.wcm.provider";
com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDER_CONNECTIONS = "ibm.connections.provider";
// JSON configuration object which contains one entry per known scopeProvider.
// Each configuration object supports the following properties
//
// feedQueryUrl: String
// Suffix which gets concatenated with the mycontenthandler base Url to build the feed request Url
// schemaPrefix: [optional] String
// If necessary, specifies the prefix each ID value of the returned feed has and which needs to be
// stripped to get the ID only. If the feed already returns plain IDs, this property can be omitted.
// scopeProvider: String
// The name of the scopeProvider (again), so the function receiving a configuration object can e.g.
// run lookups with that name against the NLS bundle for getting dialog titles
// getEntries: Function
// Callback function that returns the array within the returned JSON feed object where the entries are
// located.
// Example: If the JSON datasource returns an object with the following layout:
//
// atom: {
// entries: [
// {}, {}, {}
// ]
// }
// the function would receive the top-level object with property 'atom' and would have to return the 'entries'
// array
com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDERS = {
"ibm.wcm.provider": { // no need to specify settings for the wcm scope provider, as there is special case
// handling in place for WCM (uses another dialog)
feedQueryUrl: "",
schemaPrefix: "",
scopeProvider: "ibm.wcm.provider",
getEntries: "",
feedQueryUrlTemplate: "",
feedSupportsSearch: false,
feedSearchParam: "",
showTruncationMessage: false
},
"ibm.connections.provider": {
feedQueryUrl: "iccmty/all",
schemaPrefix: "",
scopeProvider: "ibm.connections.provider",
getEntries: function(/*Object*/ p_feedAsJSON) {
if (p_feedAsJSON && p_feedAsJSON.communities) {
return p_feedAsJSON.communities;
} else {
return [];
}
},
feedQueryUrlTemplate: "iccmty/all?search=${searchTerm}",
feedSupportsSearch: true,
feedSearchParam: "searchTerm",
showTruncationMessage: true
}
};
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.menucontribution.CMContextMenuLoader"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.menucontribution.CMContextMenuLoader"] = true;
/** Licensed Materials - Property of IBM, 5724-U69, (C) Copyright IBM Corp. 2011 - All Rights reserved. **/
dojo.provide("com.ibm.wps.contentmapping.menucontribution.CMContextMenuLoader");
dojo.registerModulePath("com.ibm.wps.contentmapping.menucontribution", "../com/ibm/wps/contentmapping/menucontribution");
dojo.require("com.ibm.cp.DojoLocalized");
dojo.require("com.ibm.widgets._Traceable");
/**
* This object is used to retrieve context menu items, concerning the administration
* of content mappings, by returning a {@link com.ibm.mashups.enabler.Deferred Deferred} object
* that returns those items either directly in synchronous mode or via the callback
* in asynchronous mode. The items returned by the {@link com.ibm.mashups.enabler.Deferred Deferred} must be an array of items
* that follow the {@link com.ibm.mashups.builder.model.ContextMenuItem ContextMenuItem} format.
*/
dojo.declare("com.ibm.wps.contentmapping.menucontribution.CMContextMenuLoader", [com.ibm.mashups.builder.model.ContextMenuLoader, com.ibm.widgets._Traceable], {
constructor: function(){
// set instance trace support flag
this._isTracing = this.isTracing();
this._config = new com.ibm.wps.contentmapping.utils.CMPickerConfig();
},
actions: [{
bundlePackage: "com.ibm.wps.contentmapping",
bundleName: "ContentMappingPickerUserInterface",
bundleKey: "EDIT_CONTENTMAPPINGS",
ordinal: 80,
enabled: true,
actionMethod: "launchContentMappingPickerDialog",
id: "CM:edit"
}],
/**
* Returns a {@link com.ibm.mashups.enabler.Deferred Deferred} object that will pass an array of the items loaded by this object
* as the first argument to the callback.
*
* @param {String} contextMenuId this is id of the context menu. Examples: ContextMenu.page, ContextMenu.space, ContextMenu.toolbox, ContextMenu.modeSelector ContextMenu.widgetSkin, or any additional extension. Must not be null
.
* @param {String} targetResourceId this is the ID of the resource to associate the decision for this menu choice with. Must not be null
.
* @param {String} targetResourceType this is the resource type of the resource to associate the decision for this menu choice with. May be null
.
* Possible values for this could be "com.ibm.mashups.enabler.space.SpaceNode", "com.ibm.mashups.iwidget.widget.IWidgetDefinition", "com.ibm.mashups.enabler.navigation.NavigationNode",
* or any other type used by an extension.
* @param {Object} someObject this allows an arbitrary object to be passed into the context menu loader in case it needs additional data for making the decisions.
* @return {com.ibm.mashups.enabler.Deferred} Deferred object that loads the data and fires the callback
* with an array of items conforming to the {@link com.ibm.mashups.builder.model.ContextMenuItem ContextMenuItem}
* format that are retrieved by this loader; never null
.
*/
getItems: function(/*String*/contextMenuId, /*String*/ targetResourceId, /*String*/ targetResourceType, /*Object*/ someObject){
// entry trace
var m = "getItems(contextMenuId, targetResourceId, targetResourceType, someObject)";
if (this._isTracing) {
this.traceEntry(m, [contextMenuId, targetResourceId, targetResourceType, someObject]);
}
var me = this;
var dfd = new com.ibm.wps.contentmapping.menucontribution.CMContextMenuLoadDeferred(this, function(deferred, sync, params){
var res = me._initItems(contextMenuId, targetResourceId, targetResourceType, someObject);
deferred.finish(res, 200);
return res;
});
// exit trace
if (this._isTracing) {
this.traceExit(m, dfd);
}
return dfd;
},
/**
* Event that notifies the system that this loader's contents have changed and may be reloaded
* to avoid stale data. Callers may call this function on a loader that has been registered
* to a particular context menu id or used as a contribution to an existing context menu. The
* system listens to this event in order to notify any registered listeners on a context menu
* of the event.
* @type void
*/
onChange: function(){
},
/**
* Returns an array of items conforming to the {@link com.ibm.mashups.builder.model.ContextMenuItem ContextMenuItem}
* format that are retrieved by this loader.
*
* @param {String} contextMenuId this is id of the context menu. Examples: ContextMenu.page, ContextMenu.space, ContextMenu.toolbox, ContextMenu.modeSelector ContextMenu.widgetSkin, or any additional extension. Must not be null
.
* @param {String} targetResourceId this is the ID of the resource to associate the decision for this menu choice with. Must not be null
.
* @param {String} targetResourceType this is the resource type of the resource to associate the decision for this menu choice with. May be null
.
* Possible values for this could be "com.ibm.mashups.enabler.space.SpaceNode", "com.ibm.mashups.iwidget.widget.IWidgetDefinition", "com.ibm.mashups.enabler.navigation.NavigationNode",
* or any other type used by an extension.
* @param {Object} someObject this allows an arbitrary object to be passed into the context menu loader in case it needs additional data for making the decisions.
* @return an array of items conforming to the {@link com.ibm.mashups.builder.model.ContextMenuItem ContextMenuItem}
* format that are retrieved by this loader; never null
.
*/
_initItems: function(/*String*/contextMenuId, /*String*/ targetResourceId, /*String*/ targetResourceType, /*Object*/ someObject){
// entry trace
var m = "_initItems(contextMenuId, targetResourceId, targetResourceType, someObject)";
if (this._isTracing) {
this.traceEntry(m, [contextMenuId, targetResourceId, targetResourceType, someObject]);
}
var ret = [];
var hasEditorAccess = this._config.hasPageEditorRights();
dojo.forEach(this.actions, function(actionDef){
if (hasEditorAccess) {
var localized = new com.ibm.cp.DojoLocalized({
bundlePackage: actionDef.bundlePackage,
bundleName: actionDef.bundleName,
bundleKey: actionDef.bundleKey
});
ret.push({
localized: localized,
ordinal: actionDef.ordinal,
enabled: actionDef.enabled,
id: actionDef.id,
actionCallBackFunction: this[actionDef.actionMethod]
});
}
}, this);
if (this._isTracing) {
this.traceExit(m, ret);
}
return ret;
},
launchContentMappingPickerDialog: function(){
// summary:
// Launches the content mapping picker dialog for adding, deleting and
// modifying content mappings for the current page.
// entry trace
var m = "launchContentMappingPickerDialog()";
if (this._isTracing) {
this.traceEntry(m);
}
dojo["require"]("com.ibm.wps.contentmapping.widget.CMPickerDialogWidget");
dojo["require"]("com.ibm.wps.contentmapping.dialog.ContentMappingPickerDialog");
var cmPickerWidget = new com.ibm.wps.contentmapping.widget.CMPickerDialogWidget();
var thedialog = new com.ibm.wps.contentmapping.dialog.ContentMappingPickerDialog({"widgetInstance":cmPickerWidget});
thedialog.show();
// workaround for layout bug: re-layout the dialog after it's really displayed
var timer = window.setTimeout(function()
{
if (thedialog.domNode && thedialog.domNode.style.display != "none") {
thedialog.layout();
}
window.clearTimeout(timer);
}, 1);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
}
});
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.dialog.EntitySelectDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.dialog.EntitySelectDialog"] = true;
/** ****************************************************************** */
/* Licensed Materials - Property of IBM */
/* */
/* 5724Z67 */
/* */
/* Copyright IBM Corp. 2011 All Rights Reserved. */
/* */
/* US Government Users Restricted Rights - Use, duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/** ****************************************************************** */
dojo.provide("com.ibm.wps.contentmapping.dialog.EntitySelectDialog");
dojo.require("dojo.i18n");
dojo.require('com.ibm.widgets.ResourceSelectDialog');
dojo.require("dojox.atom.io.model");
dojo.require("dojox.atom.io.Connection");
dojo.declare("com.ibm.wps.contentmapping.dialog.EntitySelectDialog",
[com.ibm.widgets.ResourceSelectDialog],
{
// _CMInterfaceMessagesBundle: [private] Object
// Messagebundle of the ContentMapping Picker dialog
_CMInterfaceMessagesBundle: null,
// _scopeProviderSettings: [private] Object
// Object which holds the configuration settings passed in to the constructor, so they
// can be used for setting up properties in postMixInProperties()
_scopeProviderSettings: {},
// _maxTooltipWidth: [private] String
// Maximum width of a tooltip as a CSS style value. We concatenate the style="max-width: " string
// when we set the Tooltip label and can neither use integer values here nor dojo.style to set
// the width. Advantage of this approach is that we can use px or em.
_maxTooltipWidth: '550px',
constructor: function(/*Object*/ p_params) {
// summary:
// Receives a few additional properties for making this instance of the dialog
// generic with regards to which entities to load from where and how to interpret
// the returned JSON object for finding entries.
//
// p_params:
// JSON object with the following properties
// feedQueryUrl:
// schemaPrefix:
// scopeProvider:
// getEntries:
//
// tags:
// public
this._scopeProviderSettings = p_params;
if (p_params && p_params.selectedResourceId) {
this.selectedResourceId = p_params.selectedResourceId;
}
},
postMixInProperties: function() {
this.inherited(arguments);
this._CMInterfaceMessagesBundle = dojo.i18n.getLocalization("com.ibm.wps.contentmapping", "ContentMappingPickerUserInterface");
// override the UI dialog strings
this.nlsResourceSelectTitle = this._CMInterfaceMessagesBundle.CMEntityPickerDialogTitles[this._scopeProviderSettings.scopeProvider].title;
this.nlsPersonLabel = this.dialogBundle.template_dialog_owned_by;
this.nlsNoUser = this.dialogBundle.template_dialog_no_owner;
this.nlsResourceTableSummary = this.dialogBundle.template_dialog_table_summary;
this.nlsSearchResourcesLabel = this._CMInterfaceMessagesBundle.CMEntityPickerDialogTitles[this._scopeProviderSettings.scopeProvider].searchlabel;
this.nlsNoResults = this._CMInterfaceMessagesBundle.CMEntityPickerDialogTitles[this._scopeProviderSettings.scopeProvider].noResults;
this.nlsTypeLabels = {
"PRIVATE": this._CMInterfaceMessagesBundle.CMProviderLabels[this._scopeProviderSettings.scopeProvider].labelPrivate,
"PUBLIC_INVITE_ONLY": this._CMInterfaceMessagesBundle.CMProviderLabels[this._scopeProviderSettings.scopeProvider].labelPublicPrivate,
"PUBLIC": ""
};
this.nlsSearchTooltip = '
' +
this._CMInterfaceMessagesBundle.CMEntityPickerDialogTitles[this._scopeProviderSettings.scopeProvider].searchTooltip +
'';
this.searchCssClass = "CMPickerHelpIcon";
this.feedQueryUrl = this._scopeProviderSettings.feedQueryUrl;
},
// Override to use our processing methods and strings
_populateResourceSelector: function () {
var aNode = this.resourceSelector;
this.selectorWidget = new com.ibm.widgets.ResourceSelector({
feedQueryUrl: this.feedQueryUrl,
atomFeed: false,
entryStartIndex: 1, // skip over first entry as it should be parent page templates node, we want the rest
//_getUserDataForEntry: this._getUserDataForEntry,
_processEntryResultsBeforeStoring: dojo.partial(this._processEntryResultsBeforeStoring, this._scopeProviderSettings),
_getEntriesFromJsonFeed: dojo.partial(this._getEntriesFromJsonFeed, this._scopeProviderSettings),
getAvailableResourcesCount: this.getAvailableResourcesCount,
getMaxResourcesCount: this.getMaxResourcesCount,
feedQueryUrlTemplate: this._scopeProviderSettings.feedQueryUrlTemplate,
feedSupportsSearch: this._scopeProviderSettings.feedSupportsSearch,
feedSearchParam: this._scopeProviderSettings.feedSearchParam,
warningIconClass: "CMPickerWarningIcon",
showTruncationMessage: this._scopeProviderSettings.showTruncationMessage,
nlsTruncationMsg: this._CMInterfaceMessagesBundle.CMEntityPickerDialog.warningResultsTruncatedMsg,
nlsSearchTooltip: this.nlsSearchTooltip,
searchCssClass: this.searchCssClass,
nlsPersonLabel: this.nlsPersonLabel,
nlsNoUser: this.nlsNoUser,
nlsResourceTableSummary: this.nlsResourceTableSummary,
nlsSearchResourcesLabel: this.nlsSearchResourcesLabel,
nlsNoResources: this.nlsNoResults,
nlsTypeLabels: this.nlsTypeLabels,
selectedResourceId: this.selectedResourceId
},aNode);
},
/* getAvailableResourcesCount: function(Object resData) {
var value = resData ? (resData.itemsListed ? parseInt(resData.itemsListed) : 0) : 0;
console.log("getAvailableResourcesCount = ", value);
return value;
},
getMaxResourcesCount: function(Object resData) {
var value = resData ? (resData.totalResults ? parseInt(resData.totalResults) : 0) : 0;
console.log("getMaxResourcesCount = ", value);
return value;
},
*/
getAvailableResourcesCount: function(/*Object*/ resData) {
if (resData && resData.itemsListed) {
if (dojo.isString(resData.itemsListed)) {
return parseInt(resData.itemsListed, 10);
} else {
return resData.itemsListed;
}
} else {
return 0;
}
},
getMaxResourcesCount: function(/*Object*/ resData) {
if (resData && resData.totalResults) {
if (dojo.isString(resData.totalResults)) {
return parseInt(resData.totalResults, 10);
} else {
return resData.totalResults;
}
} else {
return 0;
}
},
_getEntriesFromJsonFeed: function(scopeProviderSettings, feedUrl) {
// summary:
// Queries the JSON feed and then examines the entries returned to gather the
// title, description, id for a resource.
// A call is made to _processEntryResultsBeforeStoring
// for subclassess to manipulate the entry before storing the data.
// Subclasses can override these functions to perform specific functions needed
// to handle the atom entries for a particular resource type.
var dataArray = this.resourceData;
var me = this;
var resourceList = null;
var getResourceHandler = dojo.xhrGet( {
url: feedUrl,
sync: true,
handleAs: "json",
preventCache: true,
headers: {"X-Pragma":"admin"},
load: function(data){
resourceList = data;
},
error: function(error){
console.debug("ResourceSelector _getEntriesFromJsonFeed ERROR");
console.debug(error);
}
});
if (resourceList) {
var resourceEntries = resourceList;
// resourceList contains the data returned by the server, now we pass that along
// to the getNumXxx methods to figure out whether a truncation of results has
// occurred
var availableResults = this.getAvailableResourcesCount(resourceList);
var maxResults = this.getMaxResourcesCount(resourceList);
if (maxResults > availableResults) {
this._showTruncationMsgDiv(availableResults, maxResults);
} else {
this._hideTruncationMsgDiv();
}
// ask the scopeProvider configuration for the exact location of the entries
// within the returned JSON object
if (dojo.isFunction(scopeProviderSettings.getEntries)) {
resourceEntries = scopeProviderSettings.getEntries(resourceList);
}
if (resourceEntries) {
var rData = this.resourceData;
var selectedId = this.selectedResourceId;
dojo.forEach (resourceEntries, function(entry) {
var ctr = dataArray.length;
var _id = entry.id;
var _selected = false;
// has a prior selection been made at all?
if (selectedId && selectedId.length > 0 ) {
_selected = (selectedId === _id);
}
// no, then just default to the first child as being selected
else if (ctr === 0) {
_selected = true;
}
var _title = entry.title;
var _description = entry.description;
if (_description === null) {
_description = "";
}
var _owner = entry.owner;
var _ownerId = entry.ownerId;
var _type = entry.type;
var data = {id:_id, title:_title, description:_description, user:_owner, ownerId:_ownerId, selected:_selected, type:_type};
var processEntryData = dojo.hitch(me, me._processEntryResultsBeforeStoring);
data = processEntryData(data);
dataArray[ctr] = data;
});
}
}
},
// Override to clean up the id data associated with a template atom entry
_processEntryResultsBeforeStoring: function(scopeProviderSettings, data){
if (data) {
var _id = data.id;
if (scopeProviderSettings && scopeProviderSettings.schemaPrefix && dojo.isString(scopeProviderSettings.schemaPrefix)) {
// get id, strip off schema
data.id = this._stripOffPrefix(_id, scopeProviderSettings.schemaPrefix);
}
// set selection
var selectedId = this.selectedResourceId;
var _selected = false;
// has a prior selection been made at all?
if (selectedId && selectedId.length > 0 && (selectedId === _id)) {
data.selected = true;
}
}
return data;
}
}
);
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.utils.CMDialogLauncher"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.utils.CMDialogLauncher"] = true;
/** ****************************************************************** */
/* Licensed Materials - Property of IBM */
/* */
/* 5724Z67 */
/* */
/* Copyright IBM Corp. 2011 All Rights Reserved. */
/* */
/* US Government Users Restricted Rights - Use, duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/** ****************************************************************** */
dojo.provide("com.ibm.wps.contentmapping.utils.CMDialogLauncher");
dojo.registerModulePath("com.ibm.wps.contentmapping.utils.", "../com/ibm/wps/contentmapping/utils");
dojo.require("com.ibm.widgets._Traceable");
dojo.require("ibm.toolbar.ModalDialog");
dojo.declare("com.ibm.wps.contentmapping.utils.CMDialogLauncher",
[com.ibm.widgets._Traceable], {
// summary:
// Provides helper methods for either launching the Community
// picker dialog or the WCM Authoring UI based Picker
// _CMInterfaceMessagesBundle: [private] Object
// Messagebundle of the ContentMapping Picker dialog
_CMInterfaceMessagesBundle: null,
// _WCMDialogTitle: [private] String
// Localized title for the WCM Content Item picker dialog
_WCMDialogTitle: "",
// _entitySelectDlgDeferredList: [private] dojo.DeferredList object
// DeferredList used to synchronize onChange and onConfirm events being thrown by the
// EntitySelectDialog. Need a global variable, to avoid having multiple DeferredLists
// piling up in memory, when users open the dialog and cancelling it multiple times
// without ever pressing the OK button.
_entitySelectDlgDeferredList: null,
// _pickerConfig: [private] Object
// [com.ibm.wps.contentmapping.utils.CMPickerConfig] instance
_pickerConfig: null,
constructor: function(){
// summary:
// Constructs an object instance
// tags:
// public
// set instance trace support flag
this._isTracing = this.isTracing();
// entry trace
var m = "constructor()";
if (this._isTracing) {
this.traceEntry(m);
}
this._CMInterfaceMessagesBundle = dojo.i18n.getLocalization("com.ibm.wps.contentmapping", "ContentMappingPickerUserInterface");
this._pickerConfig = new com.ibm.wps.contentmapping.utils.CMPickerConfig();
this._WCMDialogTitle = this._CMInterfaceMessagesBundle.CMEntityPickerDialogTitles[com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDER_WCM].title;
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
launchEntitySelectDialog: function(/*Object*/ p_params) {
// summary:
// Creates a [com.ibm.wps.contentmapping.dialog.EntitySelectDialog] instance
// and shows the dialog for picking a mapping target
//
// p_params:
// JSON object with the following properties
// "scopeProvider": String Identifier of the scopeProvider this dialog is being launched for.
// For example ibm.wcm.provider or ibm.community.provider. The function
// passes along configuration data registered for this scopeProvider in
// [com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDERS] to
// the EntitySelectDialog.
// "onComplete": Function (Callback) which will be called by the EntitySelectDialog
// when the user confirms (clicking the OK button) the dialog.
// Returns an Object with the following properties about the selected item
// resourceValue: String ObjectID of the selected item
// resourceName: String Title of the selected item
// resourceDescription: String Description of the selected item
// resourcePath: String Path to the selected item
// scopeProvider: String Identifier of the related scopeProvider
// "onCancel": Function (Callback) which will be called by the EntitySelectDialog
// when the user cancels the dialog (by clicking 'Cancel' or pressing Escape)
// "selectedResourceId": String The id to pre-select when opening the dialog.
// tags:
// public
// entry trace
var m = "launchEntitySelectDialog(p_params)";
if (this._isTracing) {
this.traceEntry(m, dojo.toJson(p_params));
}
var providerCfgSettings = com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDERS[p_params.scopeProvider];
providerCfgSettings.selectedResourceId = p_params.selectedResourceId;
// verify all mandatory properties are defined
if (providerCfgSettings &&
providerCfgSettings.feedQueryUrl &&
providerCfgSettings.scopeProvider &&
dojo.isFunction(providerCfgSettings.getEntries)) {
var dlg = new com.ibm.wps.contentmapping.dialog.EntitySelectDialog(providerCfgSettings);
var deferreds = [];
if (p_params.onComplete && dojo.isFunction(p_params.onComplete)) {
var deferredOnChange = new dojo.Deferred();
dojo.connect(dlg, "onChange", null, dojo.hitch(this,
dojo.partial(
function(/*String*/ p_scopeProvider, /*Object*/ p_deferred, /*Object*/ p_args) {
if (p_args) {
p_args.scopeProvider = p_scopeProvider;
}
p_deferred.callback(p_args);
},
providerCfgSettings.scopeProvider,
deferredOnChange
)
)
);
deferreds.push(deferredOnChange);
// onChange needs to be bound to a context already (dojo.hitch(this, onChange))
var deferredOnSubmit = new dojo.Deferred();
dojo.connect(dlg, "onSubmit", null, dojo.hitch(this,
dojo.partial(
function(/*Object*/ p_deferred, /*Object*/ p_args) {
p_deferred.callback(p_args);
},
deferredOnSubmit
)
)
); // onComplete needs to be bound to a context already (dojo.hitch(this, onComplete))
deferreds.push(deferredOnSubmit);
this._entitySelectDlgDeferredList = new dojo.DeferredList(deferreds);
this._entitySelectDlgDeferredList.addCallback(
dojo.hitch(this, function(/*Array*/ p_results) {
// the first entry in the array holds the result of the onChange deferred callback and this is the one we're
// interested in for passing it along to the onComplete Event handler
// p_results[0][0] contains a boolean telling us whether the deferred has
// returned with a success message. So usually, this value is true here.
// we're only interested in the actual result object living in p_results[0][1]
// this is what was passed in by the deferred.callback(args) as the args object
p_params.onComplete(p_results[0][1]);
}
)
);
}
if (p_params.onCancel && dojo.isFunction(p_params.onCancel)) {
dojo.connect(dlg, "cancel", null, p_params.onCancel); // onCancel needs to be bound to a context already (dojo.hitch(this, onCancel))
}
// on the generic ResourceSelectDialog, there's a focus() method, which calls show() + does
// some steps to focus the first available element within the dialog. That's important, especially
// when calling this dialog from within another dialog, because otherwise the focus stays on
// the calling dialog.
if (dlg.focus) {
dlg.focus();
} else {
// fallback
dlg.show();
}
} else {
if (providerCfgSettings &&
providerCfgSettings.scopeProvider) {
// special WCM case handling
if (providerCfgSettings.scopeProvider == com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDER_WCM) {
// use WCM launch method for bringing up the WCM Authoring UI dialog
this._launchWCMPickerDialog(p_params);
}
}
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_launchWCMPickerDialog: function(/*Object*/ p_params) {
// summary:
// Launches the WCM Authoring UI based Picker dialog to pick a WCM content item to
// map to.
//
// As launching this dialog, is considered being a special case, this function is not
// meant to be called directly. Therefore, it's a private method.
//
// p_params:
// JSON object with the following properties
// "onComplete": Function (Callback) which will be called by the EntitySelectDialog
// when the user confirms (clicking the OK button) the dialog.
// Returns an Object with the following properties about the selected item
// resourceValue: String ObjectID of the selected item
// resourceName: String Title of the selected item
// resourceDescription: String Description of the selected item
// resourcePath: String Path to the selected item
// scopeProvider: String Identifier of the related scopeProvider
// "onCancel": Function (Callback) which will be called by the WCM Select Dialog
// when the user cancels the dialog (by clicking 'Cancel' or pressing Escape)
// tags:
// private
// entry trace
var m = "_launchWCMPickerDialog(p_params)";
var currentProjectUUID = ibm.toolbar.ProjectSupport.getCurrentProjectUUID();
if (this._isTracing) {
this.traceEntry(m, dojo.toJson(p_params));
this.traceEntry(m, currentProjectUUID);
}
var wcmDialogUrl = "?uri=dialog:wcm&view=folder";
if (currentProjectUUID) {
wcmDialogUrl = wcmDialogUrl + "&projectId=" + currentProjectUUID;
}
// use ModalDialog to launch the WCM Picker dialog
var modalDlg = new ibm.toolbar.ModalDialog();
modalDlg.open(wcmDialogUrl,
dojo.hitch(this, function(/*String*/ actionLabel, /*Array*/ selectedItems) {
if (selectedItems === null) {
// dialog was closed or cancelled
if (p_params.onCancel && dojo.isFunction(p_params.onCancel)) {
p_params.onCancel();
}
} else {
// trigger onChange and onComplete callback functions in sequence
// to mimic the behavior of the EntitySelectDialog for calling
// code
if (p_params.onComplete && dojo.isFunction(p_params.onComplete)) {
// dojo.isArray() doesn't work here, as Array was created in another
// window (see dojo documentation for dojo.isArrayLike)
if (selectedItems && dojo.isArrayLike(selectedItems)) {
// if there are multiple results, return only the id of
// the first one
if (selectedItems.length > 0) {
var itemID = selectedItems[0].selectedId;
// get more information about the selected item
var infoDef = this._getAdditionalInfoForContentItem(itemID);
infoDef.addCallback(
dojo.partial(
dojo.hitch(this, function(selectedItem, additionalData) {
// build the object with return values
var itemData = {
"resourceValue": selectedItem.selectedId,
"resourceName": additionalData.title,
"resourceDescription": additionalData.desc,
"resourcePath": selectedItem.displayTitle,
"scopeProvider": com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDER_WCM
};
p_params.onComplete(itemData);
}
),
selectedItems[0]
)
);
infoDef.addErrback(
dojo.partial(
dojo.hitch(this, function(selectedItem, error) {
// build the object with reduced set of
// values, as we couldn't get additional info
var itemData = {
"resourceValue": selectedItem.selectedId,
"resourcePath": selectedItem.displayTitle,
"scopeProvider": com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDER_WCM
};
p_params.onComplete(itemData);
}
),
selectedItems[0]
)
);
}
}
}
}
}
),
this._WCMDialogTitle
);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_getAdditionalInfoForContentItem: function(/*String*/ p_contentItemID) {
// summary:
// Runs an XHRGet request against the WCM JSON datasource to gather
// more detailed information about a WCM Content Item identified by
// p_contentItemID.
//
// Returns a dojo.Deferred object, whose callback will pass on the
// resulting JSON object with the properties returned by the server.
//
// p_contentItemID:
// ObjectID of the content item to gather information about
// returns:
// dojo.Deferred callback(item_properties)
//
// tags:
// private
// entry trace
var m = "_getAdditionalInfoForContentItem(p_contentItemID)";
if (this._isTracing) {
this.traceEntry(m, p_contentItemID);
}
var deferredToReturn = new dojo.Deferred();
var wcmUrl = this._pickerConfig.addParamToURL(this._pickerConfig.getMyContentHandlerBaseUrl(), "uri", "wcm:oid:" + p_contentItemID);
wcmUrl = this._pickerConfig.addParamToURL(wcmUrl, "mode", "download");
wcmUrl = this._pickerConfig.addParamToURL(wcmUrl, "view", "summary");
wcmUrl = this._pickerConfig.addParamToURL(wcmUrl, "prop", "desc");
wcmUrl = this._pickerConfig.addParamToURL(wcmUrl, "prop", "title");
var xhrArgs = {
url: wcmUrl,
handleAs: "json",
headers: {"X-Pragma":"admin"},
load: function(data, ioArgs) {
deferredToReturn.callback(data, ioArgs);
},
error: function(error, ioArgs) {
deferredToReturn.errback(error, ioArgs);
}
};
dojo.xhrGet(xhrArgs);
// exit trace
if (this._isTracing) {
this.traceExit(m, deferredToReturn);
}
return deferredToReturn;
}
});
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.widget.CMPickerPageWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.widget.CMPickerPageWidget"] = true;
/** ****************************************************************** */
/* Licensed Materials - Property of IBM */
/* */
/* 5724Z67 */
/* */
/* Copyright IBM Corp. 2011 All Rights Reserved. */
/* */
/* US Government Users Restricted Rights - Use, duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/** ****************************************************************** */
dojo.provide("com.ibm.wps.contentmapping.widget.CMPickerPageWidget");
dojo.registerModulePath("com.ibm.wps.contentmapping.widget.", "../com/ibm/wps/contentmapping/widget");
dojo.require("dojo.string");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.Tooltip");
dojo.require("dijit._Templated");
dojo.require("com.ibm.widgets._Traceable");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.CheckBox");
dojo.require("dojox.html.entities");
dojo.declare("com.ibm.wps.contentmapping.widget.CMPickerPageWidget", [dijit.layout.ContentPane, dijit._Templated, com.ibm.widgets._Traceable], {
// summary:
// This widget is consumed by the
// [com.ibm.wps.contentmapping.widget.CMPickerDialogWidget] widget
// namespace: [protected] String
// The namespace this widget uses for building its user interface elements
namespace: "CMPickerPageWidget",
// templateString:
// see dijit.Dialog
templateString:"\n",
// the space reserved for a vertical scrollbar of a page widget (child) in px
placeForVerticalScrollbar: 0,
// the space reserved for a horizontal scrollbar of a page widget (child) in px
placeForHorizontalScrollbar: 0,
// boolean indicating if membership integration is enabled for the widget's scopeprovider or not
membershipIntegrationEnabled: false,
// widgetsInTemplate: [protected] Boolean
// see dijit._Templated
widgetsInTemplate: true,
// blankImgUrl: Object
// URL pointing to a blank image (1x1 transparent pixel)
blankImgUrl: dojo.moduleUrl("dojo", "resources/blank.gif").toString(),
_acDelegateTableHeaderColumn: null,
// _acHelpIcon: [private] DomNode
// DomNode for the AC Delegation Column Help Icon
_acHelpIcon: null,
// _defaultHelpIcon: [private] DomNode
// DomNode for the Default Column Help Icon
_defaultHelpIcon: null,
// _membershipHelpIcon: [private] DomNode
// DomNode for the membership integration checkbox Help Icon
_membershipHelpIcon: null,
_defaultTableHeaderColumn: null,
// _errorState: [private] Boolean
// Indicates whether an error occurred and whether this widget went into error state.
// The error state persists, until _clearError() was called.
_errorState: false,
// _propagationCheckbox: [private] dijit.form.CheckBox
// Reference to the propagationCheckbox, if available for this scope provider. null otherwise.
_propagationCheckbox: null,
// _membershipIntgCheckbox: [private] dijit.form.CheckBox
// Reference to the membershipIntgCheckbox, if available for this scope provider. null otherwise.
_membershipIntgCheckbox: null,
// scopeprovider:
// the scopeprovider to use for this page
_scopeprovider: null,
// row selected because of containing the default mapping
_selectedRow: null,
// description row selected because of describing the default mapping
_selectedDescription: null,
// _nlsMessages: [private] Object
// Object holding localized strings used for providing localized messages
_nlsMessages: {},
// _nlsUserInterface: [private] Object
// Object holding localized strings used for providing localized user interface elements
_nlsUserInterface: {},
// the initial minimal size of this wiget's marginBox.
_initialMinSize: {
"w": 100,
"h": 50
},
// _eventHandlers: [private] Array
// Array of handlers created when connecting events to methods
_eventHandlers: [],
// array of contentmappings currently managed by this widget, each modified entry has a dirty=true flag
_managedMappings: [],
// _mappingToUIMap: [private] Object
// Object holding UI element references for any managedMapping being displayed by the dialog.
// The key (property name) equals the mapping's ID and the value is another JSON object with domNode References
_mappingToUIMap: {},
// _maxTooltipWidth: [private] String
// Maximum width of a tooltip as a CSS style value. We concatenate the style="max-width: " string
// when we set the Tooltip label and can neither use integer values here nor dojo.style to set
// the width. Advantage of this approach is that we can use px or em.
_maxTooltipWidth: '550px',
// array of child widgets that will be destroyed when closing the dialog
_initializedWidgets: [],
// labels specific to the provider of this instance
_providerlabels: null,
/* ****************************************************************************
* PUBLIC METHODS - LIFECYCLE
* ****************************************************************************/
constructor: function(/*Object*/p_params) {
// summary:
// Constructs this widget
// p_params: Object
// The arguments for initializing this widget
// tags:
// public
// set instance trace support flag
this._isTracing = this.isTracing();
// entry trace
var m = "constructor(p_params)";
if(this._isTracing) {
this.traceEntry(m);
if(p_params) {
this.trace(m, "p_params.scopeprovider:", dojo.toJson(p_params.scopeprovider));
this.trace(m, "p_params.pageName:", p_params.pageName);
}
}
// reset some global variables
this._acDelegateTableHeaderColumn = null;
this._defaultTableHeaderColumn = null;
this._propagationCheckbox = null;
this._membershipIntgCheckbox = null;
this._scopeprovider = p_params.scopeprovider;
this._nlsMessages = p_params.nlsMessages;
this._nlsUserInterface = p_params.nlsUserInterface;
this._managedMappings = this._managedMappings
.concat(dojo.filter(p_params.scopeprovider.contentmappings, function(mapping){return mapping.isSystem === true;}))
.concat(dojo.filter(p_params.scopeprovider.contentmappings, function(mapping){return mapping.isSystem !== true;}));
if(this._nlsUserInterface) {
// init common labels
this.nlsTableSummary = this._nlsUserInterface[this.namespace].table_summary;
this.nlsClickToSelect = this._nlsUserInterface[this.namespace].strClickToSelect;
this.nlsClickToDelete = this._nlsUserInterface[this.namespace].strClickToDelete;
this.nlsUseParentButton = this._nlsUserInterface[this.namespace].useParentButtonDefault;
var pageName = p_params.pageName;
// init provider specific labels
if(this._scopeprovider && this._scopeprovider.name) {
this._providerlabels = this._nlsUserInterface.CMProviderLabels[this._scopeprovider.name];
this.title = this._providerlabels.title;
this.nlsNoMappings = this._providerlabels.noMappings;
this.nlsLegend = this._providerlabels.legend;
this.nlsHeader = dojo.string.substitute(this._providerlabels.header, [pageName]);
this.nlsPickerButton = this._providerlabels.pickerButton;
this.nlsLaunchItemManageUI = this._providerlabels.labelLaunchItemManageUI || "";
this.nlsPickerButtonTooltip = this._providerlabels.pickerButtonTooltip;
// Change label of picker button if only one mapping is supported, and this already exists
if(!this._scopeprovider.supportsMultipleMappings && this._scopeprovider.contentmappings && this._scopeprovider.contentmappings.length > 0) {
this.nlsPickerButton = this._providerlabels.pickerButtonReplace;
}
} else {
if(this._isTracing) {
this.error(m, "Scopeprovider not set or name not available");
}
}
} else {
if(this._isTracing) {
this.error(m, "NLS data not available");
}
}
// default
this.inherited(arguments);
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
postCreate: function() {
// summary:
// Binds resources required by this widget after its template DOM has been set up.
// tags:
// protected
// entry trace
var m = "postCreate()";
if(this._isTracing) {
this.traceEntry(m);
}
this._createUseParentButton();
// display 'Launch connections UI link'
if (this._scopeprovider.manageItemsURL) {
this._enableManageItemsLink();
}
var mappings = this._managedMappings;
if(mappings && mappings.length > 0) {
var parent = this.CMPickerPageWidgetTableBody;
// clear out old rows if there
this._removeAllChildNodes(parent);
this._createTableHeaders();
this._preProcessSystemDefaultMappings(mappings);
// add table rows for each resource found
dojo.forEach(mappings, function(entry, i) {
this._createTableEntry(entry, i);
}, this);
}
this._createMembershipIntegrationCheckbox();
this._initEventHandlers();
// default
this.inherited(arguments);
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
startup: function() {
this._createTopologyPropagationCheckbox(this._scopeprovider.childPropagationCount, this._scopeprovider.pagePropagationLevels);
this._createHelpTooltips();
},
/* ****************************************************************************
* PUBLIC METHODS - SIZING
* ****************************************************************************/
changeSize: function(changeSize, p_placeForHorizontalScrollbar, p_placeForVerticalScrollbar) {
// summary:
// Resizes this widget to the given size, by setting it's
// domNode's marginBox. Also the size of this widget's container node
// gets layouted.
// tags:
// public
// entry trace
var m = "changeSize()";
if(this._isTracing) {
this.traceEntry(m, dojo.toJson(changeSize));
}
dojo.marginBox(this.domNode, {
"w": changeSize.w,
"h": changeSize.h
});
this.placeForHorizontalScrollbar = p_placeForHorizontalScrollbar;
this.placeForVerticalScrollbar = p_placeForVerticalScrollbar;
this.layout();
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
layout: function() {
// summary:
// Widgets override this method to size and position their contents/children.
// When this is called this._contentBox is guaranteed to be set (see resize()).
// This is called after the widget's size has been changed.
// tags:
// public
var m = "layout()";
if(this._isTracing) {
this.traceEntry(m);
}
var widthToSet = Math.max(dojo.marginBox(this.domNode).w, this._initialMinSize.w);
var heightToSet = Math.max(dojo.marginBox(this.domNode).h, this._initialMinSize.h);
// trace
if(this._isTracing) {
this.trace(m, "widthToSet:", widthToSet);
this.trace(m, "heightToSet:", heightToSet);
}
dojo.marginBox(this.containerNode, {
"w": widthToSet - this.placeForVerticalScrollbar,
"h": heightToSet - this.placeForHorizontalScrollbar
});
dojo.style(this.CMPickerPageWidgetFormContent, "height", "100%");
dojo.style(this.CMPickerPageWidgetTable, "width", "100%");
if(!dojo.isIE){
if (this.placeForVerticalScrollbar > 0){
dojo.style(this.CMPickerPageWidgetDiv, {"overflow-y": "auto", "overflowY": "auto"});
} else {
dojo.style(this.CMPickerPageWidgetDiv, {"overflow-y": "hidden", "overflowY": "hidden"});
}
if (this.placeForHorizontalScrollbar > 0){
dojo.style(this.CMPickerPageWidgetDiv, {"overflow-x": "auto", "overflowX": "auto"});
} else {
dojo.style(this.CMPickerPageWidgetDiv, {"overflow-x": "hidden", "overflowX": "hidden"});
}
}
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
getMinSize: function() {
// summary:
// Computes the minimal size this wiget's domNode needs for its marginBox.
// returns:
// The minimal size this wiget's domNode needs for its marginBox, e.g. {"w": minWidth, "h": minHeight}
// tags:
// private
var m = "getMinSize()";
if(this._isTracing) {
this.traceEntry(m);
}
// temporarily allow the containerNode content to fully expand
dojo.marginBox(this.containerNode, {
"w": 1000,
"h": 800
});
// allow contained elements to grow with their content
dojo.style(this.CMPickerPageWidgetTable, "width", "auto");
var minWidth = Math.max(dojo.marginBox(this.CMPickerPageWidgetTable).w, 600);
dojo.marginBox(this.containerNode, {
"w": minWidth,
"h": 800
});
dojo.style(this.CMPickerPageWidgetFormContent, "height", "auto");
var minHeight = Math.max(dojo.marginBox(this.CMPickerPageWidgetFormContent).h, 200);
// allow contained elements to grow with the dialog (for manual resize)
dojo.style(this.CMPickerPageWidgetFormContent, "height", "100%");
dojo.style(this.CMPickerPageWidgetTable, "width", "100%");
// return actual height and width of contained elements
var result = {
"w": minWidth,
"h": minHeight
};
// exit trace
if(this._isTracing) {
this.traceExit(m, dojo.toJson(result));
}
return result;
},
/* ****************************************************************************
* PUBLIC METHODS - GETTER
* ****************************************************************************/
getManagedMappings: function() {
// summary:
// Getter of the private property _managedMappings, which contains all managed, modified
// and new added mappings.
// returns: Array of mappings, for example:
// [{ id: "2349234",
// title: "Web Content/Articles",
// description: "All articles",
// scope: null,
// titlePath: null,
// isDefault: true,
// isSystem: false,
// isDelegating: false
// dirty: true }]
// tags:
// public
var m = "getManagedMappings()";
if(this._isTracing) {
this.traceEntry(m);
this.traceExit(m, dojo.toJson(this._managedMappings));
}
return this._managedMappings;
},
getScopeProviderName: function() {
// summary:
// Returns the scope provider name bound to this page widget.
// returns: String
// The scope provider name
// tags:
// public
var m = "getScopeProviderName()";
if(this._isTracing) {
this.traceEntry(m);
}
var result = this._scopeprovider.name;
if(this._isTracing) {
this.traceExit(m, result);
}
return result;
},
isMappingPropagationEnabled: function() {
// summary:
// Determines whether mapping propagation (to child pages) is enabled for the scope
// provider bound to this page, which is the case, if the following two conditions are true:
// - the scopeprovider supports topology propagations
// - the user has checked the checkbox for activating the topology propagation
// returns: Boolean
// true, if the conditions mentioned above are met, false otherwise
// tags:
// public
var m = "isMappingPropagationEnabled()";
if(this._isTracing) {
this.traceEntry(m);
}
var result;
if(this._scopeprovider.supportsTopologyOperations) {
// check for the propagation checkbox being available and checked
if(this._propagationCheckbox) {
result = this._propagationCheckbox.attr('checked') ? true : false;
// make sure the result is a boolean value
} else {
result = false;
}
} else {
result = false;
}
if(this._isTracing) {
this.traceExit(m, result);
}
return result;
},
hasMembershipIntegrationEnabled: function() {
// summary:
// Returns true if the membership integration flag has changed AND is true
// tags:
// public
var result = (this.membershipIntegrationEnabled && (this.membershipIntegrationEnabled !== this._scopeprovider.membershipIntegrationEnabled));
// exit trace
if(this._isTracing) {
this.traceExit("hasMembershipIntegrationEnabled");
}
return result;
},
hasMembershipIntegrationDisabled: function() {
// summary:
// Returns true if the membership integration flag has changed AND is false
// tags:
// public
var result = (!this.membershipIntegrationEnabled && (this.membershipIntegrationEnabled !== this._scopeprovider.membershipIntegrationEnabled));
// exit trace
if(this._isTracing) {
this.traceExit("hasMembershipIntegrationDisabled");
}
return result;
},
uninitialize: function() {
// summary:
// Releases the resources bound by this dialog before it is destroyed
// tags:
// protected
// entry trace
var m = "uninitialize()";
if(this._isTracing) {
this.traceEntry(m);
}
// remove all tooltips that were dynamically created
this._destroyHelpTooltips();
// disconnect the callbacks from their related events
this._clearEventHandlers();
dojo.forEach(this._initializedWidgets, function(widget) {
if(dojo.exists("destroyRecursive", widget)) {
widget.destroyRecursive();
}
});
// default
this.inherited(arguments);
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
/* ****************************************************************************
* EVENTS
* ****************************************************************************/
onChange: function() {
// summary:
// Callback stub, which is called whenever a mapping
// changed
},
onLayoutChange: function() {
// summary:
// Callback stub, which is called whenever this widget layout
// changed and therfore grew or shrunk.
},
onErrorStateChanged: function(/*Object*/p_sender, /*Boolean*/p_errorState, /*String*/p_errorMsg, /*String?*/p_errorDetails) {
// summary:
// Callback method that is triggered by this widget when an error condition
// occurred and the associated error message needs to be displayed in the
// owning dialog or if the widget was in error state previously and the
// error was cleared.
//
},
/* ****************************************************************************
* PRIVATE METHODS
* ****************************************************************************/
_createTableHeaders: function() {
// summary:
// Creates the table headers with individual labels for each scope provider
// tags:
// private
var m = "_createTableHeaders()";
if(this._isTracing) {
this.traceEntry(m);
}
if(this._scopeprovider && this._scopeprovider.name) {
// omit table headers if only name and delete colums are needed (makes it more clearly arranged)
if (this._scopeprovider.supportsAccessControlDelegation || this._scopeprovider.supportsMultipleMappings) {
var parent = this.CMPickerPageWidgetTableBody;
var tr = dojo.create("tr", {
className: "lotusFirst lotusSort"
}, parent);
if(this._scopeprovider.supportsMultipleMappings) {
var th1 = this._defaultTableHeaderColumn = dojo.create("th", {
id: this._scopeprovider.name + "_columnheader_default",
className: "lotusFirstCell CMPFirstCell CMPTableHeaderLabel CMPControlHeaderCell",
innerHTML: this._providerlabels.thIsDefault,
scope: "col"
}, tr);
}
var th3 = dojo.create("th", {
id: this._scopeprovider.name + "_columnheader_mapping",
className: "CMPTableHeaderLabel",
innerHTML: this._providerlabels.thMappingName,
scope: "col"
}, tr);
if(this._scopeprovider.supportsAccessControlDelegation) {
var th5 = this._acDelegateTableHeaderColumn = dojo.create("th", {
id: this._scopeprovider.name + "_columnheader_acdelegate",
className: "CMPTableHeaderLabel CMPControlHeaderCell",
innerHTML: this._providerlabels.thACDelegation,
scope: "col"
}, tr);
}
var th6 = dojo.create("th", {
id: this._scopeprovider.name + "_columnheader_delete",
className: "lotusLastCell CMPLastCell CMPTableHeaderLabel CMPControlHeaderCell",
innerHTML: this._providerlabels.thDelete,
scope: "col"
}, tr);
}
} else {
if(this._isTracing) {
this.error(m, "Scopeprovider not set or name not available");
}
return;
}
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
_createTableEntry: function(/*Object*/entry, /*Integer*/idx) {
// summary:
// Creates a table entry representing a mapping.
// entry:
// The entry data in format like:
// { id: "2349234",
// title: "Web Content/Articles",
// description: "All articles",
// scope: null,
// titlePath: null,
// isDefault: true,
// isSystem: false,
// isDelegating: false }
// idx:
// The index of the entry within the table
// tags:
// private
var m = "_createTableEntry()";
if(this._isTracing) {
this.traceEntry(m, dojo.toJson(entry), idx);
}
var parent = this.CMPickerPageWidgetTableBody;
var id = entry.id;
var direction = (entry.rtl ? "rtl" : "ltr");
var nlsText = this._nlsMessages.utils.noTitleLabel;
var nlsHoverText = entry.id;
var showWarningIcon = true;
if(dojo.isString(entry.title)) {
nlsText = entry.title;
nlsHoverText = nlsText;
// use title text as hover text, if available
showWarningIcon = false;
}
// will be undefined, if his information is missing, we'll assume that the target can be seen in this case
var canViewMappingTarget;
if(( typeof entry.warning) !== 'undefined') {
canViewMappingTarget = false;
// to be on the save side, reset nlsHoverText to id here
nlsHoverText = entry.id;
showWarningIcon = true;
} else {
canViewMappingTarget = true;
}
var columnCount = 4;
//default
var defaultCheckBox;
var deleteButton;
var delegationCheckBox;
/* ************ MAIN ROW ************** */
var tr1 = dojo.create("tr", {
id: "tr1_" + id
}, parent);
var td1 = dojo.create("td", {
className: "lotusFirstCell CMPFirstCell CMPControlCell"
}, tr1);
if(this._scopeprovider.supportsMultipleMappings) {
var defaultCheckBoxDiv = dojo.create("div", null, td1);
defaultCheckBox = new dijit.form.RadioButton({
name: "isDefault",
title: this._providerlabels.thIsDefault,
value: id,
checked: ((typeof entry.isDefault) == 'undefined' ? false : entry.isDefault),
id: id + "_default_association_" + idx,
className: "lotusCheckbox",
onChange: dojo.hitch(this, this._changeMapping, id, entry.scope, "isDefault")
}, defaultCheckBoxDiv);
// remember for cleanup
this._initializedWidgets.push(defaultCheckBox);
}
var td3 = dojo.create("td", {
tabindex: "0",
className: "CMPCell",
"aria-describedby": id + "_label_" + idx
}, tr1);
var td3span = dojo.create("span", {
className: "CMPCell"
}, td3);
var warningAltText = this._nlsMessages.utils.noTitleAvailableTitle;
// show warning icon, if title of this entry could not be retrieved (because either the mapping target was deleted
// or
// the user has no view rights)
if(canViewMappingTarget === false) {
// set displayed title text to noTitleAvailable msg
nlsText = this._nlsMessages.utils.noTitleAvailableLabel;
}
if(showWarningIcon) {
// use warning message sent by the server, instead of
// generic msg, if it is available
if(dojo.isString(entry.warning) && (entry.warning !== "")) {
warningAltText = entry.warning;
}
// only if this is really 'false', do nothing if it's just undefined or 'not true'
var warningSpan = dojo.create("span", {
id: id + "_warning_span_" + idx,
className: "CMPickerWarningIcon",
title: warningAltText
}, td3span);
dojo.create("img", {
id: id + "_warning_img_" + idx,
className: " CMPickerIcon24",
src: this.blankImgUrl,
alt: warningAltText
}, warningSpan);
}
var titleSpan = dojo.create("span", {
lang: entry.locale,
dir: direction,
id: id + "_label_" + idx,
className: "CMPMappingLabel CMPCell" + (entry.isSystem ? " CMPSystemMappingCell" : ""),
innerHTML: dojox.html.entities.encode(nlsText),
title: nlsHoverText,
"aria-label": nlsText
}, td3span);
if (entry.type && entry.type !== "PUBLIC" ) {
dojo.create("span", {
className: "lotusType",
innerHTML: (entry.type === "PRIVATE" ? this._providerlabels.labelPrivate : this._providerlabels.labelPublicPrivate)
}, titleSpan);
}
if(this._scopeprovider.supportsAccessControlDelegation) {
columnCount++;
var td5 = dojo.create("td", {
className: "CMPControlCell"
}, tr1);
var delegationCheckBoxDiv = dojo.create("div", null, td5);
delegationCheckBox = new dijit.form.CheckBox({
name: "isDelegating",
value: id,
title: this._providerlabels.thACDelegation,
checked: entry.isDelegating ? entry.isDelegating : false,
id: id + "_association_delegates_" + idx,
className: "CMPCell lotusCheckbox",
onChange: dojo.hitch(this, this._changeMapping, id, entry.scope, "isDelegating")
}, delegationCheckBoxDiv);
this._initializedWidgets.push(delegationCheckBox);
}
var td6 = dojo.create("td", {
className: "lotusLastCell CMPLastCell CMPControlCell"
}, tr1);
if(!entry.isSystem) {
var delDiv = dojo.create("td", null, td6);
deleteButton = new dijit.form.Button({
baseClass: "dijitButton deleteButton CMPCellBtnCell",
showLabel: false,
tooltip: this.nlsClickToDelete,
title: this.nlsClickToDelete,
alt: this._nlsUserInterface[this.namespace].altDeleteImg,
iconClass: "deleteIcon"
}, delDiv);
this._initializedWidgets.push(deleteButton);
this._eventHandlers.push(dojo.connect(deleteButton, "onClick", this, function() {
this._deleteMapping(id, entry.scope);
}));
}
/* *************************************** */
/* ************ DETAILS ROW (WCM only) *** */
if(this._scopeprovider.name === com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDER_WCM) {
dojo.style(td3, "paddingBottom", "0px");
var tr2 = dojo.create("tr", {
id: "tr2_" + id,
className: "lotusDetails"
}, parent);
var td_detail1 = dojo.create("td", {
className: "lotusFirstCell CMPFirstCell CMPDetailsCell",
innerHTML: " "
}, tr2);
var td_detail3 = dojo.create("td", {
className: "lotusLastCell CMPDetailsCell",
colSpan: (columnCount - 2).toString()
}, tr2);
var hasTitlePath = entry.titlePath && entry.titlePath !== "";
if(entry.isSystem) {//special case for WCM managed pages
var span_IsSystem = dojo.create("span", {
className: "isSystemText lotusLeft",
innerHTML: this._providerlabels.isSystemText,
dir: ( (((typeof ibmCfg) !== 'undefined') && ((typeof ibmCfg.themeConfig) !== 'undefined') && ibmCfg.themeConfig.isRTL) ? "rtl" : "ltr" )
}, td_detail3);
if(hasTitlePath) {
var span_separator = dojo.create("span", {
className: "detailsText divider lotusLeft",
innerHTML: " | "
}, td_detail3);
}
}
var span_details;
if(!hasTitlePath) {
span_details = dojo.create("span", {
className: "detailsText lotusLeft ",
innerHTML: " "
}, td_detail3);
} else {
var fragments = entry.titlePath.split("/");
// pathes are always ltr, only their fragments may not
span_details = dojo.create("span", {
className: "detailsText lotusLeft path",
dir: "ltr"
}, td_detail3);
dojo.forEach(fragments, function(fragment, idx) {
if (fragment && fragment.length > 0){
dojo.create("span", {
lang: entry.locale,
dir: direction,
innerHTML: fragment
}, span_details);
if(idx < (fragments.length - 1)) {
dojo.create("span", {
dir: direction,
innerHTML: " / "
}, span_details);
}
}
});
}
}
/* *************************************** */
/* ******** DESCRIPTION ROW ************** */
var description = entry.description;
if(!description || description === "") {
description = " ";
}
dojo.style(td3, "paddingBottom", "0px");
var tr3 = dojo.create("tr", {
id: "tr3_" + id,
className: "lotusDetails"
}, parent);
var td_desc1 = dojo.create("td", {
className: "lotusFirstCell CMPFirstCell CMPCell",
innerHTML: " "
}, tr3);
var td_desc3 = dojo.create("td", {
className: "lotusLastCell CMPLastCell CMPCell",
colSpan: (columnCount - 2).toString()
}, tr3);
var div_desc = dojo.create("div", {
lang: entry.locale,
dir: direction,
className: "descriptionText",
innerHTML: description
}, td_desc3);
if (dojo.isIE){
dojo.style(td_desc3, "width", "auto");
}
/* *************************************** */
/* ********** ACCESSIBILITY ************** */
if(defaultCheckBox) {
dojo.attr(defaultCheckBox.focusNode, "role", "checkbox");
dojo.attr(defaultCheckBox.focusNode, "aria-describedby", id + "_label_" + idx);
}
if(delegationCheckBox) {
dojo.attr(delegationCheckBox.focusNode, "role", "checkbox");
dojo.attr(delegationCheckBox.focusNode, "aria-describedby", id + "_label_" + idx);
}
if(deleteButton) {
dojo.attr(deleteButton.focusNode, "aria-describedby", id + "_label_" + idx);
dojo.attr(deleteButton.focusNode, "aria-label", this._nlsUserInterface[this.namespace].altDeleteImg);
}
/* *************************************** */
// connect entry with it's UI artifacts, so we can easily access them later on
dojo.setObject(entry.id + ".ui.row", tr1, this._mappingToUIMap);
dojo.setObject(entry.id + ".ui.defaultRadioButton", defaultCheckBox, this._mappingToUIMap);
if(!this._scopeprovider.supportsMultipleMappings || entry.isDefault) {
// the background color call has to be made here after the description row gets added
this._setSelectedRowBackgroundColor(tr1);
}
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
_createTopologyPropagationCheckbox: function(/*Integer*/p_numChildPages, /*Integer*/p_numLevels) {
// summary:
// Dynamically creates a checkbox widget that allows the user to switch mappings propagation
// to child pages on. Checkbox is unchecked by default.
// p_numChildPages: Integer
// Max. number of child pages that will get the mapping(s) of the current page assigned to them.
// Will be displayed as part of the checkbox label.
// p_numLevels: Integer
// Max. number of child page levels the mappings will be applied to. A value of 0 means all
// child levels will be affected (unlimited).
// returns: Boolean
// true, if the checkbox was created and placed into the DomTree successfully, false otherwise
// tags:
// private
var m = "_createTopologyPropagationCheckbox(p_numChildPages, p_numLevels)";
if(this._isTracing) {
this.traceEntry(m, [p_numChildPages, p_numLevels]);
}
var result = false;
if(this._scopeprovider.supportsTopologyOperations && p_numChildPages > 0) {
var htmlTemplateChildCount = "${0}";
var htmlTemplateLevelCount = "${0}";
// assume the default message
var nlsLabel = this._providerlabels.labelCopyToAllDirectChildren;
var htmlLabel = null;
var childCount;
if(p_numLevels === "1") {
nlsLabel = this._providerlabels.labelCopyToAllDirectChildren;
if(nlsLabel) {
childCount = dojo.string.substitute(htmlTemplateChildCount, [p_numChildPages]);
htmlLabel = dojo.string.substitute(nlsLabel, [childCount]);
}
} else {
if(p_numLevels === "0") {
nlsLabel = this._providerlabels.labelCopyToAllChildPages;
if(nlsLabel) {
childCount = dojo.string.substitute(htmlTemplateChildCount, [p_numChildPages]);
htmlLabel = dojo.string.substitute(nlsLabel, [childCount]);
}
} else {
// level is neither 0 nor 1
nlsLabel = this._providerlabels.labelCopyToChildPagesUpToLevel;
if(nlsLabel) {
childCount = dojo.string.substitute(htmlTemplateChildCount, [p_numChildPages]);
var levelCount = dojo.string.substitute(htmlTemplateLevelCount, [p_numLevels]);
htmlLabel = dojo.string.substitute(nlsLabel, [childCount, levelCount]);
}
}
}
if(!htmlLabel) {
// if nlsLabel is not available for this scopeprovider, assume the feature is not supported
// and don't display the checkbox at all
result = false;
} else {
this._removeAllChildNodes(this.propagateToChildrenDIV);
var mappingExists = this._managedMappings && this._managedMappings.length > 0;
var widgetDiv = dojo.create("div", null, this.propagateToChildrenDIV);
var textSpan = dojo.create("span", {
"id": this.namespace + "_" + this._scopeprovider.name + "_propagationCheckboxLabel",
"innerHTML": htmlLabel
}, this.propagateToChildrenDIV);
// the checkbox will turn widgetDiv DIV tag we created above into it's domNode (everything
// else gets removed)
this._propagationCheckbox = new dijit.form.CheckBox({
"name": this.namespace + "_" + this._scopeprovider.name + "_propagationCheckbox",
"id": this.namespace + "_" + this._scopeprovider.name + "_propagationCheckboxID",
"checked": false,
"showLabel": true,
"disabled": !mappingExists,
"tabIndex": "0"
}, widgetDiv);
// make DIV with the new checkbox visible
dojo.removeClass(this.propagateToChildrenDIV, "lotusHidden");
// add accessibility
if(this._propagationCheckbox) {
dojo.attr(this._propagationCheckbox.focusNode, "role", "button");
dojo.attr(this._propagationCheckbox.focusNode, "aria-describedby", this.namespace + "_" + this._scopeprovider.name + "_propagationCheckboxLabel");
}
this._initializedWidgets.push(this._propagationCheckbox);
result = true;
}
}
// exit trace
if(this._isTracing) {
this.traceExit(m, result);
}
},
_createMembershipIntegrationCheckbox: function() {
// summary:
// Dynamically creates a checkbox widget that allows the user to switch on/off the membership
// integration. "On" means that all members of the mapped entity (e.g. community) will also get
// access to the page contents.
// returns: Boolean
// true, if the checkbox was created and placed into the DomTree successfully, false otherwise
// tags:
// private
var m = "_createMembershipIntegrationCheckbox()";
if(this._isTracing) {
this.traceEntry(m);
}
var result = false;
if(this._scopeprovider.supportsMembershipIntegration) {
// set the initial state of this property retrieved from the JSON feed
this.membershipIntegrationEnabled = this._scopeprovider.membershipIntegrationEnabled;
var nlsLabel = this._providerlabels.labelEnableMembershipIntegration;
if(!nlsLabel) {
// if nlsLabel is not available for this scopeprovider, assume the feature is not supported
// and don't display the checkbox at all
result = false;
} else {
this._removeAllChildNodes(this.membershipIntegrationDIV);
var mappingExists = this._managedMappings && this._managedMappings.length > 0;
var widgetDiv = dojo.create("div", null, this.membershipIntegrationDIV);
var textSpan = dojo.create("span", {
"id": this.namespace + "_" + this._scopeprovider.name + "_membershipIntgCheckboxLabel",
"innerHTML": nlsLabel,
"style": { color: (!this._scopeprovider.allowedToChangeMembershipIntegration || !mappingExists) ? "gray" : "black" }
}, this.membershipIntegrationDIV);
// the checkbox will turn widgetDiv DIV tag we created above into it's domNode (everything
// else gets removed)
this._membershipIntgCheckbox = new dijit.form.CheckBox({
"name": this.namespace + "_" + this._scopeprovider.name + "_membershipIntgCheckbox",
"id": this.namespace + "_" + this._scopeprovider.name + "_membershipIntgCheckboxID",
"checked": this._scopeprovider.membershipIntegrationEnabled,
"showLabel": true,
"disabled": !this._scopeprovider.allowedToChangeMembershipIntegration || !mappingExists,
"tabIndex": "0",
"onChange": dojo.hitch(this, this._callbackMembershipIntegrationCheckboxClick)
}, widgetDiv);
// make DIV with the new checkbox visible
dojo.removeClass(this.membershipIntegrationDIV, "lotusHidden");
// add accessibility
if(this._membershipIntgCheckbox) {
dojo.attr(this._membershipIntgCheckbox.focusNode, "role", "button");
dojo.attr(this._membershipIntgCheckbox.focusNode, "aria-describedby", this.namespace + "_" + this._scopeprovider.name + "_membershipIntgCheckboxLabel");
}
this._initializedWidgets.push(this._membershipIntgCheckbox);
result = true;
}
}
// exit trace
if(this._isTracing) {
this.traceExit(m, result);
}
},
_createUseParentButton: function() {
// summary:
// Displays/Hides the "Use association from parent page" button depending on if
// the scopeprovider supports topology operations. Enables/Disables the
// "Use association from parent page" button depending on if the parent page has
// a default mapping or not.
// tags:
// private
// entry trace
var m = "_createUseParentButton()";
if(this._isTracing) {
this.traceEntry(m);
}
// init the use-default-mapping-from-parent-page button if the scope provider supports topology operations
if(this._scopeprovider.supportsTopologyOperations) {
dojo.attr(this.useParentButton, "title", this._providerlabels.useParentButtonNoMappingTooltip);
dijit.setWaiState(this.useParentButton, "label", this._providerlabels.useParentButtonNoMappingTooltip);
this.useParentButton.style.display = '';
var parentMappings = this._scopeprovider.parentcontentmappings;
if(parentMappings) {
var parentDefaultMappings = dojo.filter(parentMappings, function(mapping) {
return (mapping.isDefault && mapping.isDefault === true && mapping.scope === this._scopeprovider.primaryScope);
}, this);
if(parentDefaultMappings && parentDefaultMappings.length > 0) {
dojo.attr(this.useParentButton, "disabled", false);
dojo.removeClass(this.useParentButton, "lotusBtnDisabled");
dijit.setWaiState(this.useParentButton, "disabled", false);
if(parentDefaultMappings[0].title) {
//tooltip
var titleLabel = dojo.string.substitute(this._providerlabels.useParentButtonTooltip, [parentDefaultMappings[0].title]);
dojo.attr(this.useParentButton, "title", titleLabel);
dijit.setWaiState(this.useParentButton, "label", titleLabel);
var shortTitle = parentDefaultMappings[0].title.length > 25 ? parentDefaultMappings[0].title.substr(0, 25).concat("...") : parentDefaultMappings[0].title;
dojo.empty(this.useParentButton);
// "Use "...
dojo.create("span", {
innerHTML: this._nlsUserInterface[this.namespace].useParentButton
}, this.useParentButton);
// + title of parent page's default mapping
dojo.create("span", {
lang: parentDefaultMappings[0].locale,
dir: parentDefaultMappings[0].rtl ? "rtl" : "ltr",
innerHTML: "\"" + shortTitle + "\""
}, this.useParentButton);
} else {
//default tooltip if parent mapping does not have a title
dojo.attr(this.useParentButton, "title", this.nlsUseParentButton);
dijit.setWaiState(this.useParentButton, "label", this.nlsUseParentButton);
}
}
}
}
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
_addMapping: function(/*Object*/selectedEntity, /*Boolean*/ enableMembershipIntegration) {
// summary:
// Function called whenever a table entry should be added. It adds the mapping specified at
// selectedEntity to this._managedMappings and sets its dirty flag to true and its isNew flag to true.
// selectedEntity:
// The selected entity, which is an object with the following properties:
// resourceValue
// resourceName
// resourceDescription
// resourcePath
// tags:
// private
var m = "_addMapping()";
if(this._isTracing) {
this.traceEntry(m, selectedEntity);
}
var mappingWasAdded = false;
var mappingExisted = this._managedMappings && this._managedMappings.length > 0;
if(selectedEntity.resourceValue && selectedEntity.resourceValue.length > 0) {
// detect duplicate mapping here and don't add duplicate mappings + show error message
// a duplicate is found, when id + scope of the selectedEntity match the id + scope of
// an already existing mapping in _managedMappings
if(dojo.some(this._managedMappings, function(entry) {
return ((entry.id === selectedEntity.resourceValue) && (entry.scope === selectedEntity.resourceScope));
})) {
this._showError(this._nlsMessages.pickerPageWidget.errorDuplicateMapping);
} else if(this._scopeprovider.supportsMultipleMappings) {
this._managedMappings.push({
id: selectedEntity.resourceValue,
title: selectedEntity.resourceName,
locale: selectedEntity.locale,
rtl: selectedEntity.rtl,
description: selectedEntity.resourceDescription,
scope: this._scopeprovider.primaryScope,
titlePath: selectedEntity.resourcePath,
isDefault: (!mappingExisted || selectedEntity.isDefault),
isSystem: selectedEntity.isSystem,
isDelegating: selectedEntity.isDelegating,
warning: selectedEntity.warning,
type: selectedEntity.type
});
mappingWasAdded = true;
} else {
this._managedMappings = [{
id: selectedEntity.resourceValue,
title: selectedEntity.resourceName,
locale: selectedEntity.locale,
rtl: selectedEntity.rtl,
description: selectedEntity.resourceDescription,
scope: this._scopeprovider.primaryScope,
titlePath: selectedEntity.resourcePath,
isDefault: true,
isSystem: selectedEntity.isSystem,
isDelegating: selectedEntity.isDelegating,
warning: selectedEntity.warning,
type: selectedEntity.type
}];
mappingWasAdded = true;
}
}
if(mappingWasAdded) {
// in these cases we do a table clear before adding the new mapping
if(!mappingExisted || !this._scopeprovider.supportsMultipleMappings) {
var parent = this.CMPickerPageWidgetTableBody;
// clear help tooltip references
this._acDelegateTableHeaderColumn = null;
this._defaultTableHeaderColumn = null;
// clear out old rows if there
this._removeAllChildNodes(parent);
this._createTableHeaders();
this._createHelpTooltips();
// enable checkboxes
if (this._propagationCheckbox) {
this._propagationCheckbox.set("disabled", false);
}
}
// check if user is allowed to change the membership integration
if(this._membershipIntgCheckbox && this._scopeprovider.allowedToChangeMembershipIntegration) {
dojo.byId(this.namespace + "_" + this._scopeprovider.name + "_membershipIntgCheckboxLabel").style.color = "black";
this._membershipIntgCheckbox.set("disabled", false);
if(enableMembershipIntegration && selectedEntity.type === "PRIVATE") {
this._membershipIntgCheckbox.set("checked", true);
dojo.addClass(this._membershipIntgCheckbox.domNode.parentNode, "greenBkgr");
this.membershipIntegrationEnabled = true;
} else {
dojo.removeClass(this._membershipIntgCheckbox.domNode.parentNode, "greenBkgr");
this._membershipIntgCheckbox.set("checked", false);
this.membershipIntegrationEnabled = false;
}
}
// now add the new row
this._createTableEntry(this._managedMappings[this._managedMappings.length - 1], this._managedMappings.length - 1);
// call onChange for callbacks
this.onChange();
this.onLayoutChange();
}
// exit trace
if(this._isTracing) {
if(mappingWasAdded) {
this.trace(m, "Updated _managedMappings:", dojo.toJson(this._managedMappings));
} else {
this.trace(m, "Duplicate mapping not added: ", dojo.toJson(selectedEntity));
}
this.traceExit(m);
}
},
_changeMapping: function(/*String*/p_mappingId, /*String*/p_scope, /*String*/p_name, /*String*/p_value) {
// summary:
// Function called whenever a table entry was modified. It modifies the respective mapping, which
// is contained at this._managedMappings and sets its dirty flag to true.
// p_mappingId:
// The entity id the page is mapped to and which mapping was modified.
// p_scope:
// The scope of the mapping which was modified.
// p_name:
// The name of the mapping's attribute which was modified.
// p_value:
// The new value which was set for the mapping's attribute.
// tags:
// private
var m = "_changeMapping()";
if(this._isTracing) {
this.traceEntry(m, [p_mappingId, p_scope, p_name, p_value]);
}
this._property = {};
dojo.setObject("_property." + p_name, p_value, this);
if(this._managedMappings && this._managedMappings.length > 0) {
dojo.forEach(this._managedMappings, function(entry, i) {
if(entry.id === p_mappingId && (!p_scope || entry.scope === p_scope)) {
var oldIsDefaultValue = entry.isDefault;
dojo.mixin(entry, this._property);
var newIsDefaultValue = entry.isDefault;
if((newIsDefaultValue != oldIsDefaultValue) && (newIsDefaultValue === true)) {
// make sure the row of this entry is shown selected
var tableRow = dojo.getObject(entry.id + ".ui.row", false, this._mappingToUIMap);
this._setSelectedRowBackgroundColor(tableRow);
}
}
}, this);
// call onChange for callbacks
this.onChange();
}
// exit trace
if(this._isTracing) {
this.trace(m, "Updated _managedMappings:", dojo.toJson(this._managedMappings));
this.traceExit(m);
}
},
_deleteMapping: function(/*String*/p_mappingId, /*String*/p_scope) {
// summary:
// Function called whenever a table entry should be deleted. It deletes the respective mapping, which
// is contained at this._managedMappings and puts the mapping id to this._deletedMappings if it wasn't
// a new, unsaved mapping.
// p_mappingId:
// The entity's id the page is mapped to and which mapping should be deleted.
// p_scope:
// The scope of the mapping which should be deleted.
// tags:
// private
var m = "_deleteMapping()";
if(this._isTracing) {
this.traceEntry(m, [p_mappingId, p_scope]);
}
if(this._managedMappings && this._managedMappings.length > 0) {
this._managedMappings = dojo.filter(this._managedMappings, function(entry) {
return (entry.id !== p_mappingId || (entry.scope !== p_scope));
});
}
// update _mappingToUIMap, by clearing the UI object for the deleted entry
dojo.setObject(p_mappingId, {}, this._mappingToUIMap);
// delete the table entry
var mappingFirstRow = dojo.byId("tr1_" + p_mappingId);
var mappingSecondRow = dojo.byId("tr2_" + p_mappingId);
var mappingThirdRow = dojo.byId("tr3_" + p_mappingId);
if(mappingFirstRow) {
dojo.destroy(mappingFirstRow);
}
if(mappingSecondRow) {
dojo.destroy(mappingSecondRow);
}
if(mappingThirdRow) {
dojo.destroy(mappingThirdRow);
}
//destroy all widgets that are related to this association
dojo.forEach(this._initializedWidgets, function(widget) {
if(widget.id && widget.id.indexOf(p_mappingId)>-1) {
widget.destroyRecursive();
}
});
//check if we need to create the "empty" table row
if(this._managedMappings && this._managedMappings.length < 1) {
// clear help tooltip references
this._acDelegateTableHeaderColumn = null;
this._defaultTableHeaderColumn = null;
var parent = this.CMPickerPageWidgetTableBody;
// clear out header row if there
this._removeAllChildNodes(parent);
var emptyRow = dojo.create("tr", null, this.CMPickerPageWidgetTableBody);
var emptyCell = dojo.create("td", {
tabindex: "0",
className: "lotusFirstCell noMappingsCell CMPCell",
"aria-describedby": this.id + "_noMappingSpan"
}, emptyRow);
var emptyText = dojo.create("span", {
className: "CMPMappingLabel",
id: this.id + "_noMappingSpan",
innerHTML: dojox.html.entities.encode(this.nlsNoMappings)
}, emptyCell);
// disable checkboxes
if (this._propagationCheckbox) {
this._propagationCheckbox.set("disabled", true);
}
if (this._membershipIntgCheckbox) {
dojo.byId(this.namespace + "_" + this._scopeprovider.name + "_membershipIntgCheckboxLabel").style.color = "gray";
this._membershipIntgCheckbox.set("disabled", true);
this._membershipIntgCheckbox.set("checked", false);
dojo.removeClass(this._membershipIntgCheckbox.domNode.parentNode, "greenBkgr");
this.membershipIntegrationEnabled = false;
}
}
// now, fixup the default entry (if it was deleted, select a new one)
if(this._scopeprovider.supportsMultipleMappings) {
this._autoSelectDefaultMapping();
}
// call onChange for callbacks
this.onChange();
this.onLayoutChange();
// exit trace
if(this._isTracing) {
this.trace(m, "Updated _managedMappings:", dojo.toJson(this._managedMappings));
this.traceExit(m);
}
},
_autoSelectDefaultMapping: function() {
// summary:
// Determines whether a default mapping is set or not within _managedMappings and
// auto selects a new default (usually the first entry in the list), if it is
// missing. No change is made to the default, if there's already a default mapping
// set.
//
// Use only, if multiple mappings are supported.
//
// tags:
// private
var m = "_autoSelectDefaultMapping()";
if(this._isTracing) {
this.traceEntry(m);
}
var isDefaultMappingSet = dojo.some(this._managedMappings, function(mapping) {
return (mapping.isDefault === true);
});
if(!isDefaultMappingSet) {
if(this._managedMappings.length > 0) {
var newDefaultMapping = this._managedMappings[0];
var tableRow = dojo.getObject(newDefaultMapping.id + ".ui.row", false, this._mappingToUIMap);
var defaultRadioButton = dojo.getObject(newDefaultMapping.id + ".ui.defaultRadioButton", false, this._mappingToUIMap);
newDefaultMapping.isDefault = true;
this._setSelectedRowBackgroundColor(tableRow);
if(defaultRadioButton) {
defaultRadioButton.attr('checked', true);
}
}
}
if(this._isTracing) {
this.traceExit(m);
}
},
_createHelpTooltips: function() {
// summary:
// Creates various help icons across the page, which are used to show onHover tooltips
// with HTML markup support
// tags:
// private
var m = "_createHelpTooltips()";
if(this._isTracing) {
this.traceEntry(m);
}
if(this._defaultTableHeaderColumn) {
this._defaultHelpIcon = this._createHelpIcon(this._defaultTableHeaderColumn, this._scopeprovider.name + "_columnheader_default_helpIcon", this._nlsUserInterface.CMPickerPageWidget.defaultBtnTooltip);
}
if(this._acDelegateTableHeaderColumn) {
this._acHelpIcon = this._createHelpIcon(this._acDelegateTableHeaderColumn, this._scopeprovider.name + "_columnheader_acdelegate_helpIcon", this._nlsUserInterface.CMPickerPageWidget.acDelegateBtnTooltip);
}
if(this._membershipIntgCheckbox && !dojo.byId(this._scopeprovider.name + "_membershipIntg_helpIcon")) {
this._membershipHelpIcon = this._createHelpIcon(this.membershipIntegrationDIV, this._scopeprovider.name + "_membershipIntg_helpIcon", this._providerlabels.enableMembershipIntegrationTooltip);
}
if(this._propagationCheckbox && !dojo.byId(this._scopeprovider.name + "_propagateToChildren_helpIcon")) {
this._propagateToChildrenHelpIcon = this._createHelpIcon(this.propagateToChildrenDIV, this._scopeprovider.name + "_propagateToChildren_helpIcon", this._providerlabels.propagateToChildrenTooltip);
}
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
_destroyHelpTooltips: function() {
// summary:
// Creates various help icons across the page, which are used to show onHover tooltips
// with HTML markup support
// tags:
// private
var m = "_destroyHelpTooltips()";
if(this._isTracing) {
this.traceEntry(m);
}
// destroy all help icons that are still there
if(this._defaultHelpIcon) {
this._defaultHelpIcon.destroy();
delete this._defaultHelpIcon;
}
if(this._acHelpIcon) {
this._acHelpIcon.destroy();
delete this._acHelpIcon;
}
if(this._membershipHelpIcon) {
this._membershipHelpIcon.destroy();
delete this._membershipHelpIcon;
}
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
_createHelpIcon: function(/*DomNode*/p_parentNode, /*String*/p_id, /*String*/p_helpString) {
// summary:
// Creates a help icon below the given parentNode. The icon related nodes (a, img) will be
// added via dojo.place("last") into the parent domNode.
// p_parentNode: DomNode
// DomNode where the help node will be placed
// p_id: String
// ID for the new help icon domNode
// p_helpString: String
// Markup of the help being displayed in a dijit.Tooltip widget
// returns:
// The reference to the dijit.Tooltip that was created
// tags:
// private
var m = "_createHelpIcon(p_parentNode, p_id, p_helpString)";
if(this._isTracing) {
this.traceEntry(m, [p_parentNode, p_id, p_helpString]);
}
var anchor = dojo.create("a", {
"id": p_id,
"role": "button",
"href": "javascript:void(0);",
"class": "CMPickerHelpIcon"
}, p_parentNode);
var image = dojo.create("img", {
"src": this.blankImgUrl,
"alt": "",
"role": "presentation",
"width": "16",
"height": "16"
}, anchor);
var span = dojo.create("span", {
"class": "lotusAltText",
"innerHTML": "?"
}, anchor);
var ttp = new dijit.Tooltip({
connectId: [p_id],
label: '' +
p_helpString +
'',
position: ["below"]
});
// add event handlers that will update the global WP dijit.Tooltip variable that
// is used to support ESCAPE key closing support for tooltips
this._eventHandlers.push(dojo.connect(ttp, "onShow", dojo.hitch(this, function(target) {
com.ibm.wps.contentmapping._currentTooltipNode = target;
})
));
this._eventHandlers.push(dojo.connect(ttp, "onHide", dojo.hitch(this, function() {
com.ibm.wps.contentmapping._currentTooltipNode = null;
})
));
// exit trace
if(this._isTracing) {
this.traceExit(m, ttp);
}
return ttp;
},
_enableManageItemsLink: function() {
// summary:
// Enables the Manage Items Link on the Picker Page instance (makes it visible, attaches onClick handler and optionally
// also adds a tooltip to it
//
// tags:
// private
var m = "_enableManageItemsLink()";
if(this._isTracing) {
this.traceEntry(m);
}
dojo.style(this.launchManageUrl, 'display', 'inline-block');
this._eventHandlers.push(dojo.connect(this.launchManageUrl, 'onclick', null, dojo.partial(this._openManageItemsUrl, this._scopeprovider.manageItemsURL)));
if (this._providerlabels.labelLaunchItemManageUITooltip) {
var tooltip = new dijit.Tooltip({
connectId: [this.launchManageUrl],
label: '' +
this._providerlabels.labelLaunchItemManageUITooltip +
'',
position: ["below"]
});
if (tooltip) {
this._initializedWidgets.push(tooltip);
}
}
if(this._isTracing) {
this.traceExit(m);
}
},
_setSelectedRowBackgroundColor: function(/*tr DOM element*/row) {
// summary:
// Highlights the background of a table row with a color, the
// CMPickerPageWidget.SELECTED_ROW_COLOR
// row:
// The table row to handle (tr DOM element)
// tags:
// private
// clear the background color on old selected rows
if(this._selectedRow) {
dojo.removeClass(this._selectedRow, "CMPSelectedRow");
}
if(this._selectedDetails) {
dojo.removeClass(this._selectedDetails, "CMPSelectedRow");
}
if(this._selectedDescription) {
dojo.removeClass(this._selectedDescription, "CMPSelectedRow");
}
// set the background on the new selection
dojo.addClass(row, "CMPSelectedRow");
this._selectedRow = row;
var detailsTableRow = row.nextSibling;
if(this._scopeprovider.name === com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDER_WCM) {
if(detailsTableRow && dojo.attr(detailsTableRow, "class") === "lotusDetails") {
dojo.addClass(detailsTableRow, "CMPSelectedRow");
this._selectedDetails = detailsTableRow;
row = detailsTableRow;
} else {
this._selectedDetails = null;
}
}
var descriptionTableRow = row.nextSibling;
if(descriptionTableRow && dojo.attr(descriptionTableRow, "class") === "lotusDetails") {
dojo.addClass(descriptionTableRow, "CMPSelectedRow");
this._selectedDescription = descriptionTableRow;
} else {
this._selectedDescription = null;
}
},
_preProcessSystemDefaultMappings: function(/*Array*/p_mappings) {
// summary:
// Scans through all given mappings and sets the system mapping (if available)
// as the default, if no other mapping has the default flag set to true.
// p_mappings: Array of Object
// An array of content mapping objects
// tags:
// private
var m = "_preProcessSystemDefaultMappings(p_node)";
// entry trace
if(this._isTracing) {
this.traceEntry(m, dojo.toJson(p_mappings));
}
var systemMapping = null;
var defaultMapping = null;
dojo.forEach(p_mappings, dojo.hitch(this, function(/*Object*/p_mapping) {
if((p_mapping.isSystem === true) && (!systemMapping)) {
systemMapping = p_mapping;
}
if(p_mapping.isDefault === true) {
defaultMapping = p_mapping;
}
}));
if((defaultMapping === null) && (systemMapping !== null)) {
if(this._isTracing) {
this.trace(m, "Setting the following system mapping as the new default: ", dojo.toJson(systemMapping));
}
systemMapping.isDefault = true;
}
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
_removeAllChildNodes: function(/*DomNode*/p_node) {
// summary:
// Removes all child nodes from beneath the given domNode. Makes sure that the given
// p_node has no children when this method completes.
// p_node: DomNode
// Parent node whose child nodes will all be removed
// tags:
// private
var m = "_removeAllChildNodes(p_node)";
if(this._isTracing) {
this.traceEntry(m, [p_node]);
}
if(p_node) {
var nodes = dojo.query("*", p_node);
if(nodes) {
// remove all nodes found below the given parent node
nodes.orphan();
}
}
if(this._isTracing) {
this.traceExit(m);
}
},
_showError: function(/*String*/p_errorMsg, /*String*/p_errorDetails) {
// summary:
// Sends the provided error message to a registered listener (could be a
// dialog) for display. Optionally, also sends a more detailed message
// for the error.
// p_errorMsg: String
// The error message to display
// p_errorDetails: String
// Optional string with a more detailed description of the error
// tags:
// protected
var m = "_showError(p_errorMsg, p_errorDetails)";
if(this._isTracing) {
this.traceEntry(m, [p_errorMsg, p_errorDetails]);
}
this._errorState = true;
// notify registered listeners of the error and have them e.g. display
// the error message + details
this.onErrorStateChanged(this, true, p_errorMsg, p_errorDetails);
if(this._isTracing) {
this.traceExit(m);
}
},
_clearError: function() {
// summary:
// Clears the error state (sets this._errorState to false) and notifies
// listeners of the changed error state
// tags:
// private
var m = "_clearError()";
if(this._isTracing) {
this.traceEntry(m);
}
this._errorState = false;
// notify registered listeners of the fact that we cleared the error
// no more parameters needed when clearing the error state
this.onErrorStateChanged(this, false);
if(this._isTracing) {
this.traceExit(m);
}
},
_initEventHandlers: function() {
// summary:
// Connects the events supported by this dialog to the corresponding callback methods
// and stores the Handlers in the _eventHandlers array
// tags:
// private
// entry trace
var m = "_initEventHandlers()";
if(this._isTracing) {
this.traceEntry(m);
}
if(this.pickerButton) {
this._eventHandlers.push(dojo.connect(this.pickerButton, "onclick", this, "_callbackPickerButtonClick"));
}
if(this.useParentButton) {
this._eventHandlers.push(dojo.connect(this.useParentButton, "onclick", this, "_callbackUseParentButtonClick"));
}
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
_clearEventHandlers: function() {
// summary:
// Disconnects the events supported by this dialog from the corresponding callback methods
// tags:
// private
// entry trace
var m = "_clearEventHandlers()";
if(this._isTracing) {
this.traceEntry(m);
}
dojo.forEach(this._eventHandlers, dojo.disconnect);
this._eventHandlers = [];
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
/* ****************************************************************************
* PRIVATE METHODS - CALLBACKS
* ****************************************************************************/
_callbackPickerButtonClick: function() {
// summary:
// Callback after the entity picker button was clicked. Launches the entity picker dialog
// tags:
// protected
// entry trace
var m = "_callbackPickerButtonClick()";
if(this._isTracing) {
this.traceEntry(m);
}
var listPickerLauncher = new com.ibm.wps.contentmapping.utils.CMDialogLauncher();
var defaultmapping = dojo.filter(this._managedMappings, function(mapping) {
return (mapping.isDefault && mapping.isDefault === true);
});
listPickerLauncher.launchEntitySelectDialog({
scopeProvider: this._scopeprovider.name,
selectedResourceId: (defaultmapping && defaultmapping[0]) ? defaultmapping[0].id : "undefined",
onComplete: dojo.hitch(this, function(item) {
this._addMapping(item, true);
}),
onCancel: dojo.hitch(this, function() {
this.onLayoutChange();
// triggers _fixResizeHelper on the parent dialog implicitly
})
});
this._initializedWidgets.push(listPickerLauncher);
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
_callbackUseParentButtonClick: function() {
// summary:
// Callback after the "Use association from parent page" button was clicked. Adds the default mapping
// of the parent page.
// tags:
// protected
// entry trace
var m = "_callbackUseParentButtonClick()";
if(this._isTracing) {
this.traceEntry(m);
}
var parentMappings = this._scopeprovider.parentcontentmappings;
if(parentMappings) {
var parentDefaultMappings = dojo.filter(parentMappings, function(mapping) {
return (mapping.isDefault && mapping.isDefault === true && mapping.scope === this._scopeprovider.primaryScope);
}, this);
if(parentDefaultMappings && parentDefaultMappings.length > 0) {
this._addMapping({
resourceValue: parentDefaultMappings[0].id,
resourceName: parentDefaultMappings[0].title,
resourceDescription: parentDefaultMappings[0].description,
resourcePath: parentDefaultMappings[0].titlePath,
resourceScope: parentDefaultMappings[0].scope,
locale: parentDefaultMappings[0].locale,
rtl: parentDefaultMappings[0].rtl,
isDefault: parentDefaultMappings[0].isDefault,
isSystem: parentDefaultMappings[0].isSystem,
isDelegating: parentDefaultMappings[0].isDelegating,
warning: parentDefaultMappings[0].warning,
type: parentDefaultMappings[0].type
}, false);
}
}
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
},
_callbackMembershipIntegrationCheckboxClick: function(/*String*/p_value) {
// summary:
// Toggles the property for membership integration. Called each time the checkbox is clicked
// tags:
// private
var m = "_createMembershipIntegrationCheckbox()";
if(this._isTracing) {
this.traceEntry(m);
}
this.membershipIntegrationEnabled = p_value === true ? true : false;
// exit trace
if(this._isTracing) {
this.trace(m, "Setting membershipIntegrationEnabled to ", this.membershipIntegrationEnabled);
this.traceExit(m);
}
},
_openManageItemsUrl: function(/*String*/ p_url) {
// summary:
// Opens a new browser window and navigates to the given URL there.
// tags:
// private
var m = "_openManageItemsUrl(p_url)";
if(this._isTracing) {
this.traceEntry(m, p_url);
}
window.open(p_url);
// exit trace
if(this._isTracing) {
this.traceExit(m);
}
}
});
com.ibm.wps.contentmapping.widget.CMPickerPageWidget.SELECTED_ROW_COLOR = "#f2f9ff";
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.utils.CMRESTServiceHelper"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.utils.CMRESTServiceHelper"] = true;
/** ****************************************************************** */
/* Licensed Materials - Property of IBM */
/* */
/* 5724Z67 */
/* */
/* Copyright IBM Corp. 2011 All Rights Reserved. */
/* */
/* US Government Users Restricted Rights - Use, duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/** ****************************************************************** */
dojo.provide("com.ibm.wps.contentmapping.utils.CMRESTServiceHelper");
dojo.registerModulePath("com.ibm.wps.contentmapping.utils.", "../com/ibm/wps/contentmapping/utils");
dojo.require("dojo.string");
dojo.require("com.ibm.data.Resolver");
dojo.require("com.ibm.data.resolver.NMPocHandler");
dojo.require("com.ibm.widgets._Traceable");
dojo.declare("com.ibm.wps.contentmapping.utils.CMRESTServiceHelper",
[com.ibm.widgets._Traceable], {
// _nlsMessages: [private] Object
// Object holding localized strings used for providing localized messages
_nlsMessages: {},
// _pickerConfig: [private] Object
// [com.ibm.wps.contentmapping.utils.CMPickerConfig] instance
_pickerConfig: null,
// _resolverStore: [private] Object
// Reference of the global Resolver store object from the ibmPortalCfg
// object
_resolverStore: null,
// summary:
// Provides methods for sending PUT and DELETE requests
// to the content mapping service (update/create and delete
// operations).
// PUBLIC section
constructor: function(/*Object*/ p_params){
// summary:
// Constructs an object instance
// p_params:
// Parameter object
// tags:
// public
// entry trace
var m = "constructor(p_params)";
// set instance trace support flag
this._isTracing = this.isTracing();
if (this._isTracing) {
this.traceEntry(m, p_params);
}
if (p_params && p_params.nlsMessages) {
this._nlsMessages = p_params.nlsMessages;
}
this._pickerConfig = new com.ibm.wps.contentmapping.utils.CMPickerConfig();
this._resolverStore = this._getResolverStore();
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
deleteContentMappingsForPage: function(/*Object*/ p_params) {
// summary:
// Deletes all provided content mappings for the given page.
//
// p_params:
// JSON object with the following properties:
// "pageID":
// "mappingsToDelete": Array of mappings that will be deleted. Each mapping (array element) is
// a string with the ObjectID of the content item
// returns:
// dojo.Deferred Can be used to add callbacks and errbacks
// tags:
// public
var i;
var mappings = p_params.mappingsToDelete; // Array
var deferredToReturn = new dojo.Deferred();
// keep track of the Deferred object from the next mapping in the queue
// Since the last mapping will trigger methods on the Deferred object that
// we return for this method, we'll start with this one.
var deferredOfNextMapping = deferredToReturn;
// walk through the mappings array from end to start, as we need to build the execution chain
// backwards, to let it run in the forward direction
for (i = mappings.length - 1; i >= 0; i--) {
var nextMappingDeferred = new dojo.Deferred();
var mapping = mappings[i];
var callbackFn = dojo.partial(function(pageID, mappingToDelete, deferred, data, ioArgs) {
// TODO: callback function receives OK results data (could be a server response) and we
// need to pass it along, so we can offer the deferredToReturn callback function
// an array with all the responses of each individual DELETE call
this._deleteContentMappingForPage({
"pageID": pageID,
"mappingToDelete": mappingToDelete
}, deferred);
}, p_params.pageID, mapping, deferredOfNextMapping);
nextMappingDeferred.addCallback(
dojo.hitch(this, callbackFn)
);
nextMappingDeferred.addErrback(
dojo.hitch(this, function(error, ioArgs) {
// trigger errback on the deferredToReturn object, as none of the other Deferreds
// will be used any more, once an error occurred
deferredToReturn.errback(error, ioArgs);
})
);
deferredOfNextMapping = nextMappingDeferred;
}
// start running the chained operations
deferredOfNextMapping.callback();
// return the initial Deferred object that will be triggered once all Deletes were successfully
// processed or when an error occured
return deferredToReturn;
},
getContentMappingsForPageAsJSON: function(/*String*/ p_pageID, /*String?*/ p_scopeProvider, /*Function?*/ p_errorCallback) {
// summary:
// Requests a JSON object with content mappings for the
// given page from the aggregated content mapping
// datasource by sending an GET request to the server.
// If given, the parameter p_scopeProvider can be used to restrict the
// result to an array of mapping for the given scopeProvider.
// If the parameter is omitted or null, a JSON object with an array
// of scopeProviders and below each entry another array of mappings
// will be returned.
//
// p_pageID:
// String ObjectID of the page whose mappings will be returned
//
// p_scopeProvider [optional]:
// String name of the scope provider to return mappings for, if not given
// or undefined, mappings for all scope providers will be returned
// p_errorCallback [optional]:
// Function callback function being called with parameters (error, ioArgs), whenever
// an xhr 'error' occurs. Unlike the errback() function on the Deferred object
// returned by this function, it will not only see the Javascript error
// generated by a failed XHR request, but also receive the ioArgs object
// returns:
// dojo.Deferred
// Depending on the presence of the p_scopeProvider, this method either
// returns a flat array of mappings for the given scopeProvider or a JSON
// object with an array of scopeProviders and an array of mappings below
// each scopeProvider entry as parameter to the Deferred.callback function
// tags:
// public
// entry trace
var m = "getContentMappingsForPageAsJSON(p_pageID, p_scopeProvider, p_errorCallback)";
if (this._isTracing) {
this.traceEntry(m, [p_pageID, p_scopeProvider, p_errorCallback]);
}
// public wrapper for private load method.
var deferredToReturn = this._loadContentMappingsForPageAsJSON(p_pageID, p_scopeProvider, p_errorCallback);
// exit trace
if (this._isTracing) {
this.traceExit(m, deferredToReturn);
}
return deferredToReturn;
},
getPageTitle: function(/*String*/ p_pageID, /*Boolean?*/ p_sync) {
// summary:
// Sends a remote XHR request against the NavigationModel REST API to get the
// title of the given page. Since this is an asynchronous call, the result is
// not returned immediately. The callback on the returned dojo.Deferred object
// can be used to receive the result.
//
// p_pageID:
// The OID of the page whose title needs to be retrieved
//
// p_sync: [optional]
// If set and true, the remote request will be a synchronous request that returns
// when the value was retrieved successfully from the server. If not set or false,
// the request will be allowed to run asynchronously and a dojo.Deferred object is
// returned
//
// returns:
// dojo.Deferred | String A dojo.Deferred object is returned, if p_syncRequest is missing or
// false, otherwise this method returns the pageTitle as a string
// tags:
// public
// entry trace
var m = "getPageTitle(p_pageID)";
if (this._isTracing) {
this.traceEntry(m, p_pageID);
}
// result for the synchronous version of this method
var result = "";
var deferredToReturn = new dojo.Deferred();
// adding our own local callback/errback functions to the deferred object to fill "result"
if (p_sync === true) {
deferredToReturn.addCallback(dojo.hitch(this, function(title) {
result = title;
}));
deferredToReturn.addErrback(dojo.hitch(this, function(error) {
result = this._nlsMessages.utils.noTitleLabel;
}));
}
if (!this._resolverStore) {
deferredToResult.errback(this._nlsMessages.utils.errorResolverNotAvail);
} else {
var query = {
uri: "nm:oid:" + p_pageID
};
this._resolverStore.fetch({
"query": query,
"onComplete": dojo.hitch(this, function(items, request) {
if (items.length <= 0) {
deferredToReturn.errback(dojo.string.substitute(this._nlsMessages.utils.errorPageNotFound, [p_pageID]));
} else {
var item = items[0];
var title = this._resolverStore.getValue(item, "title", "");
deferredToReturn.callback(title);
}
}
),
"sync": p_sync,
"queryOptions":{
"bypassBatch":true,
"additionalHeaders":{
"X-Pragma":"admin"
}
},
"scope": this
});
}
// if in async mode, replace result string with dojo.Deferred object we're going to return
if (p_sync !== true) {
result = deferredToReturn;
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
},
updateContentMappingsForPage: function(/*Object*/ p_params, /*String?*/ p_updateMode, /*Function?*/ p_errorCallback) {
// summary:
// Generates an Xml document for updating the given
// content mappings on the server and sends a PUT
// request with this Xml document to the server.
//
// p_params:
// JSON object with the following properties:
// "pageID": ID of the page whose mappings will be updated
// "mappingsToUpdate": Array of mappings that will be created/updated. Each mapping
// is represented by a JSON array with the following properties
// "id": String ObjectID of the content/community item to map to
// "isDefault": Boolean true, if the mapping should be the default for the page
// "isDelegating": Boolean true, if access control delegation should be enabled for this mapping
// "isSystem": Boolean true, if this is a system mapping that cannot be deleted
// "scope": String the scope to create the mapping in. Can be empty for WCM mappings
// "enablePropagation": Array of scopeProvider names for which the checkbox 'Propagate mappings
// to child pages' is checked. Omit those, that don't support propagation of don't have
// the checkbox checked.
// "disableMembershipIntegration": Array of scopeProvider names for which the checkbox 'Use community
// membership' is checked AND has changed. Omit those, that don't support membership integration.
// "enableMembershipIntegration": Array of scopeProvider names for which the checkbox 'Use community
// membership' is unchecked. Omit those, that don't support membership integration.
// p_updateMode: [optional]
// String either 'merge' or 'replace'. 'merge' adds new entries and updates existing ones, leaving all other
// mappings on the server untouched, while 'replace' creates/updates the mappings passed into this
// function and deletes all other mappings on the server. If this parameter is missing, the
// function assumes 'replace' as the default mode.
// p_errorCallback [optional]:
// Function callback function being called with parameters (error, ioArgs), whenever
// an xhr 'error' occurs. Unlike the errback() function on the Deferred object
// returned by this function, it will not only see the Javascript error
// generated by a failed XHR request, but also receive the ioArgs object
// returns:
// dojo.Deferred Can be used to add callbacks
// tags:
// public
// entry trace
var m = "updateContentMappingForPage(p_params, p_updateMode, p_errorCallback)";
if (this._isTracing) {
this.traceEntry(m, [dojo.toJson(p_params, p_updateMode, p_errorCallback)]);
}
var deferredToReturn = new dojo.Deferred();
var xmlDoc = this._getUpdateXmlDocument(p_params.pageID,
p_params.mappingsToUpdate);
var updateMode = "replace"; // assume a reasonable default (we'll usually never use 'merge' anyway)
if (p_updateMode && dojo.isString(p_updateMode)) {
if (p_updateMode == "merge") {
// make sure we only add known values to the URL, if the parameter is not merge,
// we'll go with the default value, which is replace
updateMode = p_updateMode;
}
}
var enablePropagation = null;
if (p_params.enablePropagation) {
enablePropagation = p_params.enablePropagation;
}
var disableMembershipIntegration = null;
if (p_params.disableMembershipIntegration && p_params.disableMembershipIntegration.length > 0) {
disableMembershipIntegration = p_params.disableMembershipIntegration;
}
var enableMembershipIntegration = null;
if (p_params.enableMembershipIntegration && p_params.enableMembershipIntegration.length > 0) {
enableMembershipIntegration = p_params.enableMembershipIntegration;
}
var xhrUrl = this._pickerConfig.getCMAtomDataSourceBaseUrl() + p_params.pageID;
xhrUrl = this._addSingleValueQueryParam(xhrUrl, "update", updateMode);
xhrUrl = this._addMultiValueQueryParam(xhrUrl, "enablePropagation" , enablePropagation);
xhrUrl = this._addMultiValueQueryParam(xhrUrl, "disableMembershipIntegration" , disableMembershipIntegration);
xhrUrl = this._addMultiValueQueryParam(xhrUrl, "enableMembershipIntegration" , enableMembershipIntegration);
var xhrArgs = {
url: xhrUrl,
postData: xmlDoc,
handleAs: "text",
headers: { "Content-Type": "application/atom+xml", "X-Pragma":"admin"},
load: function(data, ioArgs) {
deferredToReturn.callback(data, ioArgs);
},
error: function(error, ioArgs) {
if (p_errorCallback && dojo.isFunction(p_errorCallback)) {
p_errorCallback(error, ioArgs);
}
}
};
dojo.xhrPut(xhrArgs);
// exit trace
if (this._isTracing) {
this.traceExit(m, dojo.toJson(deferredToReturn));
}
return deferredToReturn;
},
// PRIVATE section
_addSingleValueQueryParam: function(/*String*/ p_url, /*String*/ p_key, /*String*/ p_value) {
// summary:
// Adds a single Url parameter key/value pair to the given URL and returns the result
//
// p_url: The URL to augment with the given key/value parameter pair. The Url is expected to
// already have a first parameter attached to it (?key=value), so the parameter pair
// given here, will be added as &p_key=p_value
// p_key: String Parameter key
// p_value: String Parameter value
//
// returns:
// String the initial Url with the attached key/value pair
// tags:
// private
// entry trace
var m = "_addSingleValueQueryParam(p_url, p_key, p_value)";
if (this._isTracing) {
this.traceEntry(m, [p_url, p_key, p_value]);
}
var result = p_url;
if (dojo.isString(p_url) && dojo.isString(p_value)) {
result = result.concat("&".concat(p_key).concat("=").concat(p_value));
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
},
_addMultiValueQueryParam: function(/*String*/ p_url, /*String*/ p_queryKey, /*Object|String*/ p_queryValues) {
// summary:
// Adds a multi-valued Url parameter to the given URL and returns the result
//
// p_url: The URL to augment with the given key/value parameter pairs. The Url is expected to
// already have a first parameter attached to it (?key=value), so the parameter pair
// given here, will be added as &p_queryKey=p_queryValues[0]&p_queryKey=p_queryValues[1]
// p_queryKey: String Parameter key
// p_queryValues: Array of string. Each array entry gets converted to one URL parameter using
// p_queryKey as the key and the array entry as the value
//
// returns:
// String the initial Url with the attached key/value pairs
// tags:
// private
// entry trace
var m = "_addMultiValueQueryParam(p_url, p_queryKey, p_queryValues)";
if (this._isTracing) {
this.traceEntry(m, [p_url, p_queryKey, dojo.toJson(p_queryValues)]);
}
var result = p_url;
if (p_queryValues) {
if (dojo.isArrayLike(p_queryValues)) {
dojo.forEach(p_queryValues, function(param) {
result = this._addSingleValueQueryParam(result, p_queryKey, param);
}, this);
} else {
if (dojo.isString(p_queryValues)) {
result = this._addSingleValueQueryParam(result, p_queryKey, p_queryValues);
}
}
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
},
_deleteContentMappingForPage: function(/*Object*/ p_params, /*Object*/ p_deferred) {
// summary:
// Generates an Xml document for deleting the given
// content mappings on the server and sends a DELETE
// request with this Xml document to the server.
//
// p_params:
// JSON object with the following properties
// "pageID": String ObjectID of the page whose mapping will be deleted
// "mappingToDelete": String ObjectID of the content/community mapping to delete
// p_deferred:
// [dojo.Deferred] object, whose callback() function will be called after successful
// delete operation and whose errback() function will be called on error
//
// tags:
// private
// entry trace
var m = "_deleteContentMappingForPage(p_params)";
if (this._isTracing) {
this.traceEntry(m, [dojo.toJson(p_params), dojo.toJson(p_deferred)]);
}
var xhrArgs = {
url: this._pickerConfig.getCMAtomDataSourceBaseUrl() + p_params.pageID + "&content=" + p_params.mappingToDelete,
headers: { "Content-Type": "application/atom+xml", "X-Pragma":"admin"},
sync: false,
load: function(data) {
if (p_deferred && dojo.isFunction(p_deferred.callback)) {
p_deferred.callback(data);
}
},
error: function(error) {
if (p_deferred && dojo.isFunction(p_deferred.errback)) {
p_deferred.errback(error);
}
}
};
dojo.xhrDelete(xhrArgs);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_loadContentMappingsForPageAsJSON: function(/*String*/ p_pageID, /*String?*/ p_scopeProvider, /*Function?*/ p_errorCallback) {
// summary:
// Requests a JSON object with content mappings for the
// given page from the aggregated content mapping
// datasource by sending an GET request to the server.
//
// p_pageID:
// String ObjectID of the page whose mappings will be returned
//
// p_scopeProvider [optional]:
// String name of the scope provider to return mappings for, if not given
// or undefined, mappings for all scope providers will be returned
// p_errorCallback [optional]:
// Function callback function being called with parameters (error, ioArgs), whenever
// an xhr 'error' occurs. Unlike the errback() function on the Deferred object
// returned by this function, it will not only see the Javascript error
// generated by a failed XHR request, but also receive the ioArgs object
//
// returns:
// dojo.Deferred
//
// tags:
// private
// entry trace
var m = "_loadContentMappingsForPageAsJSON(p_pageID, p_scopeProvider, p_errorCallback)";
if (this._isTracing) {
this.traceEntry(m, [p_pageID, p_scopeProvider, p_errorCallback]);
}
var deferredToReturn = new dojo.Deferred();
var requestUrl = this._pickerConfig.getCMAtomDataSourceBaseUrl() + p_pageID + "&mime-type=application/json&nocache=" + (new Date()).getTime();
if (p_scopeProvider && dojo.isString(p_scopeProvider)) {
requestUrl += "&scope-provider=" + encodeURIComponent(p_scopeProvider);
}
var xhrArgs = {
url: requestUrl,
sync: false,
headers: { "X-Pragma":"admin"},
handleAs: "json",
load: function(data, ioArgs) {
deferredToReturn.callback(data, ioArgs);
},
error: function(error, ioArgs) {
if (p_errorCallback && dojo.isFunction(p_errorCallback)) {
p_errorCallback(error, ioArgs);
}
}
};
dojo.xhrGet(xhrArgs);
// exit trace
if (this._isTracing) {
this.traceExit(m, deferredToReturn);
}
return deferredToReturn;
},
_getUpdateXmlDocument: function(/*String*/ p_pageID, /*Array*/ p_mappingsToUpdate) {
// summary:
// Returns a ready-to-use Xml document which contains
// entries for each content mapping given. The Xml document
// can be sent to the server as-is to update the given
// content mappings using the 'merge' method of the datasource.
//
// p_pageID:
// String ObjectID of the page to create/update mappings for
// p_mappingsToUpdate:
// Array of mappings to create/update, each mapping is represented by a JSON object
// with the following properties
// "id": String ObjectID of the Content/Community to map to the page
// "isDefault": Boolean true, if the mapping should become the new default for the page
// "isDelegating": Boolean true, if access control delegation should be enabled for this mapping
// "isSystem": Boolean true, if this is a system mapping that cannot be deleted
// "scope": String the scope to create the mapping in. Can be empty for WCM mappings
// returns:
// String
// tags:
// private
// entry trace
var m = "_getUpdateXmlDocument(p_pageID, p_mappingsToUpdate)";
if (this._isTracing) {
this.traceEntry(m, [p_pageID, dojo.toJson(p_mappingsToUpdate)]);
}
var xmlDocTemplate = this._getUpdateAtomTemplate({ "pageID": p_pageID });
var entries = [];
dojo.forEach(p_mappingsToUpdate, dojo.hitch(this, function(mapping) {
entries.push(this._getUpdateXmlEntry(mapping));
}));
var result = dojo.string.substitute(xmlDocTemplate, [entries.join("")]);
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // String
},
_getUpdateAtomTemplate: function(/*Object*/ p_params) {
// summary:
// Returns a string containing the template for an XML
// document needed for sending an update content mapping
// request to the server
// p_params:
// Parameter object (JSON) with the following properties
//
// "pageID": String The ObjectID of the page whose mappings will be modified
//
// returns:
// String (contains ${0} placeholder where entries for content mappings can be filled
// in by calling code)
// tags:
// private
// entry trace
var m = "_getUpdateAtomTemplate(p_params)";
if (this._isTracing) {
this.traceEntry(m, dojo.toJson(p_params));
}
var templateStringPrefix =
'' +
'' +
'' +
'IBM WebSphere Portal/8.0' +
'' +
'IBM WebSphere Portal Model Feed' +
'' +
'' +
'${pageID}' +
'' +
'';
var templateStringSuffix =
'' +
'' +
'' +
'';
// replace the variables in templatePrefix with values from p_params
var result = dojo.string.substitute(templateStringPrefix,
p_params,
com.ibm.domUtilities.encodeXML) +
"${0}" +
templateStringSuffix;
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // String
},
_getUpdateXmlEntry: function(/*Object*/ p_mappingToUpdate) {
// summary:
// Returns a string containing one line of XML for updating
// the given content mapping. Use this line of XML to fill
// it into a update content mapping Atom template
//
// p_mappingToUpdate:
// JSON object with the following properties
// "id": String ObjectID of the Content/Community to map to the page
// "isDefault": Boolean true, if the mapping should become the new default for the page
// "isDelegating": Boolean true, if access control delegation should be enabled for this mapping
// "isSystem": Boolean true, if this is a system mapping that cannot be deleted
// "scope": String the scope to create the mapping in. Can be empty for WCM mappings
//
// returns:
// String
//
// tags:
// private
// entry trace
var m = "_getUpdateXmlEntry(p_mappingToUpdate)";
if (this._isTracing) {
this.traceEntry(m, p_mappingToUpdate);
}
// since we use dojo.string.substitute for setting the id and isDefault flag, we need to ensure, both are set on
// the mapping to be updated
if (typeof p_mappingToUpdate.id == 'undefined') {
p_mappingToUpdate.id = "";
}
if (typeof p_mappingToUpdate.isDefault == 'undefined') {
p_mappingToUpdate.isDefault = false;
}
var entryTemplate =
'";
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // String
},
_getNameSpaceString: function() {
// summary:
// Builds a Namespace string as it is required for sending an Atom Feed Xml document
// to a REST datasource
// returns:
// String
// tags:
// private
// entry trace
var m = "_getNameSpaceString()";
if (this._isTracing) {
this.traceEntry(m);
}
var nsDecl = [];
nsDecl.push('xmlns:', 'atom', '="', 'http://www.w3.org/2005/Atom', '" ');
nsDecl.push('xmlns:', 'contentmapping', '="', 'http://www.ibm.com/xmlns/prod/content-mappings/v1.0', '" ');
var result = nsDecl.join('');
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // String
},
_getResolverStore: function() {
return ibmPortalConfig.resolver;
}
});
com.ibm.wps.contentmapping.utils.CMRESTServiceHelper._AC_DELEGATION_ATTR = 'delegated-role-type';
com.ibm.wps.contentmapping.utils.CMRESTServiceHelper._IS_SYSTEM_ATTR = 'system';
com.ibm.wps.contentmapping.utils.CMRESTServiceHelper._SCOPE_ATTR = 'scope';
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.utils.CMErrorMsgUtils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.utils.CMErrorMsgUtils"] = true;
dojo.provide("com.ibm.wps.contentmapping.utils.CMErrorMsgUtils");
dojo.registerModulePath("com.ibm.wps.contentmapping.utils", "../com/ibm/wps/contentmapping/utils");
dojo.require("com.ibm.widgets._Traceable");
dojo.declare("com.ibm.wps.contentmapping.utils.CMErrorMsgUtils", [com.ibm.widgets._Traceable], {
// summary:
// Provides some utility helper function for error messages related to XHR requests
// _maxErrorChars: [private] Integer
// Maximum number of characters that will be shown for an error message. The rest will
// be truncated.
_maxErrorChars: 500,
_isTracing: false,
constructor: function(/*Object?*/ p_params) {
// summary:
// Creates the error message for the given XHR request
// p_params:
// Object with the following properties
// maxErrorChars: Integer Number indicating the maximum number of characters a detailed error message
// may have
// tags:
// public
// set instance trace support flag
this._isTracing = this.isTracing();
// entry trace
var m = "constructor(p_params)";
if (this._isTracing) {
this.traceEntry(m, dojo.toJson(p_params));
}
if (p_params) {
if (p_params.maxErrorChars) {
this._maxErrorChars = p_params.maxErrorChars;
}
}
if (this._isTracing) {
this.traceExit(m);
}
},
getErrorMessageForXHR: function(/*Object*/ p_ioArgs, /*Object*/ p_nlsMessages) {
// summary:
// Creates the error message for the given XHR request
// p_ioArgs:
// The ioargs of the XHR request
// p_p_nlsMessages:
// An object containing NLS messages
// returns:
// Object Json object with two properties
// errorMessage: The error message
// errorDetails: The detailed error message [optional]
// tags:
// public
// entry trace
var m = "getErrorMessageForXHR(p_ioArgs, p_nlsMessages)";
if (this._isTracing) {
this.traceEntry(m, [ p_ioArgs, p_nlsMessages ]);
}
var result = {};
var stCode = 200;
if (p_ioArgs && p_ioArgs.xhr) {
// check for url, so we can determine, whether this is an http connection
var _url = p_ioArgs.url;
var useHTTPSMsgDetails = false;
if (_url && dojo.isString(_url)) {
useHTTPSMsgDetails = (_url.substring(0, 6).toLowerCase() === "https:");
}
if (p_ioArgs.xhr.status >= 400) {
var messageStr = 'errorHttp' + dojo.string.trim(p_ioArgs.xhr.status + '');
var detailsStr = 'errorDetailsHttp' + dojo.string.trim(p_ioArgs.xhr.status + '');
var detailsHttpsStr = 'errorDetailsHttps' + dojo.string.trim(p_ioArgs.xhr.status + '');
// trying to get the response string from the response object
var _resp = "";
if (dojo.isString(p_ioArgs.xhr.response)) {
_resp = p_ioArgs.xhr.response; // response is a string already, so just use it
} else {
// response is a javascript object, so test for the response text
if (p_ioArgs.xhr.responseText && dojo.isString(p_ioArgs.xhr.responseText)) {
_resp = p_ioArgs.xhr.responseText;
}
}
if (_resp.length > this._maxErrorChars) {
_resp = _resp.substring(0, this._maxErrorChars - 1);
}
// for errors 400 and 500, always display the msg returned from the server as the actual
// error message. Omit details message in that case. For all other status codes, display
// static message based on status code and add the optional server response as a detail
// message.
stCode = p_ioArgs.xhr.status;
if ((_resp.length > 0) &&
((stCode == 400) ||
(stCode == 500))) {
result[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_MESSAGE] = _resp;
// no detailed message in this case
} else {
if (p_nlsMessages[messageStr]) {
result[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_MESSAGE] = p_nlsMessages[messageStr];
if ((useHTTPSMsgDetails) && (p_nlsMessages[detailsHttpsStr])) {
result[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_DETAILS] = p_nlsMessages[detailsHttpsStr];
}
else if (p_nlsMessages[detailsStr]) {
result[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_DETAILS] = p_nlsMessages[detailsStr];
} else {
// grab details from response
result[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_DETAILS] = _resp;
}
} else {
// if we don't know the error, return a generic message
result[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_MESSAGE] = p_nlsMessages.errorFetchingData;
// no detailed message in this case
}
}
}
} else {
// without the xhr object within p_ioArgs, we cannot get the status and must return a generic error msg
result[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_MESSAGE] = p_nlsMessages.errorFetchingData;
// if the p_ioArgs parameter is a string, assume it contains a custom error message that we will display
// as errorDetails message
if (dojo.isString(p_ioArgs)) {
result[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_DETAILS] = p_ioArgs;
}
// no detailed message in this case
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
}
});
//*** global constants ***
// com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_MESSAGE: [const] [public] String
// The id of the attribute that contains the error message
com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_MESSAGE = "errorMessage";
// com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_DETAILS: [const] [public] String
// The id of the attribute that contains the error details
com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_DETAILS = "errorDetails";
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.widget.CMPickerDialogWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.widget.CMPickerDialogWidget"] = true;
/** ****************************************************************** */
/* Licensed Materials - Property of IBM */
/* */
/* 5724Z67 */
/* */
/* Copyright IBM Corp. 2011 All Rights Reserved. */
/* */
/* US Government Users Restricted Rights - Use, duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/** ****************************************************************** */
dojo.provide("com.ibm.wps.contentmapping.widget.CMPickerDialogWidget");
dojo.registerModulePath("com.ibm.wps.contentmapping.widget.", "../com/ibm/wps/contentmapping/widget");
dojo.require("com.ibm.widgets.GenericDialogWidget");
dojo.require("dijit.layout.TabContainer");
dojo.declare("com.ibm.wps.contentmapping.widget.CMPickerDialogWidget", [com.ibm.widgets.GenericDialogWidget], {
// summary:
// This widget is consumed by the
// [com.ibm.wps.contentmapping.dialog.ContentMappingPickerDialog] dialog
// blankImgUrl: Object
// URL pointing to a blank image (1x1 transparent pixel)
blankImgUrl: dojo.moduleUrl("dojo", "resources/blank.gif").toString(),
// namespace: [protected] String
// The namespace this widget uses for building its user interface elements
namespace: "CMPickerDialogWidget",
// templateString:
// see dijit.Dialog
templateString:"\n",
// reference to the dijit.layout.TabContainer which is displayed by this DialogWidget
_tabContainer: null,
// widgetsInTemplate: [protected] Boolean
// see dijit._Templated
widgetsInTemplate: true,
// _errorState: [private] Boolean
// Indicates whether an error occurred and whether this widget went into error state.
// The error state persists, until _clearError() was called.
_errorState: false,
// the marginBox this DialogWidget was resized to, to fit into its parent dialog
_resizedMarginBox: {
"w": 0,
"h": 0
},
// the name of the current page
_pageName: null,
// _eventHandlers: [private] Array
// Array of handlers created when connecting events to methods
_eventHandlers: [],
// the initial minimal size of this wiget's marginBox.
_initialMinSize: {
"w": 100,
"h": 100
},
// a com.ibm.wps.contentmapping.utils.CMRESTServiceHelper for using REST services
_restService: null,
// a com.ibm.wps.contentmapping.utils.CMPickerConfig for accessing the config and related functionality
_config: null,
// a [com.ibm.wps.contentmapping.utils.CMErrorMsgUtils] instance for handling XHRGet error messages
_errorMsgUtils: null,
// the provider whos tab should be initially selected
_initialSelectedProvider: null,
//provider data returned from the JSON feed
_providers: null,
// the space reserved for a vertical scrollbar of a page widget (child) in px
placeForVerticalScrollbar: 0,
// the space reserved for a horizontal scrollbar of a page widget (child) in px
placeForHorizontalScrollbar: 0,
//subscription handle for tab child selection
_selectChildHandle: null,
constructor: function(/*Object*/p_params){
// summary:
// Constructs this widget
// p_params: Object
// The arguments for initializing this widget
// tags:
// public
// set instance trace support flag
this._isTracing = this.isTracing();
// entry trace
var m = "constructor(p_params)";
var pageName = "";
if (this._isTracing) {
this.traceEntry(m, p_params);
}
// initialize the resource bundles for localization
this._initNLS();
this._restService = new com.ibm.wps.contentmapping.utils.CMRESTServiceHelper({
"nlsMessages": this._nlsMessages
});
this._config = new com.ibm.wps.contentmapping.utils.CMPickerConfig(p_params);
pageName = this._restService.getPageTitle(this._config.getCurrentPageID(), true);
this._pageName = pageName ? this._escapeXml(pageName) : pageName;
this._errorMsgUtils = new com.ibm.wps.contentmapping.utils.CMErrorMsgUtils();
if (p_params) {
this._initialSelectedProvider = p_params.scopeprovidername;
}
// default
this.inherited(arguments);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
postCreate: function(){
// summary:
// Binds resources required by this widget after its template DOM has been set up.
// Creates the tab container -> one tab for each scope provider from CM service.
// tags:
// protected
// entry trace
var m = "postCreate()";
if (this._isTracing) {
this.traceEntry(m);
}
var pageID = this._config.getCurrentResourceID();
var deferred = this._restService.getContentMappingsForPageAsJSON(pageID, null, dojo.hitch(this, function(error, ioArgs) {
this._hideLoadingDiv();
this._handleSessionExpiration(ioArgs);
this._initEventHandlers();
// need to run a subset of initialization steps in the error path, so our error message will show
this.onLayoutChange();
var errorMsgs = this._errorMsgUtils.getErrorMessageForXHR(ioArgs, this._nlsMessages.srvCommunication);
this._showError(errorMsgs[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_MESSAGE],
errorMsgs[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_DETAILS]);
if (this._isTracing) {
this.error(m, "Error loading the scopeproviders");
}
return error;
}));
deferred.addCallback(dojo.hitch(this, function(result, ioArgs){
this._hideLoadingDiv();
if (this._isTracing) {
this.trace(m, "getContentMappingsForPageAsJSON -> result: ", dojo.toJson(result));
}
if (this._validateJSONData(result)) {
this._providers = result.scopeproviders;
if (this._providers && this._providers.length > 0) {
this._tabContainer = new dijit.layout.TabContainer({
doLayout: false,
useMenu: false
}, this.CMPickerDialogWidgetTabContainer);
// add aria-controls to tab for accessibility
this._eventHandlers.push(dojo.connect(this._tabContainer.tablist, "onAddChild", this._tabContainer.tablist, function(page, idx){
var tab = this.getChildren()[idx];
dojo.attr(tab.tabContent, "aria-controls", page.id);
dojo.attr(tab.tabContent, "aria-describedby", page.id + "_header_id");
}));
dojo.forEach(this._providers, function(provider){
var cp;
if (this._initialSelectedProvider) {
// if a provider is pre-selected only display this single tab
if (provider.name === this._initialSelectedProvider){
cp = new com.ibm.wps.contentmapping.widget.CMPickerPageWidget({
scopeprovider: provider,
nlsUserInterface: this._nlsUserInterface,
nlsMessages: this._nlsMessages,
pageName: this._pageName
});
this._tabContainer.addChild(cp);
}
} else {
// else display all tabs
cp = new com.ibm.wps.contentmapping.widget.CMPickerPageWidget({
scopeprovider: provider,
nlsUserInterface: this._nlsUserInterface,
nlsMessages: this._nlsMessages,
pageName: this._pageName
});
if (provider.name === com.ibm.wps.contentmapping.utils.CMPickerConfig.SCOPE_PROVIDER_WCM) {
this._tabContainer.addChild(cp, 0); // show Web Content tag always as first tab!
}
else {
this._tabContainer.addChild(cp);
}
}
}, this);
this._tabContainer.startup();
// accessibility fix
dojo.attr(this._getFirstElementChild(this._tabContainer.tablist._leftBtn.tabContent), "alt", "");
dojo.attr(this._getFirstElementChild(this._tabContainer.tablist._menuBtn.tabContent), "alt", "");
dojo.attr(this._getFirstElementChild(this._tabContainer.tablist._rightBtn.tabContent), "alt", "");
this._initEventHandlers();
this.onChange();
this.onLayoutChange();
}
}
return result;
}));
// default
this.inherited(arguments);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
startup: function(){
// summary:
// Processing after the DOM fragment is added to the document. Calls startup() of
// this dialog's dijit.layout.TabContainer.
// tags:
// public
var m = "startup()";
if (this._isTracing) {
this.traceEntry(m);
}
// default
this.inherited(arguments);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
uninitialize: function(){
// summary:
// Releases the resources bound by this dialog before it is destroyed
// tags:
// protected
// entry trace
var m = "uninitialize()";
if (this._isTracing) {
this.traceEntry(m);
}
// disconnect the callbacks from their related events
this._clearEventHandlers();
// default
this.inherited(arguments);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
resize: function(changeSize){
// summary:
// Resizes this widget to the given size, by setting it's
// domNode's marginBox. The size of this widget's container node
// is resized, but only if the resized size does not go below its
// content's minimal size.
// tags:
// public
// entry trace
var m = "resize()";
if (this._isTracing) {
this.traceEntry(m);
}
if (changeSize) {
if (this._isTracing) {
this.trace(m, dojo.toJson(changeSize));
}
dojo.marginBox(this.domNode, {
"w": changeSize.w,
"h": changeSize.h
});
this._resizedMarginBox = dojo.marginBox(this.domNode);
}
this.layout();
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
layout: function(){
// summary:
// Widgets override this method to size and position their contents/children.
// When this is called this._contentBox is guaranteed to be set (see resize()).
// This is called after the widget's size has been changed.
// tags:
// public
var m = "layout()";
if (this._isTracing) {
this.traceEntry(m);
}
var widthToSet = Math.max(this._initialMinSize.w, this._resizedMarginBox.w);
var heightToSet = Math.max(this._initialMinSize.h, this._resizedMarginBox.h);
// trace
if (this._isTracing) {
this.trace(m, "this._initialMinSize:", dojo.toJson(this._initialMinSize));
this.trace(m, "_resizedMarginBox:", dojo.toJson(this._resizedMarginBox));
this.trace(m, "widthToSet:", widthToSet);
this.trace(m, "heightToSet:", heightToSet);
}
dojo.marginBox(this.containerNode, {
"w": widthToSet,
"h": heightToSet
});
if (this._tabContainer) {
this._tabContainer.layout();
this._tabContainer.selectedChildWidget.layout();
dojo.style(this._tabContainer.domNode, "height", "100%");
this._tabContainer.selectedChildWidget.changeSize({
"w": widthToSet,
"h": heightToSet - this._tabContainer.tablist._contentBox.h
}, this.placeForHorizontalScrollbar, this.placeForVerticalScrollbar);
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
getMinSize: function(){
// summary:
// Computes the minimal size this wiget's domNode needs for its marginBox.
// returns:
// The minimal size this wiget's domNode needs for its marginBox, e.g. {"w": minWidth, "h": minHeight}
// tags:
// private
var m = "getMinSize()";
if (this._isTracing) {
this.traceEntry(m);
}
// default if we have no tabContainer yet
var result = {
"w": 100,
"h": 50
};
if (this._tabContainer) {
var pageWigetMinSize = this._tabContainer.selectedChildWidget.getMinSize();
var minWidth = pageWigetMinSize.w;
var minHeight = this._tabContainer.tablist._contentBox.h + pageWigetMinSize.h;
result = {
"w": minWidth,
"h": minHeight
};
}
// exit trace
if (this._isTracing) {
this.traceExit(m, dojo.toJson(result));
}
return result;
},
doCancel: function(){
// summary:
// Called by the [com.ibm.widgets.GenericDialog] instance consuming
// this widget to inform this widget about the user having canceled the parent dialog.
// This widget decides whether it needs to return a JSON object, although the parent dialog
// was canceled
// returns:
// the data this widget contributes to the parent dialog result upon cancellation
// tags:
// public
// entry trace
var m = "doCancel()";
if (this._isTracing) {
this.traceEntry(m);
}
this._uninitializeAllPages();
// default
result = this.inherited(arguments);
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // Object
},
doConfirm: function(){
// summary:
// Called by the [com.ibm.widgets.GenericDialog] instance consuming
// this widget to inform this widget about the user having confirmed the parent dialog.
// This widget needs to collect its result data and store it in a JSON object, which it needs
// to return with this function
// returns:
// The data this widget contributes to the parent dialog result upon confirmation
// tags:
// public
// entry trace
var m = "doConfirm()";
if (this._isTracing) {
this.traceEntry(m);
}
if (this._tabContainer) {
var pageID = this._config.getCurrentResourceID();
var updatedMappings = [];
var propagateMappingsForProviders = [];
var disableMembershipIntgForProviders = [];
var enableMembershipIntgForProviders = [];
// collect all mappings of all CMPickerPageWidgets
dojo.forEach(this._tabContainer.getChildren(), function(pageWidget) {
var managedMappingsForPage = pageWidget.getManagedMappings();
this._postProcessSystemDefaultMappings(managedMappingsForPage);
updatedMappings = updatedMappings.concat(managedMappingsForPage);
// determine topology propagation state for each scope provider
if (pageWidget.isMappingPropagationEnabled()) {
propagateMappingsForProviders.push(pageWidget.getScopeProviderName());
}
// determine if membership integration has changed and is false
if (pageWidget.hasMembershipIntegrationDisabled()) {
disableMembershipIntgForProviders.push(pageWidget.getScopeProviderName());
}
// determine if membership integration has changed and is true
if (pageWidget.hasMembershipIntegrationEnabled()) {
enableMembershipIntgForProviders.push(pageWidget.getScopeProviderName());
}
}, this);
// since backend makes a replace off all mappings on the page we also have to add the mappings
// of the providers, that aren't even displayed because of not being initially selected
if (this._initialSelectedProvider) {
dojo.forEach(this._providers, function(provider){
if (provider.name !== this._initialSelectedProvider){
updatedMappings = updatedMappings.concat(provider.contentmappings);
}
}, this);
}
var errorCB = dojo.hitch(this, function(error, ioArgs){
var errorMsgs = this._errorMsgUtils.getErrorMessageForXHR(ioArgs, this._nlsMessages.srvCommunication);
this._showError(errorMsgs[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_MESSAGE],
errorMsgs[com.ibm.wps.contentmapping.utils.CMErrorMsgUtils.ERROR_DETAILS]);
return error;
});
var deferred = this._restService.updateContentMappingsForPage({
"pageID": pageID,
"mappingsToUpdate": updatedMappings,
"enablePropagation": propagateMappingsForProviders,
"disableMembershipIntegration": disableMembershipIntgForProviders,
"enableMembershipIntegration": enableMembershipIntgForProviders
},
"replace",
errorCB);
// if update succeded add callback to close the widget
deferred.addCallback(dojo.hitch(this, function(result){
if (this._isTracing) {
this.trace(m, "updateContentMappingsForPage -> result: ", dojo.toJson(result));
}
this._uninitializeAllPages();
this.onClose();
return result;
}));
result = deferred;
} else {
// default
result = this.inherited(arguments);
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result; // Object
},
getDialogTitle: function(){
// summary:
// Returns the title to show in the dialog that consumes this widget (see also
// [com.ibm.widgets.GenericDialog]).
// The dialog implementation is responsible of calling and honoring the title
// defined by this widget.
// tags:
// public
// entry trace
var m = "getDialogTitle()";
if (this._isTracing) {
this.traceEntry(m);
}
var result = dojo.string.substitute(this.getNlsUserInterface()[this.namespace].title, [this._pageName]);
if (!result) {
result = this.inherited(arguments);
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
},
onSelectChild: function(p_page){
// summary:
// Called whenever another tab of this widget's tabcontainer is selected
// p_page:
// The dijit._Widget rendered with the selected tab page
// tags:
// public, event
var m = "onSelectChild()";
if (this._isTracing) {
this.traceEntry(m);
}
// changes to the dialog widget cause previous error states to be cleared
this._clearError();
if (this._isTracing) {
this.traceExit(m);
}
},
onChange: function(){
// summary:
// Callback stub, which is called whenever the table of mappings
// changed and therfore grew or shrunk.
// changes to the dialog widget cause previous error states to be cleared
this._clearError();
},
onLayoutChange: function(){
// summary:
// Callback stub, which is called whenever the table of mappings
// changed and therfore grew or shrunk.
},
onClose: function(){
// summary:
// Callback stub, which is called whenever the dialog finished its work successfully.
},
onErrorStateChanged: function(/*Object*/p_sender, /*Boolean*/ p_errorState, /*String*/ p_errorMsg, /*String?*/ p_errorDetails){
// summary:
// Callback method that is triggered by this widget when an error condition
// occurred and the associated error message needs to be displayed in the
// owning dialog or if the widget was in error state previously and the
// error was cleared.
//
},
_clearError: function(){
// summary:
// Clears the error state (sets this._errorState to false) and notifies
// listeners of the changed error state
// tags:
// private
var m = "_clearError()";
if (this._isTracing) {
this.traceEntry(m);
}
this._errorState = false;
// notify registered listeners of the fact that we cleared the error
// no more parameters needed when clearing the error state
this.onErrorStateChanged(this, false);
if (this._isTracing) {
this.traceExit(m);
}
},
_clearEventHandlers: function(){
// summary:
// Disconnects the events supported by this dialog from the corresponding callback methods
// tags:
// private
// entry trace
var m = "_clearEventHandlers()";
if (this._isTracing) {
this.traceEntry(m);
}
dojo.forEach(this._eventHandlers, dojo.disconnect);
this._eventHandlers = [];
if (this._tabContainer) {
dojo.unsubscribe(this._selectChildHandle);
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_escapeXml: function(/*String*/ p_text) {
if (p_text) {
return p_text.
replace(/&/g,'&').
replace(/>/g,'>').
replace(/ 0)) {
result = p_domNode.children[0];
} else {
result = {};
}
}
} else {
result = {};
}
// exit trace
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
},
_handleSessionExpiration: function(/*Object|String*/ p_errorInfo) {
// summary:
// Checks the given error information for having indications of a 401 HTTP status code. If found,
// triggers a page reload, to have the user logon again
// tags:
// private
// entry trace
var m = "_handleSessionExpiration()";
if (this._isTracing) {
this.traceEntry(m, p_errorInfo);
}
if (dojo.isObject(p_errorInfo) &&
p_errorInfo.xhr &&
p_errorInfo.xhr.status) {
if (p_errorInfo.xhr.status === 401) {
// trigger page reload
top.location.href = document.location.href;
}
} else {
if (dojo.isString(p_errorInfo)) {
// TODO: try to parse for 401 error in this string
}
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_hideLoadingDiv: function() {
// summary:
// Hides the loading animation DIV
// tags:
// private
// entry trace
var m = "_hideLoadingDiv()";
if (this._isTracing) {
this.traceEntry(m);
}
if (this.loadingDiv) {
dojo.style(this.loadingDiv, "display", "none");
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_initEventHandlers: function(){
// summary:
// Connects the events supported by this dialog to the corresponding callback methods
// and stores the Handlers in the _eventHandlers array
// tags:
// private
// entry trace
var m = "_initEventHandlers()";
if (this._isTracing) {
this.traceEntry(m);
}
if (this._tabContainer) {
dojo.forEach(this._tabContainer.getChildren(), function(pageWidget){
this._eventHandlers.push(dojo.connect(pageWidget, "onChange", this, "onChange"));
this._eventHandlers.push(dojo.connect(pageWidget, "onLayoutChange", this, "onLayoutChange"));
this._eventHandlers.push(dojo.connect(pageWidget, "onErrorStateChanged", this, "onErrorStateChanged"));
}, this);
this._selectChildHandle = dojo.subscribe(this._tabContainer.id + "-selectChild", dojo.hitch(this, function(child){
this.onSelectChild(child);
}));
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_initNLS: function(){
// summary:
// Initializes the aspects for supporting localization, for example, by loading the required NLS bundle(s)
// tags:
// private
// entry trace
var m = "_initNLS()";
if (this._isTracing) {
this.traceEntry(m);
}
this._nlsUserInterface = dojo.i18n.getLocalization("com.ibm.wps.contentmapping", 'ContentMappingPickerUserInterface');
this._nlsMessages = dojo.i18n.getLocalization("com.ibm.wps.contentmapping", 'ContentMappingPickerMessages');
// exit trace
if (this._isTracing) {
this.trace(m, "Initialized NLS object for user interface elements:", dojo.toJson(this._nlsUserInterface));
this.trace(m, "Initialized NLS object for messages:", dojo.toJson(this._nlsMessages));
this.traceExit(m);
}
},
_postProcessSystemDefaultMappings: function(/*Array*/ p_mappings) {
// summary:
// Scans through all given mappings and resets the isDefault flag to
// false for any system mapping found. This is required, because
// the default flag cannot be set on system mappings, but it will
// implicitly be treated as the default, if no other mapping is
// flagged as a default mapping.
// p_mappings: Array of Object
// An array of content mapping objects
// tags:
// private
var m = "_postProcessSystemDefaultMappings(p_node)";
// entry trace
if (this._isTracing) {
this.traceEntry(m, dojo.toJson(p_mappings));
}
dojo.forEach(p_mappings, dojo.hitch(this, function(/*Object*/ p_mapping) {
if ((p_mapping.isSystem === true) && (p_mapping.isDefault === true)) {
p_mapping.isDefault = false;
}
}));
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_showError: function(/*String*/p_errorMsg, /*String*/ p_errorDetails){
// summary:
// Sends the provided error message to a registered listener (could be a
// dialog) for display. Optionally, also sends a more detailed message
// for the error.
// p_errorMsg: String
// The error message to display
// p_errorDetails: String
// Optional string with a more detailed description of the error
// tags:
// protected
var m = "_showError(p_errorMsg, p_errorDetails)";
if (this._isTracing) {
this.traceEntry(m, [p_errorMsg, p_errorDetails]);
}
this._errorState = true;
// notify registered listeners of the error and have them e.g. display
// the error message + details
this.onErrorStateChanged(this, true, p_errorMsg, p_errorDetails);
if (this._isTracing) {
this.traceExit(m);
}
},
_uninitializeAllPages: function() {
// summary:
// Calls the uninitialize() method on all tab page widgets that have
// been created. This ensures that the pages are able to properly uninitialize
// any DOM related widgets or artifacts, which would not be possible, with
// the call to uninitialize during destroy().
// tags:
// private
// entry trace
var m = "_uninitializeAllPages()";
if (this._isTracing) {
this.traceEntry(m);
}
if (this._tabContainer) {
dojo.forEach(this._tabContainer.getChildren(), function(pageWidget){
pageWidget.uninitialize();
}, this);
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_validateJSONData: function(/*Object*/ p_jsonData) {
// summary:
// Validates the provided JSON object wrt required fields being available
// Will cause an error to be shown in the dialog, if required fields are
// missing.
// p_jsonData: Object
// The JSON object to be validated
// returns:
// Boolean true, if validation succeeded, false, if not
// tags:
// private
// entry trace
var m = "_validateJSONData(p_jsonData)";
if (this._isTracing) {
this.traceEntry(m, dojo.toJson(p_jsonData));
}
var result;
if (p_jsonData) {
if (p_jsonData.scopeproviders) {
var providers = p_jsonData.scopeproviders;
if (dojo.isArrayLike(providers) && (providers.length > 0)) {
// validate all available scope-providers
result = dojo.every(providers, function(provider) {
return this._validateScopeProvider(provider);
}, this);
} else {
// no entries in scopeproviders array, or not an array at all
result = false;
}
} else {
// no scopeproviders field
result = false;
}
} else {
// missing json object
result = false;
}
if (!result) {
this._showError(this._nlsMessages.pickerPageWidget.errorJSONDataInvalid);
}
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
},
_validateScopeProvider: function(/*Object*/ p_scopeProvider) {
// summary:
// Validates the given scope provider object for having all required fields
// p_scopeProvider: Object
// The scope provider object to validate
// returns:
// Boolean true, if validation succeeded, false, if not
// tags:
// private
// entry trace
var m = "_validateScopeProvider(p_scopeProvider)";
if (this._isTracing) {
this.traceEntry(m, dojo.toJson(p_scopeProvider));
}
var result;
if (p_scopeProvider) {
if (p_scopeProvider.name) {
var mappings = p_scopeProvider.contentmappings;
if (mappings && dojo.isArrayLike(mappings)) {
// if a mappings array is there, validate it
result = dojo.every(mappings, function(mapping) {
return this._validateContentMapping(mapping);
}, this);
} else {
result = true; // it's ok to have a missing contentmappings array, if there are no
// mappings available
}
} else {
// no name given
result = false;
}
} else {
// no scope provider given
result = false;
}
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
},
_validateContentMapping: function(/*Object*/ p_contentMapping) {
// summary:
// Validates the given content mapping object for having all required fields
// p_scopeProvider: Object
// The content mapping object to validate
// returns:
// Boolean true, if validation succeeded, false, if not
// tags:
// private
// entry trace
var m = "_validateContentMapping(p_contentMapping)";
if (this._isTracing) {
this.traceEntry(m, dojo.toJson(p_contentMapping));
}
var result;
if (p_contentMapping) {
if (p_contentMapping.id) {
if (typeof p_contentMapping.isDefault != 'undefined') {
if (typeof p_contentMapping.isSystem != 'undefined') {
result = true; // it's ok to have some fields missing, especially a missing 'title' will be handled elsewhere
} else {
// system flag missing
result = false;
}
} else {
// default flag missing
}
} else {
// id attribute missing
result = false;
}
} else {
// no contentmapping given
result = false;
}
if (this._isTracing) {
this.traceExit(m, result);
}
return result;
}
});
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.dialog.CustomMessageDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.dialog.CustomMessageDialog"] = true;
dojo.provide("com.ibm.wps.contentmapping.dialog.CustomMessageDialog");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit.Dialog");
dojo.require("com.ibm.widgets._Traceable");
dojo.declare("com.ibm.wps.contentmapping.dialog.CustomMessageDialog", [dijit._Widget, dijit._Templated, dijit.Dialog, com.ibm.widgets._Traceable], {
// summary:
// Common Dialog
//
// CustomMessageDialog is fully customizable from an NLS string perspective and has the following layout:
//
// - a customizable message
// - two buttons with customizable lables for Yes/No Ok/Cancel, etc. type of events
// - a dialog headline showing a customizable string describing the current task
//
// You can connect to all events (Button1/Button2/Close) of the dialog
// - onCloseDialog() is fired when the dialog gets closed by clicking on X
// - onSubmitDialog() is fired when the dialog is confirmed by clicking on 'OK' (Button1)
// - onCancelDialog() is fired when the dialog gets cancelled by clicking on 'Cancel' (Button2)
// lotusui_id: String
// The ID for the global dijitDialog lotusui related wrapper DIV
lotusui_id: "dijitDialog_lotusui30_CstmMsgDlg_container",
// lotusui_class: String
// The lotusui class to assign to the wrapper DIV, if it gets created
lotusui_class: "lotusui30",
// _eventHandles: [private] Array
// Array of handles created when connecting events to methods
_eventHandles: [],
// autoClose: Boolean
// If set to true, the dialog will destroy itself on one of the three events (onCancel, onClose, onSubmit).
// If set to false, the dialog will only hide, but not destroy itself.
autoClose: true,
bIsTracing: false,
blankImg: dojo.moduleUrl("dojo", "resources/blank.gif").toString(),
// NLS strings that need to be set from the outside (e.g. by passing values on the constructor)
id: "",
nlsTitleClose: "",
nlsDialogTitle: "",
nlsDialogMessage: "",
nlsTitleButtonYes: "",
nlsTitleButtonNo: "",
templateString: null,
templateString:"\n",
constructor: function(/*Object*/ p_params) {
// p_params: Object
// JSON object with the following mandatory parameters
//
// bundle: Object
// JSON object with the following mandatory parameters
//
// CloseTitle
// DialogTitle
// DialogMessageLabel
// ButtonSubmitTitle
// ButtonCancelTitle
// id: String
this.nlsTitleClose = p_params.bundle.CloseTitle;
this.nlsDialogTitle = p_params.bundle.DialogTitle;
this.nlsDialogMessage = p_params.bundle.DialogMessageLabel;
this.nlsTitleButtonYes = p_params.bundle.ButtonSubmitTitle;
this.nlsTitleButtonNo = p_params.bundle.ButtonCancelTitle;
this._eventHandles = [];
// Dojo 1.6: make sure we don't allow dijit.Dialog to automatically assign any hover classes to our
// buttons/attachpoints
this.cssStateNodes = {};
},
postCreate: function() {
var m = "postCreate()";
if (this.bIsTracing) {
this.traceEntry(m);
}
this.inherited(arguments);
this.submitDialog.onclick = dojo.hitch(this, function() {
this.hide();
this.submit();
return false;
});
this.dialogCancel.onclick = dojo.hitch(this, function() {
this.hide();
this.cancelDialog();
return false;
});
this.closeButtonNode.onclick = dojo.hitch(this, function() {
this.hide();
this.closeDialog();
return false;
});
// connect default keyhandler to the onkeypress event for the two links acting as
// buttons
this._eventHandles.push(dojo.connect(this.dialogCancel, "onkeypress", dojo.hitch(this, "_triggerOnClickEvtForSpaceKey")));
this._eventHandles.push(dojo.connect(this.closeButtonNode, "onkeypress", dojo.hitch(this, "_triggerOnClickEvtForSpaceKey")));
// the onCancel() method of dijit.Dialog is triggered when pressing the ESC key. We need
// to connect our "closeDialog" method which destroys the dialog to that event as well.
// Otherwise closing the dialog using the ESC key would only hide the dialog instead of
// destroying it
this._eventHandles.push(dojo.connect(this, "onCancel", this, "closeDialog"));
// create lotusui surrounding DIV for this dialog and place this.domNode into it
dojo.place(this.domNode, this._findOrCreateLotusUIDIV(), "last");
if (this.bIsTracing) {
this.traceExit(m);
}
},
onCloseDialog: function() {
// method stub, users should connect to this method to get notified when
// the dialog was closed
},
onSubmitDialog: function() {
// method stub, users should connect to this method to get notified when
// the dialog was submitted (OK/YES clicked)
},
onCancelDialog: function() {
// method stub, users should connect to this method to get notified when
// the dialog was cancelled (Cancel/NO clicked)
},
submit: function() {
var m = "submit()";
if (this.bIsTracing) {
this.traceEntry(m);
}
this.onSubmitDialog();
if (this.autoClose) {
setTimeout(dojo.hitch(this, "destroyRecursive"), this.duration + 200);
}
if (this.bIsTracing) {
this.traceExit(m);
}
},
uninitialize: function() {
dojo.forEach(this._eventHandles, dojo.disconnect);
this._eventHandles = [];
},
cancelDialog: function() {
var m = "cancelDialog()";
if (this.bIsTracing) {
this.traceEntry(m);
}
this.onCancelDialog();
if (this.autoClose) {
setTimeout(dojo.hitch(this, "destroyRecursive"), this.duration + 200);
}
if (this.bIsTracing) {
this.traceExit(m);
}
},
closeDialog: function() {
var m = "closeDialog()";
if (this.bIsTracing) {
this.traceEntry(m);
}
this.onCloseDialog();
if (this.autoClose) {
setTimeout(dojo.hitch(this, "destroyRecursive"), this.duration + 200);
}
if (this.bIsTracing) {
this.traceExit(m);
}
},
_findOrCreateLotusUIDIV: function() {
// summary:
// Tries to find an existing dijit.Dialog lotusui30 container DIV in the current page
// and if it doesn't find one, creates it.
//
// Used to avoid flooding the DomTree with lotusui30 related wrapper DIVs, if dialogs
// are opened and closed many times.
// returns:
// The domNode reference of the found or created dijit.Dialog lotusui30 container DIV
// tags:
// private
// entry trace
var m = "_findOrCreateLotusUIDIV()";
if (this._isTracing) {
this.traceEntry(m);
}
var lotusui_div = dojo.byId(this.lotusui_id);
if (!lotusui_div) {
lotusui_div = dojo.create("div", { "id": this.lotusui_id,
"class": this.lotusui_class,
"wairole": "region",
"role": "region"
}, dojo.body());
}
// set wai state in any case (whether we re-use an existing or newly created
// wrapping div) to not break Accessibility
dijit.setWaiState(lotusui_div, "labelledby", this.id + "_title");
// exit trace
if (this._isTracing) {
this.traceExit(m, lotusui_div);
}
return lotusui_div;
},
_triggerOnClickEvtForSpaceKey: function(/*Event*/ p_evt) {
// summary:
// Checks whether the SPACE key was pressed and fires the onclick event handler attached to
// the target node for this event
// tags:
// private callback
if (p_evt) {
var target = p_evt.target;
if (target) {
var key = p_evt.charCode; // Space key only sets charCode, keyCode is 0
var keys = dojo.keys;
if (key === keys.SPACE) {
if (dojo.isFunction(target.onclick)) {
// trigger onclick handler when the SPACE key was pressed
target.onclick();
dojo.stopEvent(p_evt);
}
}
}
}
},
// @OVERRIDE dijit._DialogMixin._getFocusItems()
// Need to fix the buggy method, which does not take passed in domNode into account
// although dijit.Dialog relies on this method to take a domNode as an argument
_getFocusItems: function(/*Node*/ p_domNode){
// summary:
// see dijit._DialogMixin
// tags:
// protected
// Fixed _getFocusItems() method.
// Would also work with a fixed dojo version, so we're forward compatible here.
// store current containerNode reference and replace it with the passed in domNode,
// as current implementation uses 'this.containerNode' as the reference domNode
var oldContainerNode = this.containerNode;
this.containerNode = p_domNode;
// call original method
this.inherited(arguments);
// restore containerNode reference
this.containerNode = oldContainerNode;
}
});
}
if(!dojo._hasResource["com.ibm.wps.contentmapping.dialog.ContentMappingPickerDialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["com.ibm.wps.contentmapping.dialog.ContentMappingPickerDialog"] = true;
/** ****************************************************************** */
/* Licensed Materials - Property of IBM */
/* */
/* 5724Z67 */
/* */
/* Copyright IBM Corp. 2011 All Rights Reserved. */
/* */
/* US Government Users Restricted Rights - Use, duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/** ****************************************************************** */
dojo.provide("com.ibm.wps.contentmapping.dialog.ContentMappingPickerDialog");
dojo.registerModulePath("com.ibm.wps.contentmapping.dialog", "../com/ibm/wps/contentmapping/dialog");
dojo.require("dijit.Tooltip");
dojo.require("com.ibm.widgets.GenericDialog");
dojo.declare("com.ibm.wps.contentmapping.dialog.ContentMappingPickerDialog", [com.ibm.widgets.GenericDialog], {
// summary:
// Content Mapping Picker dialog, inherited from GenericDialog.
// namespace: [protected] String
// The namespace this dialog uses for building its user interface elements
namespace: "CMPickerDlg",
// templateString:
// see dijit.Dialog
templateString: dojo.cache("com.ibm.wps.contentmapping.dialog", "templates/ContentMappingPickerDialog.html", "\n \n
\n \n \n
\n
\n
\n
\n \n
\n \n \n
\n
\n
\n
\n
\n \n
\n
\n"),
// lotusui_id: String
// The ID for the global dijitDialog lotusui related wrapper DIV
// The container needs to be specific to the ContentMappingPickerDialog, as the labelledby
// aria attribute is specific to this dialog.
lotusui_id: "dijitDialog_lotusui30_CmpDlg_container",
// lotusui_class: String
// The lotusui class to assign to the wrapper DIV, if it gets created
lotusui_class: "lotusui30",
// widgetsInTemplate: [protected] Boolean
// see dijit._Templated
widgetsInTemplate: true,
// _dialogBorderWidth: [private] Integer
// Width of the dialog border (left + right side) in pixels. Used to calculate the available
// horizontal space for the ContainerNode on resize
_dialogBorderWidth: 6,
// _errorState: [private] Boolean
// Indicates whether an error occurred and whether this dialog went into error state.
// The error is displayed (and the user cannot advance within or finish the dialog)
// until _clearError() was called.
_errorState: false,
// _maxErrorChars: [private] Integer
// Maximum number of characters that will be shown for an error message. The rest will
// be truncated.
_maxErrorChars: 768,
// minHeight: [protected] Integer
// Minimum height of the dialog in pixels. Neither the resize handle, nor the layout() code allows
// to reduce the height of the dialog to a lower value.
minHeight: 200,
// minWidth: [protected] Integer
// Minimum width of the dialog in pixels. Neither the resize handle, nor the layout() code allows
// to reduce the width of the dialog to a lower value.
minWidth: 600,
// _eventHandlers: [private] Array
// Array of handlers created when connecting events to methods
_eventHandlers: [],
// _maxTooltipWidth: [private] String
// Maximum width of a tooltip as a CSS style value. We concatenate the style="max-width: " string
// when we set the Tooltip label and can neither use integer values here nor dojo.style to set
// the width. Advantage of this approach is that we can use px or em.
_maxTooltipWidth: '550px',
// _showPersistenceWarning: [private] Boolean
// If true, shows a confirmation dialog, telling the user that his action won't be undoable by clicking 'Cancel' on
// the "Edit Page Properties" dialog. Should only be set to 'true' for the legacy location within the 'Edit Page Properties' page.
_showPersistenceWarning: false,
constructor: function(/*Object*/p_params){
// set instance trace support flag
this._isTracing = this.isTracing();
var m = "constructor(p_params)";
if (this._isTracing) {
this.traceEntry(m, p_params);
}
// Dojo 1.6: make sure we don't allow dijit.Dialog to automatically assign any hover classes to our
// buttons/attachpoints
this.cssStateNodes = {};
if (p_params && (typeof p_params.showPersistenceWarning != 'undefined')) {
this._showPersistenceWarning = p_params.showPersistenceWarning ? true : false;
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
show: function() {
// summary:
// Overridden show() method of [dijit.Dialog], allowing us to trigger the startup
// method
// tags:
// protected
// entry trace
var m = "show()";
if (this._isTracing) {
this.traceEntry(m);
}
// default
this.inherited(arguments);
// allow fade-in animation of the dialog to complete, then focus the first tabbable item in the
// currently active page
setTimeout(dojo.hitch(this, function(){dijit.focus(this.titleNode);}), 30);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
postCreate: function(){
// summary:
// Binds resources required by this dialog after its DOM has been set up
// tags:
// protected
// entry trace
var m = "postCreate()";
if (this._isTracing) {
this.traceEntry(m);
}
// default
this.inherited(arguments);
dojo.attr(this.GenericDialogDiv, "lang", ibmPortalConfig.locale.replace(/_/, '-').replace(/iw/, 'he'));
dojo.attr(this.GenericDialogDiv, "dir", (ibmCfg.themeConfig.isRTL ? "rtl" : "ltr"));
this._initEventHandlers();
this._dlgTooltip = new dijit.Tooltip({
connectId: [this.namespace + "GenericDialogTitleBarHelpIcon_id"],
label: '' +
this._nlsUserInterface.CMPickerDialog.dialogTooltip +
this._nlsUserInterface.CMPickerDialog.dialogTooltip_2 +
'',
position: ["below"]
});
// make sure we update the global WP dijit.Tooltip variable with the target
// node which shows a current tooltip, so we can close it manually on ESCAPE
this._eventHandlers.push(dojo.connect(this._dlgTooltip, "onShow", dojo.hitch(this, function(target) {
com.ibm.wps.contentmapping._currentTooltipNode = target;
})
));
this._eventHandlers.push(dojo.connect(this._dlgTooltip, "onHide", dojo.hitch(this, function() {
com.ibm.wps.contentmapping._currentTooltipNode = null;
})
));
// create lotusui surrounding DIV for this dialog and place this.domNode into it
dojo.place(this.domNode, this._findOrCreateLotusUIDIV(), "last");
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
startup: function(){
// summary:
// Processing after the DOM fragment is added to the document. Calls startup() of
// this dialog's child widget.
var m = "startup()";
if (this._isTracing) {
this.traceEntry(m);
}
if (this._widget) {
this._widget.startup();
}
// default
this.inherited(arguments);
this.layout();
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
layout: function(){
// summary:
// Makes sure that the dialog is always fully visible on screen.
// Calculates the available viewport + the current dialog height
// and determines whether a specific height needs to be set, until
// the dialog was not resized manually.
// tags:
// public
// entry trace
var m = "layout()";
if (this._isTracing) {
this.traceEntry(m);
}
// determine the maximum height of the dialog to allow
var dialogMaxSize = {
"w": Math.round(dijit.getViewport().w * 0.9),
"h": Math.round(dijit.getViewport().h * 0.9)
};
// height of the wizard page header containing the dialog title and close icon
var headerHeight = dojo.marginBox(this.titleBar).h;
// height of the wizard page footer containing the dialog buttons and links
var footerHeight = dojo.marginBox(this.dialogFooter).h;
// initial min size of the dialog's widget
var widgetMinSize = {
"w": 100,
"h": 50
};
var containerNodeMarginsW = dojo.marginBox(this.containerNode).w - dojo.contentBox(this.containerNode).w;
var containerNodeMarginsH = dojo.marginBox(this.containerNode).h - dojo.contentBox(this.containerNode).h;
var errorBoxHeight = 0;
if (this._errorState){
errorBoxHeight = dojo.marginBox(this.CMPickerDialogErrorDiv).h;
}
// layout the dialog widget and get its minimal size to display properly
if (this._widget) {
this._widget.layout();
widgetMinSize = this._widget.getMinSize();
}
// now we can define the minimal size the dialog may have, so that the complete content can be displayed w.o. scrolling
var dialogMinSize = {
"w": Math.max(this.minWidth, widgetMinSize.w + containerNodeMarginsW),
"h": Math.max(this.minHeight, headerHeight + errorBoxHeight + widgetMinSize.h + footerHeight + containerNodeMarginsH)
};
// make sure that the dialog does not get larger than its max size
var dialogSizeToSet = {
"w": this._dialogBorderWidth + Math.min(dialogMaxSize.w, dialogMinSize.w),
"h": this._dialogBorderWidth + Math.min(dialogMaxSize.h, dialogMinSize.h)
};
// the dialog was resized manually
if (this.isResized === true) {
// the minimal allowed size for the dialog
var manualSize = {
"w": Math.max(this.minWidth, dojo.marginBox(this.domNode).w),
"h": Math.max(this.minHeight, dojo.marginBox(this.domNode).h)
};
// make sure that the dialog does not get larger than its max size
dialogSizeToSet = {
"w": Math.min(dialogMaxSize.w, manualSize.w),
"h": Math.min(dialogMaxSize.h, manualSize.h)
};
} else {
// ONLY RESIZE THE DIALOG IF MORE SPACE IS NEEDED, NEVER AUTO-SIZE IT SMALLER FOR SMOOTHER TABBING
dialogSizeToSet = {
"w": Math.max(dojo.marginBox(this.domNode).w, dialogSizeToSet.w),
"h": Math.max(dojo.marginBox(this.domNode).h, dialogSizeToSet.h)
};
}
/* BEGIN HANDLE SCROLLBARS */
if (dialogSizeToSet.h < dialogMinSize.h) {
if (this.isResized === false && this._widget && this._widget.placeForVerticalScrollbar === 0) {
if (this._isTracing) {
this.trace(m, "Increasing for vertical scrollbar");
}
dialogSizeToSet.w = dialogSizeToSet.w + 25;
}
if (this._widget) {
this._widget.placeForVerticalScrollbar = 25;
}
}
if (dialogSizeToSet.w < dialogMinSize.w) {
if (this.isResized === false && this._widget && this._widget.placeForHorizontalScrollbar === 0) {
if (this._isTracing) {
this.trace(m, "Increasing for horizontal scrollbar");
}
dialogSizeToSet.h = dialogSizeToSet.h + 25;
}
if (this._widget) {
this._widget.placeForHorizontalScrollbar = 25;
}
}
/* END HANDLE SCROLLBARS */
// set the dialog's size
dojo.marginBox(this.domNode, dialogSizeToSet);
// default
this.inherited(arguments);
// resize the dialog's widget to the dialog's container node size
var wigetSizeToSet = {
"w": dialogSizeToSet.w - this._dialogBorderWidth - containerNodeMarginsW,
"h": dialogSizeToSet.h - this._dialogBorderWidth - headerHeight - errorBoxHeight - footerHeight - containerNodeMarginsH
};
if (this._widget && (typeof this._widget.resize == 'function')) {
this._widget.resize(wigetSizeToSet);
}
// trace
if (this._isTracing) {
this.trace(m, "headerHeight: ", headerHeight);
this.trace(m, "footerHeight: ", footerHeight);
this.trace(m, "dialogMaxSize: ", dojo.toJson(dialogMaxSize));
this.trace(m, "containerNodeMarginsW:", containerNodeMarginsW);
this.trace(m, "containerNodeMarginsH:", containerNodeMarginsH);
this.trace(m, "widgetMinSize:", dojo.toJson(widgetMinSize));
this.trace(m, "dialogMaxSize:", dojo.toJson(dialogMaxSize));
this.trace(m, "dialogMinSize:", dojo.toJson(dialogMinSize));
this.trace(m, "dialogSizeToSet:", dojo.toJson(dialogSizeToSet));
this.trace(m, "wigetSizeToSet:", dojo.toJson(wigetSizeToSet));
this.traceExit(m);
}
},
uninitialize: function(){
// summary:
// Releases the resources bound by this dialog before it is destroyed
// tags:
// protected
// entry trace
var m = "uninitialize()";
if (this._isTracing) {
this.traceEntry(m);
}
if (this._dlgTooltip) {
this._dlgTooltip.destroy();
delete this._dlgTooltip;
}
// disconnect the callbacks from their related events
this._clearEventHandlers();
// default
this.inherited(arguments);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
postMixInProperties: function(){
// summary:
// Prepares the creation of the user interface of this dialog
// tags:
// protected
// entry trace
var m = "postMixInProperties()";
if (this._isTracing) {
this.traceEntry(m);
}
// default
this.inherited(arguments);
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
close: function(){
// summary:
// Closes the dialog
// tags:
// public
// entry trace
var m = "close()";
if (this._isTracing) {
this.traceEntry(m);
}
if (this.autoClose) {
this.hide();
setTimeout(dojo.hitch(this, "destroyDialog"), this.duration);
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_clearError: function(){
// summary:
// Clears the error state (sets this._errorState to false) and hides the
// error DIV showing the error message.
// tags:
// private
// entry trace
var m = "_clearError()";
if (this._isTracing) {
this.traceEntry(m);
}
// clear the error state and hide the error div
this._errorState = false;
dojo.style(this.CMPickerDialogErrorDetailsDiv, 'display', 'none');
dojo.style(this.CMPickerDialogErrorDiv, 'display', 'none');
dijit.setWaiState(this.CMPickerDialogErrorDiv, 'hidden', true);
dijit.setWaiState(this.CMPickerDialogErrorDetailsDiv, 'hidden', true);
// re-enable buttons in case they were disabled, because of an error
// TODO: introduce this._enableDisableButtons();
// make sure the dialog looks 'good' after closing the box
this.layout();
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_onConfirm: function(){
// summary:
// Called when the user confirms this dialog. Informs the widget this dialog consumes about the
// confirmation event to retrieve the widget result data that is then passed to the client callback
// function registered with this dialog. Eventually, this dialog is destroyed if auto closing
// is enabled
// tags:
// private callback
// entry trace
var m = "_onConfirm()";
if (this._isTracing) {
this.traceEntry(m);
}
var returnValues = {};
var confirmActionFn = function(/*Object*/ me) {
var _m = "_onConfirm.confirmActionFn()";
// in a hitched function call that correctly
// provides the 'this' context, we simply
// use it, in all other cases we assume that
// the context (this) of the caller is being
// passed as 'me' parameter
if (!me) {
me = this;
}
if (me._isTracing) {
me.traceEntry(_m);
}
if (me._widget && (typeof me._widget.doConfirm == 'function')) {
returnValues = me._widget.doConfirm();
}
// trace
if (me._isTracing) {
me.trace(_m, "Return values from widget:", returnValues);
}
if (me._onConfirmCallbackFn) {
// trace
if (me._isTracing) {
me.trace(_m, "Dispatching to callback function passing the return values from the widget:", [me._onConfirmCallbackFn, returnValues]);
}
if (dojo.isFunction(returnValues.addCallback)){
returnValues.addCallback(dojo.hitch(me, me._onConfirmCallbackFn));
} else {
// pass on return values from the widget to the caller of me dialog
me._onConfirmCallbackFn(returnValues);
}
}
if (me._isTracing) {
me.traceExit(_m);
}
};
if (this._showPersistenceWarning) {
var confirmDlg = new com.ibm.wps.contentmapping.dialog.CustomMessageDialog({
"id": "ContentMappingPickerDialog_ConfirmationDialog_id",
"bundle": this._nlsUserInterface.CMPickerConfirmationDlgBundle
});
dojo.connect(confirmDlg, "onSubmitDialog", this, dojo.hitch(this, confirmActionFn));
confirmDlg.show();
} else {
// directly call the confirmActionFn here, as we do not have to show the confirmation
// dialog in this mode
confirmActionFn(this);
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_onErrorStateChanged: function(/*Object*/p_sender, /*Boolean*/ p_errorState, /*String*/ p_errorMsg, /*String?*/ p_errorDetails){
// summary:
// Shows the given error message in the red error message box within
// the dialog. Optionally, also shows details for the error
// in a white box.
// p_sender: Object
// The widget instance sending this error to this dialog.
// p_errorState: Boolean
// The flag indicating whether the calling widget went into error state, or whether the
// error state was left.
// p_errorMsg: String
// The error message to display
// p_errorDetails: String
// Optional string with a more detailed description of the error
// tags:
// private callback
var m = "_onErrorStateChanged(p_sender, p_errorState, p_errorMsg, p_errorDetails)";
if (this._isTracing) {
this.traceEntry(m, [p_sender, p_errorState, p_errorMsg, p_errorDetails]);
}
if (p_errorState === true) {
this._showError(p_errorMsg, p_errorDetails);
}
else {
if (p_errorState === false) {
this._clearError();
}
else {
// p_errorState is not a Boolean value
}
}
if (this._isTracing) {
this.traceExit(m);
}
},
_clearEventHandlers: function(){
// summary:
// Disconnects the events supported by this dialog from the corresponding callback methods
// tags:
// private
// entry trace
var m = "_clearEventHandlers()";
if (this._isTracing) {
this.traceEntry(m);
}
dojo.forEach(this._eventHandlers, dojo.disconnect);
this._eventHandlers = [];
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
// @OVERRIDE: dijit.Dialog._onKey - handle ESC key for tooltips, or trigger default method, if no tooltip is open
_onKey: function(/*Event*/ p_evt) {
if (p_evt) {
var target = p_evt.target;
if (target) {
var key = p_evt.keyCode; // Space key only sets charCode, keyCode is 0
var keys = dojo.keys;
if (key === keys.ESCAPE) {
// check global WP variable for dijit.Tooltip
if (com.ibm.wps.contentmapping._currentTooltipNode !== null) {
// hide tooltip ...
dijit.Tooltip.hide(com.ibm.wps.contentmapping._currentTooltipNode);
// ... and prevent key event from bubbling up
dojo.stopEvent(p_evt);
} else {
this.inherited(arguments);
}
} else {
this.inherited(arguments);
}
}
}
},
_initEventHandlers: function(){
// summary:
// Connects the events supported by this dialog to the corresponding callback methods
// and stores the Handlers in the _eventHandlers array
// tags:
// private
// entry trace
var m = "_initEventHandlers()";
if (this._isTracing) {
this.traceEntry(m);
}
this._eventHandlers.push(dojo.connect(this.dialogConfirm, "onclick", this, "_onConfirm"));
if (this._widget && (typeof this._widget.onSelectChild == 'function')) {
this._eventHandlers.push(dojo.connect(this._widget, "onSelectChild", this, "layout"));
this._eventHandlers.push(dojo.connect(this._widget, "onLayoutChange", this, "_fixResizeHelper"));
this._eventHandlers.push(dojo.connect(this._widget, "onLayoutChange", this, "layout"));
this._eventHandlers.push(dojo.connect(this._widget, "onClose", this, "close"));
this._eventHandlers.push(dojo.connect(this._widget, "onErrorStateChanged", this, "_onErrorStateChanged"));
}
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_fixResizeHelper: function(){
// summary:
// Workaround for fixing the issue that the domNode of the global ResizeHelper gets destroyed, when
// closing the entity picker dialog. To be able to resize this dialog even after adding a new mapping,
// we re-create a ResizeHelper here.
// entry trace
var m = "_fixResizeHelper()";
if (this._isTracing) {
this.traceEntry(m);
}
// use method from GenericDialog to put ResizeHandler back into place properly
this._recreateResizeHandler();
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
},
_initNLS: function(){
// summary:
// Initializes the aspects for supporting localization, for example, by loading the required NLS bundle(s)
// tags:
// private
// entry trace
var m = "_initNLS()";
if (this._isTracing) {
this.traceEntry(m);
}
this._nlsUserInterface = dojo.i18n.getLocalization("com.ibm.wps.contentmapping", 'ContentMappingPickerUserInterface');
this._nlsMessages = dojo.i18n.getLocalization("com.ibm.wps.contentmapping", 'ContentMappingPickerMessages');
// exit trace
if (this._isTracing) {
this.trace(m, "Initialized NLS object for user interface elements:", dojo.toJson(this._nlsUserInterface));
this.trace(m, "Initialized NLS object for messages:", dojo.toJson(this._nlsMessages));
this.traceExit(m);
}
},
_findOrCreateLotusUIDIV: function() {
// summary:
// Tries to find an existing dijit.Dialog lotusui30 container DIV in the current page
// and if it doesn't find one, creates it.
//
// Used to avoid flooding the DomTree with lotusui30 related wrapper DIVs, if dialogs
// are opened and closed many times.
// returns:
// The domNode reference of the found or created dijit.Dialog lotusui30 container DIV
// tags:
// private
// entry trace
var m = "_findOrCreateLotusUIDIV()";
if (this._isTracing) {
this.traceEntry(m);
}
var lotusui_div = dojo.byId(this.lotusui_id);
if (!lotusui_div) {
lotusui_div = dojo.create("div", { "id": this.lotusui_id,
"class": this.lotusui_class,
"wairole": "region",
"role": "region"
}, dojo.body());
}
// set wai state in any case (whether we re-use an existing or newly created
// wrapping div) to not break Accessibility
dijit.setWaiState(lotusui_div, "labelledby", this.namespace + "GenericDialogTitleSpan_id");
this._lotusui_div = lotusui_div;
// exit trace
if (this._isTracing) {
this.traceExit(m, lotusui_div);
}
return lotusui_div;
},
_showError: function(/*String*/p_errorMsg, /*String?*/ p_errorDetails){
// summary:
// Shows the given error message in the red error message box within
// the dialog. Optionally, also shows details for the error
// in a white box.
// p_errorMsg: String
// The error message to display
// p_errorDetails: String
// Optional string with a more detailed description of the error
// tags:
// private callback
// entry trace
var m = "_showError(p_errorMsg, p_errorDetails)";
if (this._isTracing) {
this.traceEntry(m, [p_errorMsg, p_errorDetails]);
}
var errorStr = "";
if (p_errorMsg) {
if (dojo.isString(p_errorMsg)) {
errorStr = p_errorMsg;
}
else {
if (p_errorMsg.responseText && dojo.isString(p_errorMsg.responseText)) {
errorStr = p_errorMsg.responseText;
}
else {
if (p_errorMsg.message && dojo.isString(p_errorMsg.message)) {
errorStr = p_errorMsg.message;
}
}
}
}
if (errorStr) {
var _errMsg = errorStr.substring(0, Math.min(this._maxErrorChars, errorStr.length));
dojo.attr(this.CMPickerDialogErrorSpan, 'innerHTML', _errMsg);
dojo.style(this.CMPickerDialogErrorDiv, 'opacity', '1');
dojo.style(this.CMPickerDialogErrorDiv, 'display', 'block');
dijit.setWaiState(this.CMPickerDialogErrorDiv, 'hidden', false);
if (p_errorDetails && dojo.isString(p_errorDetails)) {
var _errDetails = p_errorDetails.substring(0, Math.min(this._maxErrorChars, p_errorDetails.length));
dojo.attr(this.CMPickerDialogErrorDetailsSpan, 'innerHTML', _errDetails);
dojo.style(this.CMPickerDialogErrorDetailsDiv, 'display', 'block');
dijit.setWaiState(this.CMPickerDialogErrorDetailsDiv, 'hidden', false);
}
}
else {
this.trace(m, '_showError was called with an undefined error message.');
}
// record error and set error state to true. Need to call _clearError() to
// get out of error state again.
this._errorState = true;
// disable buttons, in case they were showing enabled, but user cannot continue
// because of an error that occurred
// TODO: introduce a function to enable/disable OK Button
// this._enableDisableButtons();
// make sure the dialog looks 'good' after opening the error box
this.layout();
// exit trace
if (this._isTracing) {
this.traceExit(m);
}
}
});
}