1 /** 2 * Copyright (C) 2005-2010 Alfresco Software Limited. 3 * 4 * This file is part of Alfresco 5 * 6 * Alfresco is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * Alfresco is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 /** 21 * DocumentList Toolbar component. 22 * 23 * @namespace Alfresco 24 * @class Alfresco.DocListToolbar 25 */ 26 (function() 27 { 28 /** 29 * YUI Library aliases 30 */ 31 var Dom = YAHOO.util.Dom, 32 Event = YAHOO.util.Event, 33 Element = YAHOO.util.Element; 34 35 /** 36 * Alfresco Slingshot aliases 37 */ 38 var $html = Alfresco.util.encodeHTML, 39 $combine = Alfresco.util.combinePaths, 40 $siteURL = Alfresco.util.siteURL; 41 42 /** 43 * Preferences 44 */ 45 var PREFERENCES_ROOT = "org.alfresco.share.documentList", 46 PREF_HIDE_NAVBAR = PREFERENCES_ROOT + ".hideNavBar"; 47 48 /** 49 * DocListToolbar constructor. 50 * 51 * @param {String} htmlId The HTML id of the parent element 52 * @return {Alfresco.DocListToolbar} The new DocListToolbar instance 53 * @constructor 54 */ 55 Alfresco.DocListToolbar = function(htmlId) 56 { 57 Alfresco.DocListToolbar.superclass.constructor.call(this, "Alfresco.DocListToolbar", htmlId, ["button", "menu", "container"]); 58 59 // Initialise prototype properties 60 this.selectedFiles = []; 61 this.currentFilter = {}; 62 this.dynamicControls = []; 63 this.doclistMetadata = {}; 64 this.actionsView = "browse"; 65 66 // Decoupled event listeners 67 YAHOO.Bubbling.on("filterChanged", this.onFilterChanged, this); 68 YAHOO.Bubbling.on("deactivateAllControls", this.onDeactivateAllControls, this); 69 YAHOO.Bubbling.on("deactivateDynamicControls", this.onDeactivateDynamicControls, this); 70 YAHOO.Bubbling.on("selectedFilesChanged", this.onSelectedFilesChanged, this); 71 YAHOO.Bubbling.on("userAccess", this.onUserAccess, this); 72 YAHOO.Bubbling.on("doclistMetadata", this.onDoclistMetadata, this); 73 YAHOO.Bubbling.on("showFileUploadDialog", this.onFileUpload, this); 74 YAHOO.Bubbling.on("dropTargetOwnerRequest", this.onDropTargetOwnerRequest, this); 75 YAHOO.Bubbling.on("documentDragOver", this.onDocumentDragOver, this); 76 YAHOO.Bubbling.on("documentDragOut", this.onDocumentDragOut, this); 77 YAHOO.Bubbling.on("registerAction", this.onRegisterAction, this); 78 79 return this; 80 }; 81 82 /** 83 * Extend from Alfresco.component.Base 84 */ 85 YAHOO.extend(Alfresco.DocListToolbar, Alfresco.component.Base); 86 87 /** 88 * Augment prototype with Actions module 89 */ 90 YAHOO.lang.augmentProto(Alfresco.DocListToolbar, Alfresco.doclib.Actions); 91 92 /** 93 * Augment prototype with main class implementation, ensuring overwrite is enabled 94 */ 95 YAHOO.lang.augmentObject(Alfresco.DocListToolbar.prototype, 96 { 97 /** 98 * Object container for initialization options 99 * 100 * @property options 101 * @type object 102 */ 103 options: 104 { 105 /** 106 * Current siteId. 107 * 108 * @property siteId 109 * @type string 110 */ 111 siteId: null, 112 113 /** 114 * ContainerId representing root container 115 * 116 * @property containerId 117 * @type string 118 * @default "documentLibrary" 119 */ 120 containerId: "documentLibrary", 121 122 /** 123 * Number of multi-file uploads before grouping the Activity Post 124 * 125 * @property groupActivitiesAt 126 * @type int 127 * @default 5 128 */ 129 groupActivitiesAt: 5, 130 131 /** 132 * Flag indicating whether navigation bar is visible or not. 133 * 134 * @property hideNavBar 135 * @type boolean 136 */ 137 hideNavBar: false, 138 139 /** 140 * Google Docs enabled/disabled flag. 141 * 142 * @property googleDocsEnabled 143 * @type boolean 144 * @default false 145 */ 146 googleDocsEnabled: false, 147 148 /** 149 * Whether the Repo Browser is in use or not 150 * 151 * @property repositoryBrowsing 152 * @type boolean 153 */ 154 repositoryBrowsing: true, 155 156 /** 157 * Decides it the title shall be displayed next to the name if it contains a value that is different from the name 158 * 159 * @property useTitle 160 * @type boolean 161 * @default true 162 */ 163 useTitle: true 164 }, 165 166 /** 167 * Current path being browsed. 168 * 169 * @property currentPath 170 * @type string 171 */ 172 currentPath: "", 173 174 /** 175 * Current filter to choose toolbar view and populate description. 176 * 177 * @property currentFilter 178 * @type string 179 */ 180 currentFilter: null, 181 182 /** 183 * FileUpload module instance. 184 * 185 * @property fileUpload 186 * @type Alfresco.FileUpload 187 */ 188 fileUpload: null, 189 190 /** 191 * Array of selected states for visible files. 192 * 193 * @property selectedFiles 194 * @type array 195 */ 196 selectedFiles: null, 197 198 /** 199 * Folder Details Url for last breadcrumb 200 * 201 * @property folderDetailsUrl 202 * @type string 203 */ 204 folderDetailsUrl: null, 205 206 /** 207 * Dynamic controls that take part in the deactivateDynamicControls event 208 * 209 * @property dynamicControls 210 * @type array 211 */ 212 dynamicControls: null, 213 214 /** 215 * Metadata returned by doclist data webscript 216 * 217 * @property doclistMetadata 218 * @type object 219 * @default null 220 */ 221 doclistMetadata: null, 222 223 /** 224 * Fired by YUI when parent element is available for scripting. 225 * Component initialisation, including instantiation of YUI widgets and event listener binding. 226 * 227 * @method onReady 228 */ 229 onReady: function DLTB_onReady() 230 { 231 // New Content menu button 232 this.widgets.createContent = Alfresco.util.createYUIButton(this, "createContent-button", this.onCreateContent, 233 { 234 type: "menu", 235 menu: "createContent-menu", 236 lazyloadmenu: false, 237 disabled: true, 238 value: "CreateChildren" 239 }); 240 // Make sure we load sub menu lazily with data on each click 241 var templateNodesMenus = this.widgets.createContent.getMenu().getSubmenus(), 242 templateNodesMenu = templateNodesMenus.length > 0 ? templateNodesMenus[0] : null; 243 if (templateNodesMenu) 244 { 245 templateNodesMenu.subscribe("beforeShow", this.onCreateByTemplateNodeBeforeShow, this, true); 246 templateNodesMenu.subscribe("click", this.onCreateByTemplateNodeClick, this, true); 247 } 248 this.dynamicControls.push(this.widgets.createContent); 249 250 // New Folder button: user needs "create" access 251 this.widgets.newFolder = Alfresco.util.createYUIButton(this, "newFolder-button", this.onNewFolder, 252 { 253 disabled: true, 254 value: "CreateChildren" 255 }); 256 this.dynamicControls.push(this.widgets.newFolder); 257 258 // File Upload button: user needs "CreateChildren" access 259 this.widgets.fileUpload = Alfresco.util.createYUIButton(this, "fileUpload-button", this.onFileUpload, 260 { 261 disabled: true, 262 value: "CreateChildren" 263 }); 264 this.dynamicControls.push(this.widgets.fileUpload); 265 266 // Selected Items menu button 267 this.widgets.selectedItems = Alfresco.util.createYUIButton(this, "selectedItems-button", this.onSelectedItems, 268 { 269 type: "menu", 270 menu: "selectedItems-menu", 271 lazyloadmenu: false, 272 disabled: true 273 }); 274 this.dynamicControls.push(this.widgets.selectedItems); 275 276 // Hide/Show NavBar button 277 this.widgets.hideNavBar = Alfresco.util.createYUIButton(this, "hideNavBar-button", this.onHideNavBar, 278 { 279 type: "checkbox", 280 checked: this.options.hideNavBar 281 }); 282 if (this.widgets.hideNavBar !== null) 283 { 284 this.widgets.hideNavBar.set("title", this.msg(this.options.hideNavBar ? "button.navbar.show" : "button.navbar.hide")); 285 Dom.setStyle(this.id + "-navBar", "display", this.options.hideNavBar ? "none" : "block"); 286 this.dynamicControls.push(this.widgets.hideNavBar); 287 } 288 289 // RSS Feed link button 290 this.widgets.rssFeed = Alfresco.util.createYUIButton(this, "rssFeed-button", null, 291 { 292 type: "link" 293 }); 294 this.dynamicControls.push(this.widgets.rssFeed); 295 296 // Folder Up Navigation button 297 this.widgets.folderUp = Alfresco.util.createYUIButton(this, "folderUp-button", this.onFolderUp, 298 { 299 disabled: true, 300 title: this.msg("button.up") 301 }); 302 this.dynamicControls.push(this.widgets.folderUp); 303 304 // DocLib Actions module 305 this.modules.actions = new Alfresco.module.DoclibActions(); 306 307 // Reference to Document List component 308 this.modules.docList = Alfresco.util.ComponentManager.findFirst("Alfresco.DocumentList"); 309 310 // Preferences service 311 this.services.preferences = new Alfresco.service.Preferences(); 312 313 // Finally show the component body here to prevent UI artifacts on YUI button decoration 314 Dom.setStyle(this.id + "-body", "visibility", "visible"); 315 }, 316 317 318 /** 319 * YUI WIDGET EVENT HANDLERS 320 * Handlers for standard events fired from YUI widgets, e.g. "click" 321 */ 322 323 /** 324 * Create Content menu click handler for create content menu items (not create by template node menu items) 325 * 326 * @method onCreateContent 327 * @param sType {string} Event type, e.g. "click" 328 * @param aArgs {array} Arguments array, [0] = DomEvent, [1] = EventTarget 329 * @param p_obj {object} Object passed back from subscribe method 330 */ 331 onCreateContent: function DLTB_onCreateContent(sType, aArgs, p_obj) 332 { 333 var eventTarget = aArgs[1], 334 anchor = eventTarget.element.getElementsByTagName("a")[0]; 335 336 // Make sure a create content menu item was clicked (not a template node) 337 if (eventTarget.parent === this.widgets.createContent.getMenu() && anchor && anchor.nodeName == "A") 338 { 339 anchor.href = YAHOO.lang.substitute(anchor.href, 340 { 341 nodeRef: this.doclistMetadata.parent.nodeRef 342 }); 343 344 // Portlet fix: parameter might be encoded 345 if (anchor.href.indexOf("%7BnodeRef%7D") !== -1) 346 { 347 anchor.href = anchor.href.replace("%7BnodeRef%7D", encodeURIComponent(this.doclistMetadata.parent.nodeRef)); 348 } 349 } 350 }, 351 352 /** 353 * Create Content Template Node menu beforeShow handler 354 * 355 * @method onCreateByTemplateNodeBeforeShow 356 */ 357 onCreateByTemplateNodeBeforeShow: function DLTB_onCreateByTemplateNodeBeforeShow() 358 { 359 // Display loading message 360 var templateNodesMenu = this.widgets.createContent.getMenu().getSubmenus()[0]; 361 if (templateNodesMenu.getItems().length == 0) 362 { 363 templateNodesMenu.clearContent(); 364 templateNodesMenu.addItem(this.msg("label.loading")); 365 templateNodesMenu.render(); 366 367 // Load template nodes 368 Alfresco.util.Ajax.jsonGet( 369 { 370 url: Alfresco.constants.PROXY_URI + "slingshot/doclib/node-templates", 371 successCallback: 372 { 373 fn: function(response, menu) 374 { 375 var nodes = response.json.data, 376 menuItems = [], 377 name; 378 for (var i = 0, il = nodes.length; i < il; i++) 379 { 380 node = nodes[i]; 381 name = $html(node.name); 382 if (node.title && node.title !== node.name && this.options.useTitle) 383 { 384 name += '<span class="title">(' + $html(node.title) + ')</span>'; 385 } 386 menuItems.push( 387 { 388 text: '<span title="' + $html(node.description) + '">' + name +'</span>', 389 value: node 390 }); 391 } 392 if (menuItems.length == 0) 393 { 394 menuItems.push(this.msg("label.empty")); 395 } 396 templateNodesMenu.clearContent(); 397 templateNodesMenu.addItems(menuItems); 398 templateNodesMenu.render(); 399 }, 400 scope: this 401 } 402 }); 403 } 404 }, 405 406 /** 407 * Create Content Template Node sub menu click handler 408 * 409 * @method onCreateContentTemplateNode 410 * @param sType {string} Event type, e.g. "click" 411 * @param aArgs {array} Arguments array, [0] = DomEvent, [1] = EventTarget 412 * @param p_obj {object} Object passed back from subscribe method 413 */ 414 onCreateByTemplateNodeClick: function DLTB_onCreateContentTemplateNode(sType, aArgs, p_obj) 415 { 416 // Create content based on a template 417 var node = aArgs[1].value, 418 destination = this.doclistMetadata.parent.nodeRef; 419 420 // If node is undefined the loading or empty menu items were clicked 421 if (node) 422 { 423 Alfresco.util.Ajax.jsonPost( 424 { 425 url: Alfresco.constants.PROXY_URI + "slingshot/doclib/node-templates", 426 dataObj: 427 { 428 sourceNodeRef: node.nodeRef, 429 parentNodeRef: destination 430 }, 431 successCallback: 432 { 433 fn: function (response) 434 { 435 // Make sure we get other components to update themselves to show the new content 436 YAHOO.Bubbling.fire("nodeCreated", 437 { 438 name: node.name, 439 parentNodeRef: destination, 440 highlightFile: response.json.name 441 }); 442 } 443 }, 444 successMessage: this.msg("message.create-content-by-template-node.success", node.name), 445 failureMessage: this.msg("message.create-content-by-template-node.failure", node.name) 446 }); 447 } 448 }, 449 450 /** 451 * New Folder button click handler 452 * 453 * @method onNewFolder 454 * @param e {object} DomEvent 455 * @param p_obj {object} Object passed back from addListener method 456 */ 457 onNewFolder: function DLTB_onNewFolder(e, p_obj) 458 { 459 var destination = this.doclistMetadata.parent.nodeRef; 460 461 // Intercept before dialog show 462 var doBeforeDialogShow = function DLTB_onNewFolder_doBeforeDialogShow(p_form, p_dialog) 463 { 464 Dom.get(p_dialog.id + "-dialogTitle").innerHTML = this.msg("label.new-folder.title"); 465 Dom.get(p_dialog.id + "-dialogHeader").innerHTML = this.msg("label.new-folder.header"); 466 }; 467 468 var templateUrl = YAHOO.lang.substitute(Alfresco.constants.URL_SERVICECONTEXT + "components/form?itemKind={itemKind}&itemId={itemId}&destination={destination}&mode={mode}&submitType={submitType}&formId={formId}&showCancelButton=true", 469 { 470 itemKind: "type", 471 itemId: "cm:folder", 472 destination: destination, 473 mode: "create", 474 submitType: "json", 475 formId: "doclib-common" 476 }); 477 478 // Using Forms Service, so always create new instance 479 var createFolder = new Alfresco.module.SimpleDialog(this.id + "-createFolder"); 480 481 createFolder.setOptions( 482 { 483 width: "33em", 484 templateUrl: templateUrl, 485 actionUrl: null, 486 destroyOnHide: true, 487 doBeforeDialogShow: 488 { 489 fn: doBeforeDialogShow, 490 scope: this 491 }, 492 onSuccess: 493 { 494 fn: function DLTB_onNewFolder_success(response) 495 { 496 var folderName = response.config.dataObj["prop_cm_name"]; 497 YAHOO.Bubbling.fire("folderCreated", 498 { 499 name: folderName, 500 parentNodeRef: destination 501 }); 502 Alfresco.util.PopupManager.displayMessage( 503 { 504 text: this.msg("message.new-folder.success", folderName) 505 }); 506 }, 507 scope: this 508 }, 509 onFailure: 510 { 511 fn: function DLTB_onNewFolder_failure(response) 512 { 513 if (response) 514 { 515 var folderName = response.config.dataObj["prop_cm_name"]; 516 Alfresco.util.PopupManager.displayMessage( 517 { 518 text: this.msg("message.new-folder.failure", folderName) 519 }); 520 } 521 else 522 { 523 Alfresco.util.PopupManager.displayMessage( 524 { 525 text: this.msg("message.failure") 526 }); 527 } 528 }, 529 scope: this 530 } 531 }).show(); 532 }, 533 534 /** 535 * File Upload button click handler 536 * 537 * @method onFileUpload 538 * @param e {object} DomEvent 539 * @param p_obj {object|array} Object passed back from addListener method or args from Bubbling event 540 */ 541 onFileUpload: function DLTB_onFileUpload(e, p_obj) 542 { 543 if (this.fileUpload === null) 544 { 545 this.fileUpload = Alfresco.getFileUploadInstance(); 546 } 547 548 // Show uploader for multiple files 549 var multiUploadConfig = 550 { 551 siteId: this.options.siteId, 552 containerId: this.options.containerId, 553 uploadDirectory: this.currentPath, 554 filter: [], 555 mode: this.fileUpload.MODE_MULTI_UPLOAD, 556 thumbnails: "doclib", 557 onFileUploadComplete: 558 { 559 fn: this.onFileUploadComplete, 560 scope: this 561 } 562 }; 563 this.fileUpload.show(multiUploadConfig); 564 565 if (YAHOO.lang.isArray(p_obj) && p_obj[1].tooltip) 566 { 567 var balloon = Alfresco.util.createBalloon(this.fileUpload.uploader.id + "-dialog", 568 { 569 html: p_obj[1].tooltip, 570 width: "30em" 571 }); 572 balloon.show(); 573 574 this.fileUpload.uploader.widgets.panel.hideEvent.subscribe(function() 575 { 576 balloon.hide() 577 }); 578 } 579 }, 580 581 /** 582 * Calls the file Upload button click handler but creates an additional tooltip 583 * with information on Drag-and-Drop as an alternative method for uploading content 584 * 585 * @method onFileUploadWithTooltip 586 * @param e {object} DomEvent 587 * @param p_obj {object} Object passed back from addListener method 588 */ 589 onFileUploadWithTooltip: function DLTB_onFileUploadWithTooltip(e, p_obj) 590 { 591 this.onFileUpload(e, p_obj); 592 }, 593 594 /** 595 * File Upload complete event handler 596 * 597 * @method onFileUploadComplete 598 * @param complete {object} Object literal containing details of successful and failed uploads 599 */ 600 onFileUploadComplete: function DLTB_onFileUploadComplete(complete) 601 { 602 var success = complete.successful.length, activityData, file; 603 if (success > 0) 604 { 605 if (success < (this.options.groupActivitiesAt || 5)) 606 { 607 // Below cutoff for grouping Activities into one 608 for (var i = 0; i < success; i++) 609 { 610 file = complete.successful[i]; 611 activityData = 612 { 613 fileName: file.fileName, 614 nodeRef: file.nodeRef 615 }; 616 this.modules.actions.postActivity(this.options.siteId, "file-added", "document-details", activityData); 617 } 618 } 619 else 620 { 621 // grouped into one message 622 activityData = 623 { 624 fileCount: success, 625 path: this.currentPath, 626 parentNodeRef : this.doclistMetadata.parent.nodeRef 627 }; 628 this.modules.actions.postActivity(this.options.siteId, "files-added", "documentlibrary", activityData); 629 } 630 } 631 }, 632 633 /** 634 * Selected Items button click handler 635 * 636 * @method onSelectedItems 637 * @param sType {string} Event type, e.g. "click" 638 * @param aArgs {array} Arguments array, [0] = DomEvent, [1] = EventTarget 639 * @param p_obj {object} Object passed back from subscribe method 640 */ 641 onSelectedItems: function DLTB_onSelectedItems(sType, aArgs, p_obj) 642 { 643 var domEvent = aArgs[0], 644 eventTarget = aArgs[1]; 645 646 // Check mandatory docList module is present 647 if (this.modules.docList) 648 { 649 // Get the function related to the clicked item 650 var fn = Alfresco.util.findEventClass(eventTarget); 651 if (fn && (typeof this[fn] == "function")) 652 { 653 this[fn].call(this, this.modules.docList.getSelectedFiles()); 654 } 655 } 656 657 Event.preventDefault(domEvent); 658 }, 659 660 /** 661 * Delete Multiple Records. 662 * 663 * @method onActionDelete 664 * @param records {object} Object literal representing one or more file(s) or folder(s) to be actioned 665 */ 666 onActionDelete: function DLTB_onActionDelete(records) 667 { 668 var me = this, 669 fileNames = []; 670 671 for (var i = 0, j = records.length; i < j; i++) 672 { 673 fileNames.push("<span class=\"" + (records[i].jsNode.isContainer ? "folder" : "document") + "\">" + $html(records[i].displayName) + "</span>"); 674 } 675 676 var confirmTitle = this.msg("title.multiple-delete.confirm"), 677 confirmMsg = this.msg("message.multiple-delete.confirm", records.length); 678 679 confirmMsg += "<div class=\"toolbar-file-list\">" + fileNames.join("") + "</div>"; 680 681 Alfresco.util.PopupManager.displayPrompt( 682 { 683 title: confirmTitle, 684 text: confirmMsg, 685 noEscape: true, 686 modal: true, 687 buttons: [ 688 { 689 text: this.msg("button.delete"), 690 handler: function DLTB_onActionDelete_delete() 691 { 692 this.destroy(); 693 me._onActionDeleteConfirm.call(me, records); 694 } 695 }, 696 { 697 text: this.msg("button.cancel"), 698 handler: function DLTB_onActionDelete_cancel() 699 { 700 this.destroy(); 701 }, 702 isDefault: true 703 }] 704 }); 705 }, 706 707 /** 708 * Delete Multiple Records confirmed. 709 * 710 * @method _onActionDeleteConfirm 711 * @param records {array} Array containing records to be deleted 712 * @private 713 */ 714 _onActionDeleteConfirm: function DLTB__onActionDeleteConfirm(records) 715 { 716 var multipleRecords = [], i, ii; 717 for (i = 0, ii = records.length; i < ii; i++) 718 { 719 multipleRecords.push(records[i].jsNode.nodeRef.nodeRef); 720 } 721 722 // Success callback function 723 var fnSuccess = function DLTB__oADC_success(data, records) 724 { 725 var result; 726 var successCount = 0; 727 728 // Did the operation succeed? 729 if (!data.json.overallSuccess) 730 { 731 Alfresco.util.PopupManager.displayMessage( 732 { 733 text: this.msg("message.multiple-delete.failure") 734 }); 735 return; 736 } 737 738 YAHOO.Bubbling.fire("filesDeleted"); 739 740 for (i = 0, ii = data.json.totalResults; i < ii; i++) 741 { 742 result = data.json.results[i]; 743 744 if (result.success) 745 { 746 successCount++; 747 748 YAHOO.Bubbling.fire(result.type == "folder" ? "folderDeleted" : "fileDeleted", 749 { 750 multiple: true, 751 nodeRef: result.nodeRef 752 }); 753 } 754 } 755 756 // Activities, in Site mode only 757 if (Alfresco.util.isValueSet(this.options.siteId)) 758 { 759 var activityData; 760 if (successCount > 0) 761 { 762 if (successCount < this.options.groupActivitiesAt) 763 { 764 // Below cutoff for grouping Activities into one 765 for (i = 0; i < successCount; i++) 766 { 767 activityData = 768 { 769 fileName: data.json.results[i].id, 770 nodeRef: data.json.results[i].nodeRef, 771 path: this.currentPath 772 }; 773 this.modules.actions.postActivity(this.options.siteId, "file-deleted", "documentlibrary", activityData); 774 } 775 } 776 else 777 { 778 // grouped into one message 779 activityData = 780 { 781 fileCount: successCount, 782 path: this.currentPath, 783 parentNodeRef : this.doclistMetadata.parent.nodeRef 784 }; 785 this.modules.actions.postActivity(this.options.siteId, "files-deleted", "documentlibrary", activityData); 786 } 787 } 788 } 789 790 Alfresco.util.PopupManager.displayMessage( 791 { 792 text: this.msg("message.multiple-delete.success", successCount) 793 }); 794 }; 795 796 // Construct the data object for the genericAction call 797 this.modules.actions.genericAction( 798 { 799 success: 800 { 801 callback: 802 { 803 fn: fnSuccess, 804 scope: this, 805 obj: records 806 } 807 }, 808 failure: 809 { 810 message: this.msg("message.multiple-delete.failure") 811 }, 812 webscript: 813 { 814 method: Alfresco.util.Ajax.DELETE, 815 name: "files" 816 }, 817 wait: 818 { 819 message: this.msg("message.multiple-delete.please-wait") 820 }, 821 config: 822 { 823 requestContentType: Alfresco.util.Ajax.JSON, 824 dataObj: 825 { 826 nodeRefs: multipleRecords 827 } 828 } 829 }); 830 }, 831 832 /** 833 * Deselect currectly selected records. 834 * 835 * @method onActionDeselectAll 836 */ 837 onActionDeselectAll: function DLTB_onActionDeselectAll() 838 { 839 if (this.modules.docList) 840 { 841 this.modules.docList.selectFiles("selectNone"); 842 } 843 }, 844 845 /** 846 * Show/Hide navigation bar button click handler 847 * 848 * @method onHideNavBar 849 * @param e {object} DomEvent 850 * @param p_obj {object} Object passed back from addListener method 851 */ 852 onHideNavBar: function DLTB_onHideNavBar(e, p_obj) 853 { 854 this.options.hideNavBar = this.widgets.hideNavBar.get("checked"); 855 this.widgets.hideNavBar.set("title", this.msg(this.options.hideNavBar ? "button.navbar.show" : "button.navbar.hide")); 856 Dom.setStyle(this.id + "-navBar", "display", this.options.hideNavBar ? "none" : "block"); 857 this.services.preferences.set(PREF_HIDE_NAVBAR, this.options.hideNavBar); 858 if (e) 859 { 860 Event.preventDefault(e); 861 } 862 }, 863 864 /** 865 * Folder Up Navigate button click handler 866 * 867 * @method onFolderUp 868 * @param e {object} DomEvent 869 * @param p_obj {object} Object passed back from addListener method 870 */ 871 onFolderUp: function DLTB_onFolderUp(e, p_obj) 872 { 873 var newPath = this.currentPath.substring(0, this.currentPath.lastIndexOf("/")), 874 filter = this.currentFilter; 875 876 filter.filterData = newPath; 877 878 YAHOO.Bubbling.fire("changeFilter", filter); 879 Event.preventDefault(e); 880 }, 881 882 883 /** 884 * BUBBLING LIBRARY EVENT HANDLERS FOR PAGE EVENTS 885 * Disconnected event handlers for inter-component event notification 886 */ 887 888 /** 889 * Filter Changed event handler 890 * 891 * @method onFilterChanged 892 * @param layer {object} Event fired 893 * @param args {array} Event parameters (depends on event type) 894 */ 895 onFilterChanged: function DLTB_onFilterChanged(layer, args) 896 { 897 var obj = args[1]; 898 if (obj && (typeof obj.filterId !== "undefined")) 899 { 900 obj.filterOwner = obj.filterOwner || Alfresco.util.FilterManager.getOwner(obj.filterId); 901 902 if (obj.filterOwner) 903 { 904 if (this.currentFilter.filterOwner != obj.filterOwner || this.currentFilter.filterId != obj.filterId) 905 { 906 var filterOwner = obj.filterOwner.split(".")[1], 907 ownerIdClass = filterOwner + "_" + obj.filterId; 908 909 // Obtain array of DIVs we might want to hide 910 var divs = YAHOO.util.Selector.query('div.hideable', Dom.get(this.id)), div; 911 for (var i = 0, j = divs.length; i < j; i++) 912 { 913 div = divs[i]; 914 if (Dom.hasClass(div, filterOwner) || Dom.hasClass(div, ownerIdClass)) 915 { 916 Dom.removeClass(div, "toolbar-hidden"); 917 } 918 else 919 { 920 Dom.addClass(div, "toolbar-hidden"); 921 } 922 } 923 } 924 } 925 926 Alfresco.logger.debug("DLTB_onFilterChanged", "Old Filter", this.currentFilter); 927 this.currentFilter = Alfresco.util.cleanBubblingObject(obj); 928 Alfresco.logger.debug("DLTB_onFilterChanged", "New Filter", this.currentFilter); 929 930 if (this.currentFilter.filterId == "path" || this.currentFilter.filterId == "category") 931 { 932 this.currentPath = $combine("/", this.currentFilter.filterData); 933 this._generateBreadcrumb(); 934 935 // Enable/disable the Folder Up button 936 var paths = this.currentPath.split("/"); 937 // Check for root path special case 938 if (this.currentPath === "/") 939 { 940 paths = ["/"]; 941 } 942 this.widgets.folderUp.set("disabled", paths.length < 2); 943 } 944 else 945 { 946 this._generateDescription(); 947 } 948 this._generateRSSFeedUrl(); 949 } 950 }, 951 952 /** 953 * Deactivate All Controls event handler 954 * 955 * @method onDeactivateAllControls 956 * @param layer {object} Event fired 957 * @param args {array} Event parameters (depends on event type) 958 */ 959 onDeactivateAllControls: function DLTB_onDeactivateAllControls(layer, args) 960 { 961 var index, fnDisable = Alfresco.util.disableYUIButton; 962 for (index in this.widgets) 963 { 964 if (this.widgets.hasOwnProperty(index)) 965 { 966 fnDisable(this.widgets[index]); 967 } 968 } 969 }, 970 971 /** 972 * Deactivate Dynamic Controls event handler. 973 * Only deactivates those controls whose enabled state is evaluated on each update. 974 * 975 * @method onDeactivateDynamicControls 976 * @param layer {object} Event fired 977 * @param args {array} Event parameters (depends on event type) 978 */ 979 onDeactivateDynamicControls: function DLTB_onDeactivateDynamicControls(layer, args) 980 { 981 var index, fnDisable = Alfresco.util.disableYUIButton; 982 for (index in this.dynamicControls) 983 { 984 if (this.dynamicControls.hasOwnProperty(index)) 985 { 986 fnDisable(this.dynamicControls[index]); 987 } 988 } 989 }, 990 991 /** 992 * User Access event handler 993 * 994 * @method onUserAccess 995 * @param layer {object} Event fired 996 * @param args {array} Event parameters (depends on event type) 997 */ 998 onUserAccess: function DLTB_onUserAccess(layer, args) 999 { 1000 var fnSetWidgetAccess = function DLTB_onUserAccess_fnSetWidgetAccess(p_widget, p_userAccess) 1001 { 1002 var perms, widgetPermissions, orPermissions, orMatch, isMenuItem = false, fnEnable, fnDisable; 1003 if (p_widget instanceof YAHOO.widget.MenuItem && p_widget.element.firstChild) 1004 { 1005 isMenuItem = true; 1006 // MenuItems have to store permission values in the <a> tag's "rel" attribute 1007 perms = p_widget.element.firstChild.rel; 1008 fnEnable = Alfresco.util.bind(p_widget.cfg.setProperty, p_widget.cfg, "className", ""); 1009 fnDisable = Alfresco.util.bind(p_widget.cfg.setProperty, p_widget.cfg, "className", "hidden"); 1010 } 1011 else 1012 { 1013 // Buttons store the permission value in the "value" config variable 1014 perms = p_widget.get("value"); 1015 fnEnable = Alfresco.util.bind(p_widget.set, p_widget, "disabled", false); 1016 fnDisable = Alfresco.util.bind(p_widget.set, p_widget, "disabled", true); 1017 } 1018 // Default to enabled: disabled via missing permission 1019 fnEnable(); 1020 if (typeof perms == "string" && perms !== "") 1021 { 1022 // Comma-separation indicates "AND" 1023 widgetPermissions = perms.split(","); 1024 for (var i = 0, ii = widgetPermissions.length; i < ii; i++) 1025 { 1026 // Pipe-separation is a special case and indicates an "OR" match. The matched permission is stored in "activePermission" on the widget. 1027 if (widgetPermissions[i].indexOf("|") !== -1) 1028 { 1029 orMatch = false; 1030 orPermissions = widgetPermissions[i].split("|"); 1031 for (var j = 0, jj = orPermissions.length; j < jj; j++) 1032 { 1033 if (p_userAccess[orPermissions[j]]) 1034 { 1035 orMatch = true; 1036 if (!isMenuItem) 1037 { 1038 p_widget.set("activePermission", orPermissions[j], true); 1039 } 1040 break; 1041 } 1042 } 1043 if (!orMatch) 1044 { 1045 fnDisable(); 1046 break; 1047 } 1048 } 1049 else if (!p_userAccess[widgetPermissions[i]]) 1050 { 1051 fnDisable(); 1052 break; 1053 } 1054 } 1055 } 1056 }; 1057 1058 var obj = args[1]; 1059 if (obj && obj.userAccess) 1060 { 1061 // Fake permission if Google Docs is enabled via config 1062 if (this.options.googleDocsEnabled) 1063 { 1064 obj.userAccess["create-google-doc"] = true; 1065 } 1066 1067 var widget, index, menuItems; 1068 for (index in this.widgets) 1069 { 1070 if (this.widgets.hasOwnProperty(index)) 1071 { 1072 widget = this.widgets[index]; 1073 // Skip if this action specifies "no-access-check" 1074 if (widget.get("srcelement").className != "no-access-check") 1075 { 1076 fnSetWidgetAccess(widget, obj.userAccess); 1077 if (widget.getMenu() !== null) 1078 { 1079 menuItems = widget.getMenu().getItems(); 1080 for (var j = 0, jj = menuItems.length; j < jj; j++) 1081 { 1082 fnSetWidgetAccess(menuItems[j], obj.userAccess); 1083 } 1084 } 1085 } 1086 } 1087 } 1088 } 1089 }, 1090 1091 /** 1092 * Selected Files Changed event handler. 1093 * Determines whether to enable or disable the multi-file action drop-down 1094 * 1095 * @method onSelectedFilesChanged 1096 * @param layer {object} Event fired 1097 * @param args {array} Event parameters (depends on event type) 1098 */ 1099 onSelectedFilesChanged: function DLTB_onSelectedFilesChanged(layer, args) 1100 { 1101 if (this.modules.docList) 1102 { 1103 var files = this.modules.docList.getSelectedFiles(), fileTypes = [], file, 1104 fileType, userAccess = {}, fileAccess, index, 1105 menuItems = this.widgets.selectedItems.getMenu().getItems(), menuItem, 1106 actionPermissions, typeGroups, typesSupported, disabled, 1107 i, ii, j, jj; 1108 1109 var fnFileType = function fnFileType(file) 1110 { 1111 return (file.isContainer ? "folder" : "document"); 1112 }; 1113 1114 // Check each file for user permissions 1115 for (i = 0, ii = files.length; i < ii; i++) 1116 { 1117 file = files[i]; 1118 1119 // Required user access level - logical AND of each file's permissions 1120 fileAccess = file.node.permissions.user; 1121 for (index in fileAccess) 1122 { 1123 if (fileAccess.hasOwnProperty(index)) 1124 { 1125 userAccess[index] = (userAccess[index] === undefined ? fileAccess[index] : userAccess[index] && fileAccess[index]); 1126 } 1127 } 1128 1129 // Make a note of all selected file types Using a hybrid array/object so we can use both array.length and "x in object" 1130 fileType = fnFileType(file); 1131 if (!(fileType in fileTypes)) 1132 { 1133 fileTypes[fileType] = true; 1134 fileTypes.push(fileType); 1135 } 1136 } 1137 1138 // Now go through the menu items, setting the disabled flag appropriately 1139 for (index in menuItems) 1140 { 1141 if (menuItems.hasOwnProperty(index)) 1142 { 1143 // Defaulting to enabled 1144 menuItem = menuItems[index]; 1145 disabled = false; 1146 1147 if (menuItem.element.firstChild) 1148 { 1149 // Check permissions required - stored in "rel" attribute in the DOM 1150 if (menuItem.element.firstChild.rel && menuItem.element.firstChild.rel !== "") 1151 { 1152 // Comma-separated indicates and "AND" match 1153 actionPermissions = menuItem.element.firstChild.rel.split(","); 1154 for (i = 0, ii = actionPermissions.length; i < ii; i++) 1155 { 1156 // Disable if the user doesn't have ALL the permissions 1157 if (!userAccess[actionPermissions[i]]) 1158 { 1159 disabled = true; 1160 break; 1161 } 1162 } 1163 } 1164 1165 if (!disabled) 1166 { 1167 // Check filetypes supported 1168 if (menuItem.element.firstChild.type && menuItem.element.firstChild.type !== "") 1169 { 1170 // Pipe-separation indicates grouping of allowed file types 1171 typeGroups = menuItem.element.firstChild.type.split("|"); 1172 1173 for (i = 0; i < typeGroups.length; i++) // Do not optimize - bounds updated within loop 1174 { 1175 typesSupported = Alfresco.util.arrayToObject(typeGroups[i].split(",")); 1176 1177 for (j = 0, jj = fileTypes.length; j < jj; j++) 1178 { 1179 if (!(fileTypes[j] in typesSupported)) 1180 { 1181 typeGroups.splice(i, 1); 1182 --i; 1183 break; 1184 } 1185 } 1186 } 1187 disabled = (typeGroups.length === 0); 1188 } 1189 } 1190 menuItem.cfg.setProperty("disabled", disabled); 1191 } 1192 } 1193 } 1194 this.widgets.selectedItems.set("disabled", (files.length === 0)); 1195 } 1196 }, 1197 1198 /** 1199 * Document List Metadata event handler 1200 * NOTE: This is a temporary fix to enable access to the View Details action from the breadcrumb. 1201 * A more complete solution is to present the full list of parent folder actions. 1202 * 1203 * @method onDoclistMetadata 1204 * @param layer {object} Event fired 1205 * @param args {array} Event parameters (depends on event type) 1206 */ 1207 onDoclistMetadata: function DLTB_onDoclistMetadata(layer, args) 1208 { 1209 var obj = args[1]; 1210 this.folderDetailsUrl = null; 1211 if (obj && obj.metadata) 1212 { 1213 this.doclistMetadata = Alfresco.util.deepCopy(obj.metadata); 1214 if (obj.metadata.parent && obj.metadata.parent.nodeRef) 1215 { 1216 this.folderDetailsUrl = $siteURL("folder-details?nodeRef=" + obj.metadata.parent.nodeRef); 1217 } 1218 } 1219 }, 1220 1221 /** 1222 * Handles "dropTargetOwnerRequest" by determining whether or not the target belongs to the breacrumb 1223 * trail, and if it does determines it's path and uses it with the container nodeRef on the callback 1224 * function. 1225 * 1226 * @method onDropTargetOwnerRequest 1227 * @property layer The name of the event 1228 * @property args The event payload 1229 */ 1230 onDropTargetOwnerRequest: function DLTB_onDropTargetOwnerRequest(layer, args) 1231 { 1232 if (args && args[1] && args[1].elementId) 1233 { 1234 var crumb = Dom.get(args[1].elementId); 1235 var trail = Dom.get(this.id + "-breadcrumb"); 1236 if (Dom.isAncestor(trail, crumb)) 1237 { 1238 // The current element is part of the breadcrumb trail. 1239 // Calculate the path by working out its index within the breadcrumb trail 1240 // and then apply that to the path (remembering to compensate for the SPAN 1241 // elements that just contain the ">" separators ! 1242 var targetPath = ""; 1243 var paths = this.currentPath.split("/"); 1244 for (var i = 0, j = trail.children.length; i < j; i++) 1245 { 1246 if (i % 2 == 0) 1247 { 1248 // Only use the current index if it's even (odd indexes indicate 1249 // the SPAN containing the ">" separator character... 1250 targetPath = targetPath + "/" + paths[i/2]; 1251 } 1252 1253 // If we've reached the target element then break out of the loop... 1254 if (crumb == trail.children[i]) 1255 { 1256 break; 1257 } 1258 } 1259 1260 // Use the callback method with a nodeRef built from the the container nodeRef 1261 // concatonated with the constructed path... 1262 var nodeRef = this.doclistMetadata.container + targetPath; 1263 args[1].callback.call(args[1].scope, nodeRef, targetPath); 1264 } 1265 } 1266 }, 1267 1268 /** 1269 * Handles applying the styling and node creation required when a document is dragged 1270 * over a tree node. 1271 * 1272 * @method onDocumentDragOver 1273 * @property layer The name of the event 1274 * @property args The event payload 1275 */ 1276 onDocumentDragOver: function DLTB_onDocumentDragOver(layer, args) 1277 { 1278 if (args && args[1] && args[1].elementId) 1279 { 1280 var crumb = Dom.get(args[1].elementId); 1281 var trail = Dom.get(this.id + "-breadcrumb"); 1282 if (Dom.isAncestor(trail, crumb)) 1283 { 1284 Dom.addClass(crumb, "documentDragOverHighlight"); 1285 var firstCrumbChild = Dom.getFirstChild(crumb); 1286 if (firstCrumbChild != null && firstCrumbChild.tagName != "SPAN") 1287 { 1288 var arrow = document.createElement("span"); 1289 Dom.addClass(arrow, "documentDragOverArrow"); 1290 Dom.insertBefore(arrow, firstCrumbChild); 1291 } 1292 } 1293 } 1294 }, 1295 1296 /** 1297 * Handles applying the styling and node deletion required when a document is dragged 1298 * out of a tree node. 1299 * 1300 * @method onDocumentDragOut 1301 * @property layer The name of the event 1302 * @property args The event payload 1303 */ 1304 onDocumentDragOut: function DLTB_onDocumentDragOut(layer, args) 1305 { 1306 if (args && args[1] && args[1].elementId) 1307 { 1308 var crumb = Dom.get(args[1].elementId); 1309 var trail = Dom.get(this.id + "-breadcrumb"); 1310 if (Dom.isAncestor(trail, crumb)) 1311 { 1312 Dom.removeClass(crumb, "documentDragOverHighlight"); 1313 var firstCrumbChild = Dom.getFirstChild(crumb); 1314 if (firstCrumbChild != null && firstCrumbChild.tagName == "SPAN") 1315 { 1316 crumb.removeChild(firstCrumbChild); 1317 } 1318 } 1319 } 1320 }, 1321 1322 /** 1323 * PRIVATE FUNCTIONS 1324 */ 1325 1326 /** 1327 * Generates the HTML mark-up for the breadcrumb from the currentPath 1328 * 1329 * @method _generateBreadcrumb 1330 * @private 1331 */ 1332 _generateBreadcrumb: function DLTB__generateBreadcrumb() 1333 { 1334 var divBC = Dom.get(this.id + "-breadcrumb"); 1335 if (divBC === null) 1336 { 1337 return; 1338 } 1339 divBC.innerHTML = ""; 1340 1341 var paths = this.currentPath.split("/"); 1342 // Check for root path special case 1343 if (this.currentPath === "/") 1344 { 1345 paths = ["/"]; 1346 } 1347 // Clone the array and re-use the root node name from the DocListTree 1348 var me = this, 1349 displayPaths = paths.concat(); 1350 1351 displayPaths[0] = Alfresco.util.message("node.root", this.currentFilter.filterOwner); 1352 1353 var fnCrumbIconClick = function DLTB__fnCrumbIconClick(e, path) 1354 { 1355 Dom.addClass(e.target.parentNode, "highlighted"); 1356 Event.stopEvent(e); 1357 }; 1358 1359 var fnBreadcrumbClick = function DLTB__fnBreadcrumbClick(e, path) 1360 { 1361 var filter = me.currentFilter; 1362 filter.filterData = path; 1363 1364 YAHOO.Bubbling.fire("changeFilter", filter); 1365 Event.stopEvent(e); 1366 }; 1367 1368 var eBreadcrumb = new Element(divBC), 1369 newPath, 1370 eCrumb, 1371 eIcon, 1372 eFolder; 1373 1374 for (var i = 0, j = paths.length; i < j; ++i) 1375 { 1376 newPath = paths.slice(0, i+1).join("/"); 1377 eCrumb = new Element(document.createElement("div")); 1378 eCrumb.addClass("crumb"); 1379 eCrumb.addClass("documentDroppable"); // This class allows documents to be dropped onto the element 1380 eCrumb.addClass("documentDroppableHighlights"); // This class allows drag over/out events to be processed 1381 1382 // First crumb doesn't get an icon 1383 if (i > 0) 1384 { 1385 eIcon = new Element(document.createElement("a"), 1386 { 1387 href: "#", 1388 innerHTML: " " 1389 }); 1390 eIcon.on("click", fnBreadcrumbClick, newPath); 1391 eIcon.addClass("icon"); 1392 eIcon.addClass("filter-" + $html(this.currentFilter.filterId)); 1393 eCrumb.appendChild(eIcon); 1394 } 1395 1396 // Last crumb is rendered as a link if folderDetailsUrl is available (via doclistMetadata) 1397 if (j - i < 2) 1398 { 1399 eFolder = new Element(document.createElement("span"), 1400 { 1401 innerHTML: (this.folderDetailsUrl) ? '<a href="' + this.folderDetailsUrl + '">' + $html(displayPaths[i]) + '</a>' : $html(displayPaths[i]) 1402 }); 1403 eFolder.addClass("label"); 1404 eCrumb.appendChild(eFolder); 1405 eBreadcrumb.appendChild(eCrumb); 1406 } 1407 else 1408 { 1409 eFolder = new Element(document.createElement("a"), 1410 { 1411 href: "", 1412 innerHTML: $html(displayPaths[i]) 1413 }); 1414 eFolder.addClass("folder"); 1415 eFolder.on("click", fnBreadcrumbClick, newPath); 1416 eCrumb.appendChild(eFolder); 1417 eBreadcrumb.appendChild(eCrumb); 1418 eBreadcrumb.appendChild(new Element(document.createElement("div"), 1419 { 1420 innerHTML: ">", 1421 className: "separator" 1422 })); 1423 } 1424 } 1425 1426 var rootEl = Dom.get(this.id + "-breadcrumb"); 1427 var dndTargets = Dom.getElementsByClassName("crumb", "div", rootEl); 1428 for (var i = 0, j = dndTargets.length; i < j; i++) 1429 { 1430 new YAHOO.util.DDTarget(dndTargets[i]); 1431 } 1432 }, 1433 1434 /** 1435 * Generates the HTML mark-up for the description from the currentFilter 1436 * 1437 * @method _generateDescription 1438 * @private 1439 */ 1440 _generateDescription: function DLTB__generateDescription() 1441 { 1442 var divDesc, eDivDesc, eDescMsg, eDescMore, filterDisplay; 1443 1444 divDesc = Dom.get(this.id + "-description"); 1445 if (divDesc === null) 1446 { 1447 return; 1448 } 1449 1450 while (divDesc.hasChildNodes()) 1451 { 1452 divDesc.removeChild(divDesc.lastChild); 1453 } 1454 1455 // If filterDisplay is provided, then use that instead (e.g. for cases where filterData is a nodeRef) 1456 filterDisplay = typeof this.currentFilter.filterDisplay !== "undefined" ? this.currentFilter.filterDisplay : (this.currentFilter.filterData || ""); 1457 1458 eDescMsg = new Element(document.createElement("div"), 1459 { 1460 innerHTML: this.msg("description." + this.currentFilter.filterId, filterDisplay) 1461 }); 1462 eDescMsg.addClass("message"); 1463 1464 // If filterData is populated and a ".more.filterData" i18n message exists, then use that 1465 var i18n = "description." + this.currentFilter.filterId + ".more", 1466 i18nAlt = i18n + ".filterDisplay"; 1467 1468 if (filterDisplay !== "" && this.msg(i18nAlt) !== i18nAlt) 1469 { 1470 i18n = i18nAlt; 1471 } 1472 1473 eDescMore = new Element(document.createElement("span"), 1474 { 1475 innerHTML: this.msg(i18n, $html(filterDisplay)) 1476 }); 1477 eDescMore.addClass("more"); 1478 1479 eDescMsg.appendChild(eDescMore); 1480 eDivDesc = new Element(divDesc); 1481 eDivDesc.appendChild(eDescMsg); 1482 }, 1483 1484 /** 1485 * Generates the HTML mark-up for the RSS feed link 1486 * 1487 * @method _generateRSSFeedUrl 1488 * @private 1489 */ 1490 _generateRSSFeedUrl: function DLTB__generateRSSFeedUrl() 1491 { 1492 if (this.widgets.rssFeed && this.modules.docList) 1493 { 1494 var params = YAHOO.lang.substitute("{type}/site/{site}/{container}{path}", 1495 { 1496 type: this.modules.docList.options.showFolders ? "all" : "documents", 1497 site: encodeURIComponent(this.options.siteId), 1498 container: encodeURIComponent(this.options.containerId), 1499 path: Alfresco.util.encodeURIPath(this.currentPath) 1500 }); 1501 1502 params += "?filter=" + encodeURIComponent(this.currentFilter.filterId); 1503 if (this.currentFilter.filterData) 1504 { 1505 params += "&filterData=" + encodeURIComponent(this.currentFilter.filterData); 1506 } 1507 params += "&format=rss"; 1508 1509 this.widgets.rssFeed.set("href", Alfresco.constants.URL_FEEDSERVICECONTEXT + "components/documentlibrary/feed/" + params); 1510 Alfresco.util.enableYUIButton(this.widgets.rssFeed); 1511 } 1512 } 1513 }, true); 1514 })();