/*
* Copyright 2013 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This tool is a tool for viewing or editing a content
* @private
*/
Ext.define('Ametys.plugins.cms.content.tool.OldContentTool', {
extend: "Ametys.tool.Tool",
/**
* @property {String} _contentId The unique identifier of the content.
* @private
*/
/**
* @cfg {String} [metadata-set-name="main"] The name of metadata set of content to use for edition.
*/
/**
* @property _metadataSetName {String} The metadata set for edition. See #cfg-metadata-set-name.
*/
/**
* @cfg {String} [oldcontent-message-type="old-content"] The message type to send. Defaults to 'old-content'.
*/
/**
* @property _oldContentMessageType {String} The message type to send. See #cfg-oldcontent-message-type
*/
/**
* @private
* @property {Ext.ux.IFrame} _iframe The iframe object
*/
/**
* @private
* @property {Ext.Template} _tooltipDescriptionTpl The template used for tooltip description
*/
/**
* @private
* @property {Ext.Template} _hintTpl The template used for hint text
*/
/**
* @private
* @property {String} _baseUrl The url that the iframe should stay on
*/
constructor: function (config)
{
this.callParent(arguments);
this._hintTpl = new Ext.Template(
'<div class="title">',
'<span class="ametysicon-time51"></span>',
"{title} ({{i18n PLUGINS_CMS_TOOL_CONTENT_INTRO_VERSION}}{version})",
'</div>',
'<div class="text">',
"{{i18n PLUGINS_CMS_TOOL_CONTENT_INTRO_DESC1}}<br/>",
"{{i18n PLUGINS_CMS_TOOL_CONTENT_INTRO_DESC2}}",
'</div>'
);
this._tooltipDescriptionTpl = new Ext.Template(
"<u>{{i18n PLUGINS_CMS_TOOL_CONTENT_TOOLTIP_VERSION}}</u> : ",
"<b>v{version}</b><br/>",
"<u>{{i18n PLUGINS_CMS_TOOL_CONTENT_TOOLTIP_AUTHOR}}</u> : ",
"<b>{author}</b><br/>",
"<u>{{i18n PLUGINS_CMS_TOOL_CONTENT_TOOLTIP_LASTMODIFICATION}}</u> : ",
"<b>{lastModified}</b>"
);
this._oldContentMessageType = this.getInitialConfig('oldcontent-message-type')|| 'old-content';
},
createPanel: function ()
{
this._iframe = Ext.create("Ext.ux.IFrame", {});
this._iframe.on ('load', this._onIframeLoad, this);
return Ext.create('Ext.Panel', {
cls: 'oldcontenttool',
border: false,
layout: 'border',
scrollable: false,
items: [{
region: 'north',
xtype: 'component',
cls: 'hint',
html: ''
},
this._iframe
]
});
},
setParams: function (params)
{
this.callParent(arguments);
this._contentId = params['id'];
this._metadataSetName = params['metadata-set-name'] || 'main';
this._contentVersion = params['contentVersion'];
this._versionName = params['versionName'];
// Register the tool on the history tool
var toolId = this.getFactory().getId();
var toolParams = this.getParams();
Ametys.navhistory.HistoryDAO.addEntry({
id: this.getId(),
label: this.getTitle(),
description: this.getDescription(),
iconGlyph: this.getGlyphIcon(),
iconSmall: this.getSmallIcon(),
iconMedium: this.getMediumIcon(),
iconLarge: this.getLargeIcon(),
type: Ametys.navhistory.HistoryDAO.TOOL_TYPE,
action: Ext.bind(Ametys.tool.ToolsManager.openTool, Ametys.tool.ToolsManager, [toolId, toolParams], false)
});
this.refresh();
},
refresh: function ()
{
this.showRefreshing();
var wrappedUrl = this.getWrappedContentRevisionUrl ();
this._iframe.load(Ametys.CONTEXT_PATH + wrappedUrl)
this._baseUrl = Ametys.CONTEXT_PATH + wrappedUrl;
this.showRefreshed();
this._updateInfos();
},
/**
* Get the wrapped url for content old revision
* @returns {String} The wrapped url
*/
getWrappedContentRevisionUrl: function ()
{
var appParameters = Ametys.getAppParameters();
var additionParams = '';
Ext.Object.each(appParameters, function(key, value) {
additionParams += '&' + key + '=' + encodeURIComponent(value);
});
return '/_wrapped-content/v_' + this._contentVersion + '.html?contentId=' + this.getContentId() + additionParams;
},
/**
* Get the unique identifier of the content.
* @returns {String} The identifier of the content
*/
getContentId: function()
{
return this._contentId;
},
/**
* @private
* Listener called when the iframe is loaded.
* Protects the iframe by handling links of the internal frame by setting a onclick on every one
* @param {Ext.ux.IFrame} iframe The iframe
*/
_onIframeLoad: function (iframe)
{
if (window.event && window.event.srcElement.readyState && !/loaded|complete/.test(window.event.srcElement.readyState))
{
return;
}
Ametys.plugins.cms.content.tool.ContentTool.__URL_REGEXP.test(window.location.href);
var win = this._iframe.getWin();
var outside = false;
try
{
win.location.href
}
catch (e)
{
outside = true;
}
if (outside || (win.location.href != 'about:blank' && win.location.href.indexOf(RegExp.$1 + this._baseUrl) != 0))
{
var outsideUrl = win.location.href;
// Back to iframe base url
win.location.href = this._baseUrl;
// Open ouside url in a new window
window.open(outsideUrl);
}
else
{
var links = win.document.getElementsByTagName("a");
for (var a = 0; a < links.length; a++)
{
if (links[a].getAttribute("internal") == null && !links[a].onclick)
{
links[a].onclick = Ext.bind(this._handleLink, this, [links[a]], false);
}
}
}
},
/**
* @private
* Lazy handling of links. Each times a link is clicked, check if we should open it in a window, open another tool...
* @param {HTMLElement} link The clicked link
*/
_handleLink: function(link)
{
var currentURI = this._iframe.getWin().location.href;
var absHref = link.href;
var relHref = null;
if (/^(https?:\/\/[^\/]+)(\/.*)?/.test(absHref) && absHref.indexOf(RegExp.$1 + Ametys.CONTEXT_PATH) == 0)
{
relHref = absHref.substring(absHref.indexOf(RegExp.$1 + Ametys.CONTEXT_PATH) + (RegExp.$1 + Ametys.CONTEXT_PATH).length);
}
// Internal link
if (absHref.indexOf(currentURI) == 0) return true;
// JS Link
if (absHref.indexOf("javascript:") == 0) return true;
// Download link
if (relHref != null && relHref.indexOf("/plugins/explorer/download/") == 0) return true;
// Unknown link : open in a new window
window.open(absHref);
return false;
},
/**
* Update tool information
* @private
*/
_updateInfos: function()
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.cms.repository.ContentDAO",
methodName: 'getContentDescription',
parameters: [ this.getContentId(), null],
waitMessage: false,
callback: {
handler: this._updateInfosCb,
scope: this,
ignoreOnError: false
}
});
},
/**
* Callback function called after #_updateInfos is processed
* @param {Object} data The server response
* @param {String} data.title The title
* @param {Object} data.lastContributor The last contributor object
* @param {String} data.lastContributor.fullname The fullname of the last contributor
* @param {String} data.lastModified The last modified date at 'd/m/Y, H:i' format
* @param {String} data.iconGlyph A css class to set a glyph
* @param {String} data.iconDecorator A css class to set a glyph decorator
* @param {String} data.smallIcon The path to the small (16x16) icon. iconGlyph win if specified
* @param {String} data.mediumIcon The path to the medium (32x32) icon. iconGlyph win if specified
* @param {String} data.largeIcon The path to the large (48x48) icon. iconGlyph win if specified
* @param {Object} args The callback parameters passed to the {@link Ametys.data.ServerComm#send} method
* @private
*/
_updateInfosCb: function (data, args)
{
var title = data.title + ' (v' + this._versionName + ')';
this.setTitle(data.title);
var values = {title: data.title, version: this._versionName, author: data.lastContributor.fullname, lastModified: Ext.util.Format.date(data.lastModified, 'd/m/Y, H:i')};
var description = this._tooltipDescriptionTpl.applyTemplate (values);
this.setDescription(description);
// Set title, desc, and icons.
if (data.iconGlyph)
{
this.setGlyphIcon(data.iconGlyph);
this.setIconDecorator(data.iconDecorator);
}
else
{
this.setGlyphIcon(null);
this.setSmallIcon(data.smallIcon);
this.setMediumIcon(data.mediumIcon);
this.setLargeIcon(data.largeIcon);
}
this.getContentPanel().items.get(0).update(this._hintTpl.applyTemplate (values));
},
getMBSelectionInteraction: function()
{
return Ametys.tool.Tool.MB_TYPE_ACTIVE;
},
sendCurrentSelection: function()
{
Ametys.cms.content.ContentDAO.getContent(this.getContentId(), Ext.bind(this._createContentTarget, this));
},
/**
* Creates and fires a event of selection on the message bus
* @param {Ametys.cms.content.Content} content The concerned content
* @private
*/
_createContentTarget: function (content)
{
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.SELECTION_CHANGED,
targets: {
id: this._oldContentMessageType,
parameters: { contents: [content], 'version' : this._contentVersion, 'versionName' : this._versionName},
subtargets: []
}
});
}
});