/*
* Copyright 2015 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 UI helper provides a dialog box to upload a file from hard drive
* See #open method.
* @private
*/
Ext.define('Ametys.plugins.inlinemedia.InsertMediaHelper',
{
singleton: true,
/**
* @property {Boolean} _initialized True if the dialog box has been initialized.
* @private
*/
/**
* @property {Ext.form.Basic} _formPanel The inner basic form.
* @private
*/
/**
* @property {Ametys.window.DialogBox} _box The dialog box
* @private
*/
/**
* @property {String[]} _urlPatterns The url patterns to retrieve the video id
* @private
*/
/**
* @property {String} _videoType The type of video to be inserted.
* @private
*/
/**
* @property {tinymce.Editor} _currentEditor The last used tinymce editor
* @private
*/
/**
* Allow the user to upload a file from local hard drive
* @param {tinymce.Editor} editor The richtext editor
* @param {String} title The title of the dialog
* @param {String} iconCls The CSS class for icon
* @param {String} hintText The hint text
* @param {String} videoType The type of video.
* @param {String[]} urlPatterns RegExp Strings to retrieve the video id from its url
* @param {Number} defaultWidth The default width set in the dialog
* @param {Number} defaultHeight The default height set in the dialog
*/
open: function (editor, title, iconCls, hintText, videoType, urlPatterns, defaultWidth, defaultHeight)
{
this._delayedInitialize(editor);
this._videoType = videoType;
this._urlPatterns = urlPatterns || [];
this._initForm(title, iconCls, hintText, defaultWidth, defaultHeight);
this._box.show();
},
/**
* Initialize the dialog box
* @param {tinymce.Editor} editor The richtext editor
* @return {Boolean} true if the box has been initialized (or if it was already initialized).
* @private
*/
_delayedInitialize: function (editor)
{
this._currentEditor = editor;
if (this._initialized)
{
return true;
}
var formPanel = Ext.create('Ext.form.Panel',
{
border: false,
// bodyStyle: 'padding:5px',
scrollable: true,
defaults:
{
cls: 'ametys',
anchor: '95%'
},
fieldDefaults:
{
labelAlign: 'right',
labelSeparator: '',
labelWidth: 100,
msgTarget: 'side'
},
items: [
{
xtype: 'component',
html: '',
name: 'hint',
cls: 'a-text'
},
{
// The real tag tree will be inserted later here
itemId: 'url-field',
xtype: 'component'
},
{
xtype: 'numberfield',
allowDecimals: false,
name: 'width',
fieldLabel: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_WIDTH}}",
ametysDescription: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_WIDTH_DESC}}"
},
{
xtype: 'numberfield',
allowDecimals: false,
name: 'height',
fieldLabel: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_HEIGHT}}",
ametysDescription: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_HEIGHT_DESC}}"
}
]
});
this._formPanel = formPanel;
this._box = Ext.create('Ametys.window.DialogBox',
{
title: "",
iconCls: "",
layout: 'fit',
width: 520,
items: formPanel,
closeAction: 'hide',
defaultFocus: 'url-field',
referenceHolder: true,
defaultButton: 'validate',
buttons: [{
reference: 'validate',
text: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_OK}}",
handler: Ext.bind(this._ok, this)
}, {
text: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_CANCEL}}",
handler: Ext.bind(this._cancel, this)
}]
});
this._initialized = true;
return true;
},
/**
* Initialize or reinitialize the form with the appropriate values.
* @param {String} title The title of the dialog
* @param {String} iconCls The CSS class for icon
* @param {String} hintText The hint text
* @param {Number} defaultWidth The default width set in the dialog
* @param {Number} defaultHeight The default height set in the dialog
* @private
*/
_initForm: function (title, iconCls, hintText, defaultWidth, defaultHeight)
{
this._box.setTitle(title);
this._box.setIconCls(iconCls);
this._formPanel.items.get(0).update(hintText);
var currentUrlField = this._formPanel.getComponent('url-field');
var position = this._formPanel.items.indexOf(currentUrlField);
// remove current field
currentUrlField.destroy();
// because regex config cannot be changed on the fly, the url field is recreated every time
var urlField = Ext.create('Ext.form.field.Text', {
xtype: 'textfield',
name: 'url',
itemId: 'url-field',
fieldLabel: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_URL}}",
ametysDescription: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_URL_DESC}}",
allowBlank: false,
regex: new RegExp(this._urlPatterns.join("|")),
regexText: "{{i18n PLUGINS_INLINEMEDIA_REGEXP_DIALOG_ERROR}}"
});
this._formPanel.insert(position, urlField);
var form = this._formPanel.getForm();
form.setValues({
"url": "",
"width": defaultWidth,
"height": defaultHeight
});
form.clearInvalid();
},
/**
* This function is called when the 'Ok' button of the dialog box #_box is pressed
* Validate the form and insert the video into the rich text
* @private
*/
_ok: function ()
{
if (!this._formPanel.getForm().isValid())
{
return;
}
var values = this._formPanel.getForm().getValues();
var videoId = this._getVideoId(values.url);
if (videoId == '')
{
Ametys.Msg.show({
title: this._box.getTitle(),
msg: "{{i18n PLUGINS_INLINEMEDIA_REGEXP_DIALOG_ERROR}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
return;
}
this._box.hide();
var width = values.width || '480';
var height = values.height || '385';
this._currentEditor.execCommand('mceBeginUndoLevel');
this._currentEditor.execCommand('mceInsertContent', false, '<img class="' + this._videoType + '" _mce_ribbon_select="1" marker="marker" media="' + this._videoType + '" width="' + width + '" height="' + height + '" src="' + Ametys.getPluginResourcesPrefix('inlinemedia') + '/img/trans.gif" data-ametys-type="' + this._videoType + '" data-ametys-src="' + videoId + '"/>');
this._currentEditor.execCommand('mceEndUndoLevel');
this._currentEditor.focus();
this._currentEditor = null;
},
/**
* Get the id of the video from its url
* @param {String} videoUrl The url
* @return {String} The id
*/
_getVideoId: function(videoUrl)
{
for (var i = 0; i < this._urlPatterns.length; i++)
{
var regexp = new RegExp(this._urlPatterns[i]);
if (regexp.test(videoUrl))
{
return RegExp.$1;
}
}
return '';
},
/**
* This function is called when the 'Cancel' button of the dialog box #_box is pressed
* Close the dialog
* @private
*/
_cancel: function ()
{
this._box.hide();
this._currentEditor.focus();
this._currentEditor = null;
}
});