1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2012, 2013, 2014, 2015, 2016 Synacor, Inc. 5 * 6 * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: https://www.zimbra.com/license 9 * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15 10 * have been added to cover use of software over a computer network and provide for limited attribution 11 * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B. 12 * 13 * Software distributed under the License is distributed on an "AS IS" basis, 14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * See the License for the specific language governing rights and limitations under the License. 16 * The Original Code is Zimbra Open Source Web Client. 17 * The Initial Developer of the Original Code is Zimbra, Inc. All rights to the Original Code were 18 * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015. 19 * 20 * All portions of the code are Copyright (C) 2012, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * @overview 26 * A static helper class used to do most of the stuff related to an item's tags - get the bubbles HTML, add listeners for changes, and inform the view to redraw the new html whenever needed. 27 * The parent view itself will set * the html into the view - this also allows the parent to do special things - for example for empty list of tags in mail message view - hide the "Tags:" row altogether. 28 */ 29 30 ZmTagsHelper = {}; 31 32 ZmTagsHelper.setupListeners = function(view) { 33 34 if (appCtxt.isChildWindow) { 35 return; 36 } 37 // Add change listener to taglist to track changes in tag color, tag name, etc. 38 view._tagList = appCtxt.getTagTree(); 39 if (!view._tagList) { 40 return; 41 } 42 view._tagChangeHandler = ZmTagsHelper._tagChangeListener.bind(view); 43 view._tagList.addChangeListener(view._tagChangeHandler); 44 }; 45 46 ZmTagsHelper.disposeListeners = 47 function(view) { 48 view._tagList && view._tagList.removeChangeListener(view._tagChangeHandler); 49 }; 50 51 /** 52 * gets the tags HTML (the bubbles html) for the item's tags 53 * @param item 54 */ 55 ZmTagsHelper.getTagsHtml = 56 function(item, view) { 57 58 if (!appCtxt.get(ZmSetting.TAGGING_ENABLED)) { 59 return ""; 60 } 61 62 var tags = item && item.getSortedTags(); 63 if (!(tags && tags.length)) { 64 return ""; 65 } 66 67 var html = [], i = 0; 68 for (var j = 0; j < tags.length; j++) { 69 var tag = tags[j]; 70 if (!tag) { 71 continue; 72 } 73 var tagParams = { 74 tag: tag, 75 html: html, 76 i: i, 77 view: view, 78 readOnly: item.isReadOnly() 79 }; 80 i = ZmTagsHelper._getTagHtml(tagParams); 81 } 82 return html.join(""); 83 }; 84 85 ZmTagsHelper._getTagHtml = 86 function(params) { 87 params = params || {}; 88 var tag = params.tag; 89 var html = params.html; 90 var i = params.i; 91 var view = params.view; 92 var readOnly = params.readOnly; 93 94 var tagClick = ['ZmTagsHelper._tagClick("', view._htmlElId, '","', AjxStringUtil.encodeQuotes(tag.name), '");'].join(""); 95 var removeClick = ['ZmTagsHelper._removeTagClick("', view._htmlElId, '","', AjxStringUtil.encodeQuotes(tag.name), '");'].join(""); 96 97 html[i++] = "<span class='addrBubble TagBubble' notoggle=1 >"; 98 99 html[i++] = "<span class='TagImage' onclick='"; 100 html[i++] = tagClick; 101 html[i++] = "'>"; 102 html[i++] = AjxImg.getImageHtml({ 103 imageName: tag.getIconWithColor(), 104 altText: ZmMsg.tag 105 }); 106 html[i++] = "</span>"; 107 108 html[i++] = "<span class='TagName' onclick='"; 109 html[i++] = tagClick; 110 html[i++] = "'>"; 111 html[i++] = AjxStringUtil.htmlEncodeSpace(tag.name); 112 html[i++] = " </span>"; 113 114 if (!readOnly) { 115 html[i++] = "<span class='ImgBubbleDelete' onclick='"; 116 html[i++] = removeClick; 117 html[i++] = "'>"; 118 html[i++] = "</span>"; 119 } 120 html[i++] = "</span>"; 121 122 return i; 123 }; 124 125 126 ZmTagsHelper._tagClick = 127 function(parentId, tagName) { 128 if (appCtxt.isChildWindow) { 129 return; 130 } 131 var tag = ZmTagsHelper._getTagClicked(tagName); 132 var view = DwtControl.fromElementId(parentId); 133 appCtxt.getSearchController().search({query: tag.createQuery(), inclSharedItems: true}); 134 }; 135 136 ZmTagsHelper._removeTagClick = 137 function(parentId, tagName) { 138 var tag = ZmTagsHelper._getTagClicked(tagName); 139 var view = DwtControl.fromElementId(parentId); 140 ZmListController.prototype._doTag.call(view._controller, view._item, tag, false); 141 }; 142 143 ZmTagsHelper._getTagClicked = 144 function(tagName) { 145 var tagList = appCtxt.getAccountTagList(); 146 return tagList.getByNameOrRemote(tagName); 147 }; 148 149 ZmTagsHelper._tagChangeListener = 150 function(ev) { 151 //note - "this" is bound to the view. 152 if (ev.type != ZmEvent.S_TAG) { return; } 153 if (this._disposed) { return; } 154 155 if (ev.event == ZmEvent.E_DELETE || ev.event == ZmEvent.E_MODIFY || ev.event == ZmEvent.E_CREATE) { 156 //note - create is needed in case of a tag that was not in local tag list (due to sharing) that now is. 157 this._setTags(); 158 } 159 }; 160 161 162 163