/** 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 ids 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
\n
\n
\n

\n \n ${nlsHeader}\n \n

\n

\n   \n \n ${nlsLaunchItemManageUI}\n

\n

\n
\n \n ${nlsLegend}\n \n \n \n \n \n \n \n
\n \n ${nlsNoMappings}\n \n
\n

\n
\n
\n
\n
\n
\n
\n
\n
\n
\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
\n
\n  ${_nlsUserInterface.CMPickerDialogWidget.loadingLabel}\n
\n
\n
\n
\n
\n
\n
\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
\n
\n

\n ${nlsDialogTitle}\n

\n \n \"\"\n X\n \n
\n
\n
\n ${nlsDialogMessage}\n
\n
\n \n \n
\n
\n
\n
\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 ${title}\n \n \n \"\"\n \n ?\n \n \n

\n \n \"\"\n \n X\n \n \n
\n \n
\n
\n \"${_nlsUserInterface.CMPickerDialog.errorImgAlt}\"\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); } } }); }