1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2010, 2011, 2012, 2013, 2014, 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) 2010, 2011, 2012, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 ZmPreviewPaneView = function(parent, controller, dropTgt) {
 25 
 26 	if (arguments.length == 0) { return; }
 27 
 28     var params = {};
 29     params.className = params.className || "ZmPreviewPaneView";
 30     params.parent = parent;
 31     params.controller = controller;
 32     params.posStyle = Dwt.ABSOLUTE_STYLE;
 33     DwtComposite.call(this, params);
 34 
 35 	this._controller = controller;
 36 
 37 	this._vertMsgSash = new DwtSash({parent:this, style:DwtSash.HORIZONTAL_STYLE, className:"AppSash-horiz",
 38 									 threshold:ZmPreviewPaneView.SASH_THRESHOLD, posStyle:Dwt.ABSOLUTE_STYLE});
 39 	this._vertMsgSash.registerCallback(this._sashCallback, this);
 40 
 41 	this._horizMsgSash = new DwtSash({parent:this, style:DwtSash.VERTICAL_STYLE, className:"AppSash-vert",
 42 									  threshold:ZmPreviewPaneView.SASH_THRESHOLD, posStyle:Dwt.ABSOLUTE_STYLE});
 43 	this._horizMsgSash.registerCallback(this._sashCallback, this);
 44 
 45 	this._previewView = new ZmPreviewView({parent:this, posStyle:DwtControl.ABSOLUTE_STYLE, controller: this._controller});
 46 	
 47     this._detailListView = new ZmDetailListView(this, this._controller, this._controller._dropTgt );
 48     this._detailListView.addSelectionListener(new AjxListener(this, this._listSelectionListener));
 49     this._listSelectionShortcutDelayAction = new AjxTimedAction(this, this._listSelectionTimedAction);
 50     this._delayedSelectionItem = null;
 51 	this.setReadingPane();
 52 };
 53 
 54 ZmPreviewPaneView.prototype = new DwtComposite;
 55 ZmPreviewPaneView.prototype.constructor = ZmPreviewPaneView;
 56 ZmPreviewPaneView.LIST_SELECTION_SHORTCUT_DELAY = 300;
 57 
 58 ZmPreviewPaneView.prototype.toString =
 59 function() {
 60 	return "ZmPreviewPaneView";
 61 };
 62 
 63 // consts
 64 
 65 ZmPreviewPaneView.SASH_THRESHOLD = 5;
 66 ZmPreviewPaneView._TAG_IMG = "TI";
 67 
 68 // public methods
 69 
 70 ZmPreviewPaneView.prototype.getController =
 71 function() {
 72 	return this._controller;
 73 };
 74 
 75 ZmPreviewPaneView.prototype.getTitle =
 76 function() {
 77 	return this._detailListView.getTitle();
 78 };
 79 
 80 ZmPreviewPaneView.prototype.getListView =
 81 function() {
 82 	return this._detailListView;
 83 };
 84 
 85 /**
 86  * Displays the reading pane, based on the current settings.
 87  */
 88 ZmPreviewPaneView.prototype.setReadingPane =
 89 function() {
 90 
 91 	var tlv = this._detailListView, tv = this._previewView;
 92 	var readingPaneEnabled = this._controller.isReadingPaneOn();
 93 	if (!readingPaneEnabled) {
 94 		tv.setVisible(false);
 95 		this._vertMsgSash.setVisible(false);
 96 		this._horizMsgSash.setVisible(false);
 97 	} else {		
 98 		tv.setVisible(true);
 99 		var readingPaneOnRight = this._controller.isReadingPaneOnRight();
100 		var newSash = readingPaneOnRight ? this._vertMsgSash : this._horizMsgSash;
101 		var oldSash = readingPaneOnRight ? this._horizMsgSash : this._vertMsgSash;
102 		oldSash.setVisible(false);
103 		newSash.setVisible(true);
104 	}
105 
106 	tlv.reRenderListView();
107 
108 
109 	tv.noTab = !readingPaneEnabled || AjxEnv.isIE;
110 	var sz = this.getSize();
111 	this._resetSize(sz.x, sz.y, true);
112 };
113 
114 ZmPreviewPaneView.prototype.reRenderListView =
115 function(force){
116     var tlv = this._detailListView;
117     tlv.reRenderListView(force  );
118     var sz = this.getSize();
119 	this._resetSize(sz.x, sz.y, true);
120 };
121 
122 ZmPreviewPaneView.prototype.enableRevisionView =
123 function(enabled){
124     this._detailListView.enableRevisionView(enabled);    
125 };
126 
127 ZmPreviewPaneView.prototype.isRevisionViewEnabled =
128 function(){
129     return this._detailListView._revisionView;  
130 };
131 
132 ZmPreviewPaneView.prototype.resetPreviewPane =
133 function(newPreviewStatus, oldPreviewStatus){
134 
135 	this._detailListView._colHeaderActionMenu = null;  //action menu needs to be recreated as it's different for different views
136 
137     this.setReadingPane();
138 
139     if(oldPreviewStatus == ZmSetting.RP_OFF){
140         var items = this.getSelection();
141         if(items.length > 0){
142             this._previewView.set(items[0]);
143         }else{
144             this._selectFirstItem();
145         }
146     }
147     
148 };
149 
150 ZmPreviewPaneView.prototype.getPreviewView =
151 function() {
152 	return this._previewView;
153 };
154 
155 ZmPreviewPaneView.prototype.getSelectionCount =
156 function() {
157 	return this._detailListView.getSelectionCount();
158 };
159 
160 ZmPreviewPaneView.prototype.getSelection =
161 function() {
162 	return this._detailListView.getSelection();
163 };
164 
165 ZmPreviewPaneView.prototype.reset =
166 function() {
167 	this._detailListView.reset();
168 	this._previewView.reset();
169 };
170 
171 ZmPreviewPaneView.prototype.isPreviewPaneVisible =
172 function() {
173 	return this._previewView.getVisible();
174 };
175 
176 ZmPreviewPaneView.prototype.setBounds =
177 function(x, y, width, height) {
178 	DwtComposite.prototype.setBounds.call(this, x, y, width, height);
179 	this._resetSize(width, height);
180 };
181 
182 ZmPreviewPaneView.prototype._resetSize =
183 function(newWidth, newHeight, force) {
184 
185 
186 	if (newWidth <= 0 || newHeight <= 0) { return; }
187 	if (!force && newWidth == this._lastResetWidth && newHeight == this._lastResetHeight) { return; }
188 
189 	var readingPaneOnRight = this._controller.isReadingPaneOnRight();
190 
191 	if (this.isPreviewPaneVisible()) {
192 		var sash = this.getSash();
193 		var sashSize = sash.getSize();
194 		var sashThickness = readingPaneOnRight ? sashSize.x : sashSize.y;
195 		if (readingPaneOnRight) {
196 			var listViewWidth = this._vertSashX || (Number(ZmMsg.LISTVIEW_WIDTH)) || Math.floor(newWidth / 2.5);
197 			this._detailListView.resetSize(listViewWidth, newHeight);
198 			sash.setLocation(listViewWidth, 0);
199 			this._previewView.setBounds(listViewWidth + sashThickness, 0,
200 									newWidth - (listViewWidth + sashThickness), newHeight);
201 		} else {
202 			var listViewHeight = this._horizSashY || (Math.floor(newHeight / 2) - DwtListView.HEADERITEM_HEIGHT);
203 			this._detailListView.resetSize(newWidth, listViewHeight);
204 			sash.setLocation(0, listViewHeight);
205 			this._previewView.setBounds(0, listViewHeight + sashThickness, newWidth,
206 									newHeight - (listViewHeight + sashThickness));
207 		}
208 	} else {
209 		this._detailListView.resetSize(newWidth, newHeight);
210 	}
211 	this._detailListView._resetColWidth();
212 
213 	this._lastResetWidth = newWidth;
214 	this._lastResetHeight = newHeight;
215 };
216 
217 ZmPreviewPaneView.prototype._sashCallback =
218 function(delta) {
219 
220 	var readingPaneOnRight = this._controller.isReadingPaneOnRight();
221 	if (delta > 0) {
222 		if (readingPaneOnRight) {
223 			// moving sash right
224 			var minMsgViewWidth = 300;
225 			var currentMsgWidth = this._previewView.getSize(true).x;
226 			delta = Math.max(0, Math.min(delta, currentMsgWidth - minMsgViewWidth));
227 			var newListWidth = ((AjxEnv.isIE) ? this._vertMsgSash.getLocation().x : this._detailListView.getSize(true).x) + delta;
228 			if (delta > 0) {
229 				this._detailListView.resetSize(newListWidth, Dwt.DEFAULT);
230 				this._previewView.setBounds(this._previewView.getLocation().x + delta, Dwt.DEFAULT,
231 										currentMsgWidth - delta, Dwt.DEFAULT);
232 				
233 			} else {
234 				delta = 0;
235 			}
236 			
237 			
238 			
239 		} else {
240 			// moving sash down
241 			var newMsgViewHeight = this._previewView.getSize().y - delta;
242 			var minMsgViewHeight = 150;
243 			if (newMsgViewHeight > minMsgViewHeight) {
244 				this._detailListView.resetSize(Dwt.DEFAULT, this._detailListView.getSize(true).y + delta);
245 				this._previewView.setBounds(Dwt.DEFAULT, this._previewView.getLocation().y + delta,
246 							Dwt.DEFAULT, newMsgViewHeight);
247 			} else {
248 				delta = 0;
249 			}
250 		}
251 	} else {
252 		var absDelta = Math.abs(delta);
253 
254 		if (readingPaneOnRight) {
255 			// moving sash left
256 			var currentWidth = this._vertMsgSash.getLocation().x;
257 			absDelta = Math.max(0, Math.min(absDelta, currentWidth - 300));
258 
259 			if (absDelta > 0) {
260 				delta = -absDelta;
261 				this._detailListView.resetSize(currentWidth - absDelta, Dwt.DEFAULT);
262 				this._previewView.setBounds(this._previewView.getLocation().x - absDelta, Dwt.DEFAULT,
263 						this._previewView.getSize(true).x + absDelta, Dwt.DEFAULT);
264 			} else {
265 				delta = 0;
266 			}
267 		} else {
268 			// moving sash up
269 			if (!this._minMLVHeight) {
270 				var list = this._detailListView.getList();
271 				if (list && list.size()) {
272 					var item = list.get(0);
273 					var div = document.getElementById(this._detailListView._getItemId(item));
274 					this._minMLVHeight = DwtListView.HEADERITEM_HEIGHT + (Dwt.getSize(div).y * 2);
275 				} else {
276 					this._minMLVHeight = DwtListView.HEADERITEM_HEIGHT;
277 				}
278 			}
279 
280 			if (this.getSash().getLocation().y - absDelta > this._minMLVHeight) {
281 				// moving sash up
282 				this._detailListView.resetSize(Dwt.DEFAULT, this._detailListView.getSize(true).y - absDelta);
283 				this._previewView.setBounds(Dwt.DEFAULT, this._previewView.getLocation().y - absDelta,
284 						Dwt.DEFAULT, this._previewView.getSize(true).y + absDelta);
285 			} else {
286 				delta = 0;
287 			}
288 		}
289 	}
290 
291 	if (delta) {
292 		this._detailListView._resetColWidth();
293 		if (readingPaneOnRight) {
294 			this._vertSashX = this._vertMsgSash.getLocation().x;
295 		} else {
296 			this._horizSashY = this._horizMsgSash.getLocation().y;
297 		}
298 	}
299 
300 	return delta;
301 };
302 
303 ZmPreviewPaneView.prototype._selectFirstItem =
304 function() {
305 	var list = this._detailListView.getList();
306 	var selectedItem = list ? list.get(0) : null;
307 	if (selectedItem && !selectedItem.isFolder) {
308 		this._detailListView.setSelection(selectedItem);
309 	}else{
310         this._previewView.enablePreview(false);
311     }
312 };
313 
314 ZmPreviewPaneView.prototype.getSash =
315 function() {
316 	var readingPaneOnRight = this._controller.isReadingPaneOnRight();
317 	return readingPaneOnRight ? this._vertMsgSash : this._horizMsgSash;
318 };
319 
320 ZmPreviewPaneView.prototype.getLimit =
321 function(offset) {
322 	return this._detailListView.getLimit(offset);
323 };
324 
325 ZmPreviewPaneView.prototype.set =
326 function(list, sortField) {
327 	this._detailListView.set(list, sortField);
328     var list = this._detailListView._zmList;
329     if(list)
330         list.addChangeListener(new AjxListener(this, this._listViewChangeListener));
331     this._previewView.set(null);
332 };
333 
334 ZmPreviewPaneView.prototype._listViewChangeListener =
335 function(ev){
336    
337     var item = this._detailListView.getSelection();
338     item = item && item[0];
339     if(item){
340          this._listSelectionListener(ev, item);
341     }else{
342          this._previewView.enablePreview(false);
343     }
344     
345 };
346 
347 ZmPreviewPaneView.prototype._listSelectionTimedAction =
348 function() {
349 	if(!this._delayedSelectionItem) {
350 		return;
351 	}
352 	if (this._listSelectionShortcutDelayActionId) {
353 		AjxTimedAction.cancelAction(this._listSelectionShortcutDelayActionId);
354 	}
355 	this._previewView.set(this._delayedSelectionItem);
356 };
357 
358 ZmPreviewPaneView.prototype._listSelectionListener = function(ev, item) {
359 
360     var item = item || ev.item;
361     if (!item) {
362     	return;
363     }
364 
365     var cs = appCtxt.isOffline && appCtxt.getCurrentSearch();
366     if (cs) {
367         appCtxt.accountList.setActiveAccount(item.getAccount());
368     }
369     var noChange = ev && ev._details && ev._details.oldFolderId == item.folderId;
370     // Ignore (no preview change) if move to same folder, deletion, or multi-select (shift key)
371     if ((ev.event === ZmEvent.E_MOVE && noChange) || ev.event === ZmEvent.E_DELETE || ev.shiftKey) {
372         return;
373     }
374 
375     if(ev.field == ZmItem.F_EXPAND && this._detailListView._isExpandable(item)){
376         this._detailListView.expandItem(item);   
377     } else if(this._controller.isReadingPaneOn() && item){
378     	if (ev.kbNavEvent) {
379     		if (this._listSelectionShortcutDelayActionId) {
380     			AjxTimedAction.cancelAction(this._listSelectionShortcutDelayActionId); 
381     		}
382     		this._delayedSelectionItem = item;
383     		this._listSelectionShortcutDelayActionId = AjxTimedAction.scheduleAction(this._listSelectionShortcutDelayAction,
384     				ZmPreviewPaneView.LIST_SELECTION_SHORTCUT_DELAY)
385     	} else {
386     		this._previewView.set(item);
387     	}
388     }
389 };
390 
391 ZmPreviewPaneView.prototype._toggle =
392 function(item){
393     if(this._detailListView._expanded[item.id]){
394         this._detailListView.collapse(item);
395     }else{
396         this._expand(item);
397     }   
398 };
399 
400 ZmPreviewPaneView.prototype._expand =
401 function(item){
402     var handleCallback = new AjxCallback(this, this._handleVersions, item);
403     if(item && item instanceof ZmBriefcaseItem)
404         item.getRevisions(handleCallback);
405 };
406 
407 ZmPreviewPaneView.prototype._handleVersions =
408 function(item, result){
409     result =  result.getResponse();
410     result = result.ListDocumentRevisionsResponse.doc;
411 
412     var revisions = this._getRevisionItems(item, result);
413     this._detailListView.expand(item, revisions);
414 };
415 
416 ZmPreviewPaneView.prototype._getRevisionItems =
417 function(item, revisions){
418     var revisionItems = [];
419     for(var i=0; i<revisions.length; i++){
420         var rev = revisions[i];
421         var rItem = new ZmRevisionItem(this._getRevisionId(rev), item);
422         rItem.set(rev);
423         revisionItems.push(rItem);
424     }
425     return AjxVector.fromArray(revisionItems);
426 };
427 
428 ZmPreviewPaneView.prototype._getRevisionId =
429 function(rev){
430     return ( rev.id +'_'+(rev.version||rev.ver));    
431 };
432 
433 
434 ZmPreviewPaneView.prototype._restoreVerListener =
435 function(){
436     var items = this._detailListView.getSelection();
437     if(!items || items.length == 0) return;
438     var verItem = items[0];
439     this.restoreVersion(verItem);
440 };
441 
442 ZmPreviewPaneView.prototype.restoreVersion =
443 function(verItem){
444     if(verItem.isRevision){
445         var item =  verItem.parent;
446         if(item && item.version != verItem.revision ){
447             item.restoreVersion(verItem.version, new AjxCallback(this, this.refreshItem, item));
448         }
449     }
450 };
451 
452 ZmPreviewPaneView.prototype.deleteVersions =
453 function(items){
454     items = items || this._detailListView.getSelection();
455     if(!items || items.length == 0) return;
456 
457     var delVerBatchCmd = new ZmBatchCommand(true, null, true);
458     for(var i=0; i<items.length; i++){
459         delVerBatchCmd.add(new AjxCallback(this, this.deleteVersion, [items[i], delVerBatchCmd]));
460     }
461     delVerBatchCmd.run();
462 };
463 
464 ZmPreviewPaneView.prototype.deleteVersion =
465 function(verItem, batchCmd){
466     if(verItem.isRevision){
467         var item =  verItem.parent;
468         if(item && item.version != verItem.revision ){
469             item.deleteVersion(verItem.version, new AjxCallback(this, this.refreshItem, item), batchCmd);
470         }
471     }
472 };
473 
474 ZmPreviewPaneView.prototype.refreshItem =
475 function(item){
476     this._detailListView.collapse(item, true);    
477     this._expand(item);
478 };
479 
480 
481 //ZmPreviewView
482 
483 /**
484  * @overview
485  * This file contains the Preview Pane View.
486  */
487 
488 /**
489  * Creates a Preview view.
490  * @class
491  * This class represents the contact split view.
492  *
493  * @param	{Hash}	params		a hash of parameters
494  * @extends	DwtComposite
495  */
496 
497 ZmPreviewView = function(params){
498 
499     if (arguments.length == 0) { return; }
500 
501     this._controller = params.controller;
502 	params.className = params.className || "ZmPreviewView";
503     params.posStyle = Dwt.ABSOLUTE_STYLE;
504 	DwtComposite.call(this, params);
505 
506     this._initialize();
507 
508 };
509 
510 ZmPreviewView.prototype = new DwtComposite;
511 ZmPreviewView.prototype.constructor = ZmPreviewView;
512 
513 ZmPreviewView.prototype.toString = 
514 function() {
515 	return "ZmPreviewView";	
516 };
517 
518 ZmPreviewView.prototype._initialize =
519 function(){
520 
521     var htmlElId = this.getHTMLElId();
522     this.getHtmlElement().innerHTML = AjxTemplate.expand("briefcase.Briefcase#PreviewView", {id:htmlElId});
523 
524     this._headerEl = document.getElementById(htmlElId+"_header");
525     this._bodyEl   = document.getElementById(htmlElId+"_body");
526     this._containerEl   = document.getElementById(htmlElId+"_container");
527 
528     //Create DWT IFrame
529     var params = {
530 		parent: this,
531 		className: "PreviewFrame",
532 		id: htmlElId + "_iframe",
533 		hidden: false,
534 		html: AjxTemplate.expand("briefcase.Briefcase#NoPreview", {id:htmlElId}),
535 		noscroll: false,
536 		posStyle: DwtControl.STATIC_STYLE
537 	};
538 	
539 	
540 	this._iframePreview = new DwtIframe(params);
541 	this._iframePreviewId = this._iframePreview.getIframe().id;
542 
543     this._iframePreview.reparentHtmlElement(this._bodyEl);
544 
545     this._previewContainer = document.getElementById(htmlElId+"_filepreview");
546     this._noresultContainer = document.getElementById(htmlElId+"_noitem");
547 
548     //Header Elements
549     this._headerName = document.getElementById(this._htmlElId+"_name");
550     this._headerImage = document.getElementById(this._htmlElId+"_image");   
551 
552     this._headerCreated = document.getElementById(this._htmlElId+"_created");
553     this._headerCreator = document.getElementById(this._htmlElId+"_creator");
554     this._headerModified = document.getElementById(this._htmlElId+"_modified");
555     this._headerModifier = document.getElementById(this._htmlElId+"_modifier");
556     this._headerLockTime = document.getElementById(this._htmlElId+"_lockTime");
557     this._headerLockUser = document.getElementById(this._htmlElId+"_lockUser");
558 
559     this._headerNotesSection = document.getElementById(this._htmlElId+"_notes_section");
560     this._headerNotes = document.getElementById(this._htmlElId+"_notes");
561     this._headerExpand = document.getElementById(this._htmlElId+"_expand");
562 
563     this._lockStatus = document.getElementById(this._htmlElId+"_lock");
564 
565     Dwt.setHandler(this._headerExpand, DwtEvent.ONCLICK, AjxCallback.simpleClosure(this._toggleExpand, this));
566 
567     this._iframePreview.getIframe().onload = AjxCallback.simpleClosure(this._updatePreview, this);
568 
569     DwtShell.getShell(window).addControlListener(new AjxListener(this, function() { return this._onResize.apply(this, arguments); }));
570     this.addControlListener(new AjxListener(this, function() { return this._onResize.apply(this, arguments); }));
571 };
572 
573 ZmPreviewView._errorCallback =
574 function(errorCode, error){
575 
576     var previewView = window._zmPreviewView;
577     previewView._handleError(previewView._previewItem, errorCode, error);
578 
579 };
580 
581 ZmPreviewView.prototype._handleError =
582 function(item, errorCode, error){
583 
584     this.enablePreview(true);
585 
586     if(item){
587 
588         var restUrl = item.getRestUrl();
589         restUrl = AjxStringUtil.fixCrossDomainReference(restUrl);
590 
591         //Try to generate, otherwise fallback
592         if(ZmMimeTable.isRenderable(item.contentType)){
593             this._iframePreview.setSrc(restUrl);
594         }else if(ZmMimeTable.isMultiMedia(item.contentType)){
595             html = [
596                 "<div style='height:100%;width:100%;text-align:center;vertical-align:middle;padding-top:30px;'>",
597                 "<embed src='",restUrl,"'/>",
598                 "</div>"
599             ].join('');
600             this._iframePreview.setIframeContent(html);
601         }else{
602             //Show Download Link
603             var downloadLink = restUrl + (restUrl.match(/\?/) ? '&' : '?') + "disp=a";
604             var html = [
605                 "<div style='height:100%;width:100%;text-align:center;vertical-align:middle;padding-top:30px;font-family: \'Helvetica Neue\',Helvetica,Arial,\'Liberation Sans\',sans-serif;'>",
606                     AjxMessageFormat.format(ZmMsg.previewDownloadLink, downloadLink),
607                 "</div>"
608             ].join('');
609             this._iframePreview.setIframeContent(html);
610         }
611         
612     }    
613 };        
614 
615 ZmPreviewView.prototype._setupErrorCallback =
616 function(url){
617 
618     if(!window._zmPreviewView)
619         window._zmPreviewView = this;
620 
621     url = url + ( url.match(/\?/) ? '&' : '?' ) + "callback=ZmPreviewView._errorCallback";
622 
623     return url;
624 };
625 
626 ZmPreviewView.prototype.set = function(item) {
627 
628     if (!item){
629         this.enablePreview(false);
630         return;
631     }
632 
633     if (item === this._previewItem) {
634         return;
635     }
636 
637     this._oldItem = this._previewItem;
638     this._previewItem = item;
639     this.enablePreview(true);
640 
641     this._previewContent = false;
642 
643     if (item.isFolder) {
644         this._setFolder(item);
645         return;
646     }
647 
648 
649     this._setHeader(item);
650 
651     var restUrl = item.getRestUrl();
652     restUrl = AjxStringUtil.fixCrossDomainReference(restUrl);
653 
654     if (ZmMimeTable.isWebDoc(item.contentType)) {
655         restUrl = restUrl + ( restUrl.match(/\?/) ? '&' : '?' ) + "viewonly=1";
656     }
657     else {
658 
659         this._setupLoading();
660 
661         //Send everything trough ConvertD
662         restUrl = this._setupErrorCallback(restUrl);
663         restUrl += ( restUrl.match(/\?/) ? '&' : '?' ) + "fmt=native&view=html";
664     }
665 
666     this._iframePreview.setSrc(restUrl);
667 	Dwt.setLoadedTime("ZmBriefcaseItem"); //iframe src set but item may not be downloaded by browser
668 };
669 
670 ZmPreviewView.prototype._setupLoading =
671 function(){
672 
673     var html = [
674         "<div style='height:100%;width:100%;text-align:center;vertical-align:middle;padding-top:30px;'>",ZmMsg.generatingPreview,"</div>"
675     ].join('');
676     try{
677         this._iframePreview.setIframeContent(html);
678     }catch(ex){
679         //At times the previous item is not loaded or in the process of loading, causes iframe.body to be null.
680         DBG.println("ZmPreviewView#_setupLoading");
681         DBG.println("New Item:"+ this._previewItem.name );
682 		DBG.println("  "+ex);
683     }
684 };
685 
686 ZmPreviewView.prototype._resetIframeHeight =
687 function(){
688     var iframe = this._iframePreview.getIframe();
689     var doc = this._iframePreview.getDocument();
690     var origHeight = AjxEnv.isIE ? doc.body.scrollHeight : 0;
691     var h = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight, origHeight);
692     iframe.style.height = h + "px";
693     if (AjxEnv.isWebKitBased) {
694         // bug: 39434, WebKit specific
695         // After the iframe ht is set there is change is body.scrollHeight, weird.
696         // So reset ht to make the entire body visible.
697         var newHt = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight);
698         if (newHt > h) {
699             iframe.style.height = newHt + "px";
700         }
701     }
702 };
703 
704 ZmPreviewView.prototype._setFolder =
705 function(item){
706 
707     this._cleanup();
708     //Name
709     this._headerName.innerHTML = AjxStringUtil.htmlEncode(item.name);
710     //Briefcase icon
711     this._headerImage.className = "ImgBriefcase_48";
712     if(this._headerModifier)
713         this._headerModifier.innerHTML = item.getOwner();
714     this._setIframeContent(AjxTemplate.expand('briefcase.Briefcase#FolderPreview'));
715 };
716 
717 ZmPreviewView.prototype._setIframeContent =
718 function(html){
719     this._previewContent = html;
720     this._iframePreview.setSrc('javascript:\"\";');
721 };
722 
723 ZmPreviewView.prototype._updatePreview =
724 function(){
725     if(this._previewContent){
726         this._iframePreview.setIframeContent(this._previewContent);
727         this._previewContent = false;
728     }
729 	else {
730 	    var iframeDoc = this._iframePreview && this._iframePreview.getDocument();
731 	    if (!iframeDoc) {
732 		    return;
733 	    }
734 	    this._iframePreview._resetEventHandlers();  //for resizing reading pane on right
735         var images = iframeDoc && iframeDoc.getElementsByTagName("img");
736 	    if (images && images.length) {
737 		    for (var i = 0; i <images.length; i++) {
738 			    var dfsrc = images[i].getAttribute("dfsrc");
739 			    if (dfsrc && dfsrc.match(/https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w\_\.]*(\?\S+)?)?)?/)) {
740 				    // Fix for IE: Over HTTPS, http src urls for images might cause an issue.
741 				    try {
742 					    images[i].src = ''; //unload it first
743 					    images[i].src = dfsrc;
744 				    } catch (ex) {
745 					    // do nothing
746 				    }
747 			    }
748 		    }
749 	    }
750     }
751 };
752 
753 
754 ZmPreviewView.prototype._cleanup =
755 function(){
756 
757     this._headerName.innerHTML = "";
758 
759     this._headerImage.className = "ImgUnknownDoc_48";
760 
761     if(this._headerModified)
762         this._headerModified.innerHTML = "";
763     if(this._headerCreated)
764         this._headerCreated.innerHTML = "";
765     if(this._headerCreator)
766         this._headerCreator.innerHTML = "";
767     if(this._lockStatus)
768         this._lockStatus.innerHTML = AjxImg.getImageHtml("Blank_16");
769     if(this._headerLockTime){
770         this._headerLockTime.innerHTML = "";
771     }
772     if(this._headerLockUser){
773         this._headerLockUser.innerHTML = "";
774     }
775     Dwt.setVisible(this._headerNotesSection, false);
776 
777     this._previewContent = false;
778 
779 };
780 
781 ZmPreviewView.prototype._setHeader =
782 function(item){
783 
784     //Name
785     this._headerName.innerHTML = AjxStringUtil.htmlEncode(item.name);
786 
787     //Image icon
788     var contentType = item.contentType;
789     if(contentType && contentType.match(/;/)) {
790         contentType = contentType.split(";")[0];
791     }
792     var mimeInfo = contentType ? ZmMimeTable.getInfo(contentType) : null;
793     var icon = "Img" + ( mimeInfo ? mimeInfo.imageLarge : "UnknownDoc_48");
794     this._headerImage.className = icon;
795 
796     //Modified & Created.  For Modified, use contentChangeDate, which is content modification (modifiedDate is
797 	// content and metaData changes).
798     var dateFormatter = AjxDateFormat.getDateTimeInstance(AjxDateFormat.LONG, AjxDateFormat.SHORT);
799     if (this._headerModified && item.contentChangeDate) {
800         this._headerModified.innerHTML = dateFormatter.format(item.contentChangeDate);
801 	}
802     if(this._headerModifier)
803         this._headerModifier.innerHTML = item.modifier;
804     if (this._headerCreated && item.createDate) {
805         this._headerCreated.innerHTML = dateFormatter.format(item.createDate);
806 	}
807     if(this._headerCreator)
808         this._headerCreator.innerHTML = item.creator;
809 
810     if(this._lockStatus)
811         this._lockStatus.innerHTML = AjxImg.getImageHtml(item.locked ? "Padlock" : "Blank_16");
812 
813     if(this._headerLockTime){
814         if(item.locked){
815             dateFormatter = AjxDateFormat.getDateInstance();
816             this._headerLockTime.innerHTML = dateFormatter.format(item.lockTime);
817         }else{
818             this._headerLockTime.innerHTML = ""
819         }        
820     }
821 
822     if(this._headerLockUser){
823         this._headerLockUser.innerHTML = item.locked ? item.lockUser : "";
824     }
825 
826     this.setNotes(item);
827 
828     this._onResize();
829 };
830 
831 ZmPreviewView.prototype.setNotes =
832 function(item){
833     var visible = item.subject;
834     Dwt.setVisible(this._headerNotesSection, visible);
835     if(visible && this._headerNotes){
836         this._headerNotes.innerHTML = AjxStringUtil.nl2br(item.subject);
837     }
838     this.expandNotes(false);
839 };
840 
841 ZmPreviewView.prototype.expandNotes =
842 function(expand){
843 
844     this._expandState = expand;
845 
846     if(this._headerNotes){
847         this._headerNotes.style.height = expand ? "" : "15px";
848     }
849     if(this._headerExpand){
850        this._headerExpand.innerHTML = AjxImg.getImageHtml((expand ? "NodeExpanded" : "NodeCollapsed"));
851     }
852 };
853 
854 ZmPreviewView.prototype._toggleExpand =
855 function(){
856     this.expandNotes(!this._expandState);
857 };
858 
859 ZmPreviewView.prototype.downloadListener =
860 function(item){
861     this._controller.downloadFile(item);
862 };
863 
864 ZmPreviewView.prototype.emailListener =
865 function(item){
866     this._controller.sendFilesAsAttachment(item);
867 };
868 
869 ZmPreviewView.prototype.openListener =
870 function(item){
871     this._controller.openFile(item);
872 };
873 
874 ZmPreviewView.prototype.editListener =
875 function(item){
876     this._controller.editFile(item);
877 };
878 
879 ZmPreviewView.prototype.enablePreview =
880 function(enabled){
881     if(enabled){
882         Dwt.setDisplay(this._previewContainer, Dwt.DISPLAY_INLINE);
883         Dwt.setDisplay(this._noresultContainer, Dwt.DISPLAY_NONE);
884     }else{
885         Dwt.setDisplay(this._previewContainer, Dwt.DISPLAY_NONE);
886         Dwt.setDisplay(this._noresultContainer, Dwt.DISPLAY_INLINE);
887     }
888 };
889 
890 ZmPreviewView.prototype._onResize =
891 function() {
892     if (this._containerEl && this._bodyEl) {
893         // in order to adapt to decreasing sizes in IE, make the body
894         // very small before getting its parent's size
895         Dwt.setSize(this._bodyEl, 1, 1);
896 
897         var size = Dwt.getSize(this._containerEl);
898         Dwt.setSize(this._bodyEl, size.x, size.y);
899     }
900 };
901