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