mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-08 23:19:04 +01:00
Convert et2_core_editableWidget and et2_widget_htmlarea to TS
This commit is contained in:
parent
edf95a4bdf
commit
7d01281fa0
@ -1,3 +1,4 @@
|
|||||||
|
"use strict";
|
||||||
/**
|
/**
|
||||||
* EGroupware eTemplate2 - JS Widget base class
|
* EGroupware eTemplate2 - JS Widget base class
|
||||||
*
|
*
|
||||||
@ -5,15 +6,27 @@
|
|||||||
* @package etemplate
|
* @package etemplate
|
||||||
* @subpackage api
|
* @subpackage api
|
||||||
* @link http://www.egroupware.org
|
* @link http://www.egroupware.org
|
||||||
* @author Andreas Stöckel
|
* @author Nathan Gray
|
||||||
* @copyright Stylite 2011
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
|
var __extends = (this && this.__extends) || (function () {
|
||||||
|
var extendStatics = function (d, b) {
|
||||||
|
extendStatics = Object.setPrototypeOf ||
|
||||||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||||
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||||
|
return extendStatics(d, b);
|
||||||
|
};
|
||||||
|
return function (d, b) {
|
||||||
|
extendStatics(d, b);
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
/*egw:uses
|
/*egw:uses
|
||||||
et2_core_inputWidget;
|
et2_core_inputWidget;
|
||||||
*/
|
*/
|
||||||
|
var et2_core_inputWidget_1 = require("./et2_core_inputWidget");
|
||||||
|
var et2_core_inheritance_1 = require("./et2_core_inheritance");
|
||||||
/**
|
/**
|
||||||
* et2_editableWidget derives from et2_inputWidget and adds the ability to start
|
* et2_editableWidget derives from et2_inputWidget and adds the ability to start
|
||||||
* readonly, then turn editable on double-click. If we decide to do this with
|
* readonly, then turn editable on double-click. If we decide to do this with
|
||||||
@ -21,184 +34,161 @@
|
|||||||
*
|
*
|
||||||
* @augments et2_inputWidget
|
* @augments et2_inputWidget
|
||||||
*/
|
*/
|
||||||
var et2_editableWidget = (function(){ "use strict"; return et2_inputWidget.extend(et2_ISubmitListener,
|
var et2_editableWidget = /** @class */ (function (_super) {
|
||||||
{
|
__extends(et2_editableWidget, _super);
|
||||||
attributes: {
|
/**
|
||||||
readonly: {
|
* Constructor
|
||||||
name: "readonly",
|
*/
|
||||||
type: "string", // | boolean
|
function et2_editableWidget(_parent, _attrs, _child) {
|
||||||
default: false,
|
var _this = this;
|
||||||
description: "If set to 'editable' will start readonly, double clicking will make it editable and clicking out will save"
|
// 'Editable' really should be boolean for everything else to work
|
||||||
},
|
if (_attrs.readonly && typeof _attrs.readonly === 'string') {
|
||||||
toggle_readonly: {
|
_attrs.readonly = true;
|
||||||
name: "toggle_readonly",
|
var toggle_readonly = _attrs.toggle_readonly;
|
||||||
type: "boolean",
|
}
|
||||||
default: true,
|
// Call the inherited constructor
|
||||||
description: "Double clicking makes widget editable. If off, must be made editable in some other way."
|
_this = _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_editableWidget._attributes, _child || {})) || this;
|
||||||
},
|
if (typeof toggle_readonly != 'undefined')
|
||||||
save_callback: {
|
_this._toggle_readonly = toggle_readonly;
|
||||||
name: "save_callback",
|
return _this;
|
||||||
type: "string",
|
}
|
||||||
default: et2_no_init,
|
et2_editableWidget.prototype.destroy = function () {
|
||||||
description: "Ajax callback to save changed value when readonly is 'editable'. If not provided, a regular submit is done."
|
var node = this.getInputNode();
|
||||||
},
|
if (node) {
|
||||||
save_callback_params: {
|
jQuery(node).off('.et2_editableWidget');
|
||||||
name: "readonly",
|
}
|
||||||
type: "string",
|
_super.prototype.destroy.call(this);
|
||||||
default: et2_no_init,
|
};
|
||||||
description: "Additional parameters passed to save_callback"
|
/**
|
||||||
},
|
* Load the validation errors from the server
|
||||||
editable_height: {
|
*
|
||||||
name: "Editable height",
|
* @param {object} _attrs
|
||||||
description: "Set height for widget while in edit mode",
|
*/
|
||||||
type: "string"
|
et2_editableWidget.prototype.transformAttributes = function (_attrs) {
|
||||||
}
|
_super.prototype.transformAttributes.call(this, _attrs);
|
||||||
},
|
};
|
||||||
|
et2_editableWidget.prototype.attachToDOM = function () {
|
||||||
/**
|
var res = _super.prototype.attachToDOM.call(this);
|
||||||
* Constructor
|
var node = this.getDOMNode();
|
||||||
*
|
if (node && this._toggle_readonly) {
|
||||||
* @memberOf et2_inputWidget
|
jQuery(node)
|
||||||
*/
|
.off('.et2_editableWidget')
|
||||||
init: function(_parent, _attrs) {
|
.on("dblclick.et2_editableWidget", this, function (e) {
|
||||||
// 'Editable' really should be boolean for everything else to work
|
e.data.dblclick.call(e.data, this);
|
||||||
if(_attrs.readonly && typeof _attrs.readonly === 'string')
|
})
|
||||||
{
|
.addClass('et2_clickable et2_editable');
|
||||||
_attrs.readonly = true;
|
}
|
||||||
this._toggle_readonly = _attrs.toggle_readonly;
|
else {
|
||||||
}
|
jQuery(node).addClass('et2_editable_readonly');
|
||||||
this._super.apply(this, arguments);
|
}
|
||||||
},
|
return res;
|
||||||
|
};
|
||||||
destroy: function() {
|
et2_editableWidget.prototype.detatchFromDOM = function () {
|
||||||
var node = this.getInputNode();
|
_super.prototype.detatchFromDOM.call(this);
|
||||||
if (node)
|
};
|
||||||
{
|
/**
|
||||||
jQuery(node).off('.et2_editableWidget');
|
* Handle double click
|
||||||
}
|
*
|
||||||
|
* Turn widget editable
|
||||||
this._super.apply(this, arguments);
|
*
|
||||||
},
|
* @param {DOMNode} _node
|
||||||
|
*/
|
||||||
/**
|
et2_editableWidget.prototype.dblclick = function (_node) {
|
||||||
* Load the validation errors from the server
|
// Turn off readonly
|
||||||
*
|
this.set_readonly(false);
|
||||||
* @param {object} _attrs
|
jQuery('body').on("click.et2_editableWidget", this, function (e) {
|
||||||
*/
|
// Make sure click comes from body, not a popup
|
||||||
transformAttributes: function(_attrs) {
|
if (jQuery.contains(this, e.target) && e.target.type != 'textarea') {
|
||||||
this._super.apply(this, arguments);
|
jQuery(this).off("click.et2_editableWidget");
|
||||||
|
e.data.focusout.call(e.data, this);
|
||||||
},
|
}
|
||||||
|
});
|
||||||
attachToDOM: function() {
|
};
|
||||||
this._super.apply(this,arguments);
|
/**
|
||||||
var node = this.getDOMNode();
|
* User clicked somewhere else, save and turn back to readonly
|
||||||
if (node && this._toggle_readonly)
|
*
|
||||||
{
|
* @param {DOMNode} _node Body node
|
||||||
jQuery(node)
|
* @returns {et2_core_editableWidgetet2_editableWidget.et2_core_editableWidgetAnonym$0@call;getInstanceManager@call;submit}
|
||||||
.off('.et2_editableWidget')
|
*/
|
||||||
.on("dblclick.et2_editableWidget", this, function(e) {
|
et2_editableWidget.prototype.focusout = function (_node) {
|
||||||
e.data.dblclick.call(e.data, this);
|
var value = this.get_value();
|
||||||
})
|
var oldValue = this._oldValue;
|
||||||
.addClass('et2_clickable et2_editable');
|
// Change back to readonly
|
||||||
}
|
this.set_readonly(true);
|
||||||
else
|
// No change, do nothing
|
||||||
{
|
if (value == oldValue)
|
||||||
jQuery(node).addClass('et2_editable_readonly');
|
return;
|
||||||
}
|
// Submit
|
||||||
|
if (this.options.save_callback) {
|
||||||
},
|
var params = [value];
|
||||||
|
if (this.options.save_callback_params) {
|
||||||
detatchFromDOM: function() {
|
params = params.concat(this.options.save_callback_params.split(','));
|
||||||
this._super.apply(this,arguments);
|
}
|
||||||
},
|
egw.json(this.options.save_callback, params, function () {
|
||||||
|
}, this, true, this).sendRequest();
|
||||||
/**
|
}
|
||||||
* Handle double click
|
else {
|
||||||
*
|
this.set_value(value);
|
||||||
* Turn widget editable
|
return this.getInstanceManager().submit();
|
||||||
*
|
}
|
||||||
* @param {DOMNode} _node
|
};
|
||||||
*/
|
/**
|
||||||
dblclick: function (_node) {
|
* Called whenever the template gets submitted.
|
||||||
// Turn off readonly
|
* If we have a save_callback, we call that before the submit (no check on
|
||||||
this.set_readonly(false);
|
* the result)
|
||||||
|
*
|
||||||
jQuery('body').on("click.et2_editableWidget", this, function(e) {
|
* @param _values contains the values which will be sent to the server.
|
||||||
// Make sure click comes from body, not a popup
|
* Listeners may change these values before they get submitted.
|
||||||
if(jQuery.contains(this, e.target) && e.target.type != 'textarea')
|
*/
|
||||||
{
|
et2_editableWidget.prototype.submit = function (_values) {
|
||||||
jQuery(this).off("click.et2_editableWidget");
|
if (this.options.readonly) {
|
||||||
e.data.focusout.call(e.data, this);
|
// Not currently editing, just continue on
|
||||||
}
|
return true;
|
||||||
});
|
}
|
||||||
},
|
// Change back to readonly
|
||||||
|
this.set_readonly(true);
|
||||||
/**
|
var params = [this.get_value()];
|
||||||
* User clicked somewhere else, save and turn back to readonly
|
if (this.options.save_callback_params) {
|
||||||
*
|
params = params.concat(this.options.save_callback_params.split(','));
|
||||||
* @param {DOMNode} _node Body node
|
}
|
||||||
* @returns {et2_core_editableWidgetet2_editableWidget.et2_core_editableWidgetAnonym$0@call;getInstanceManager@call;submit}
|
if (this.options.save_callback) {
|
||||||
*/
|
egw.json(this.options.save_callback, params, function () {
|
||||||
focusout: function (_node)
|
}, this, true, this).sendRequest();
|
||||||
{
|
}
|
||||||
var value = this.get_value();
|
return true;
|
||||||
var oldValue = this._oldValue;
|
};
|
||||||
|
et2_editableWidget._attributes = {
|
||||||
// Change back to readonly
|
readonly: {
|
||||||
this.set_readonly(true);
|
name: "readonly",
|
||||||
|
type: "string",
|
||||||
// No change, do nothing
|
default: false,
|
||||||
if(value == oldValue) return;
|
description: "If set to 'editable' will start readonly, double clicking will make it editable and clicking out will save"
|
||||||
|
},
|
||||||
|
toggle_readonly: {
|
||||||
// Submit
|
name: "toggle_readonly",
|
||||||
if(this.options.save_callback)
|
type: "boolean",
|
||||||
{
|
default: true,
|
||||||
var params = [value];
|
description: "Double clicking makes widget editable. If off, must be made editable in some other way."
|
||||||
if(this.options.save_callback_params)
|
},
|
||||||
{
|
save_callback: {
|
||||||
params = params.concat(this.options.save_callback_params.split(','));
|
name: "save_callback",
|
||||||
}
|
type: "string",
|
||||||
|
default: et2_no_init,
|
||||||
egw.json(this.options.save_callback, params, function() {
|
description: "Ajax callback to save changed value when readonly is 'editable'. If not provided, a regular submit is done."
|
||||||
}, this, true, this).sendRequest();
|
},
|
||||||
}
|
save_callback_params: {
|
||||||
else
|
name: "readonly",
|
||||||
{
|
type: "string",
|
||||||
this.set_value(value);
|
default: et2_no_init,
|
||||||
return this.getInstanceManager().submit();
|
description: "Additional parameters passed to save_callback"
|
||||||
}
|
},
|
||||||
},
|
editable_height: {
|
||||||
|
name: "Editable height",
|
||||||
/**
|
description: "Set height for widget while in edit mode",
|
||||||
* Called whenever the template gets submitted.
|
type: "string"
|
||||||
* If we have a save_callback, we call that before the submit (no check on
|
}
|
||||||
* the result)
|
};
|
||||||
*
|
return et2_editableWidget;
|
||||||
* @param _values contains the values which will be sent to the server.
|
}(et2_core_inputWidget_1.et2_inputWidget));
|
||||||
* Listeners may change these values before they get submitted.
|
exports.et2_editableWidget = et2_editableWidget;
|
||||||
*/
|
//# sourceMappingURL=et2_core_editableWidget.js.map
|
||||||
submit: function(_values) {
|
|
||||||
if(this.options.readonly)
|
|
||||||
{
|
|
||||||
// Not currently editing, just continue on
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Change back to readonly
|
|
||||||
this.set_readonly(true);
|
|
||||||
|
|
||||||
var params = [this.get_value()];
|
|
||||||
if(this.options.save_callback_params)
|
|
||||||
{
|
|
||||||
params = params.concat(this.options.save_callback_params.split(','));
|
|
||||||
}
|
|
||||||
if(this.options.save_callback)
|
|
||||||
{
|
|
||||||
egw.json(this.options.save_callback, params, function() {
|
|
||||||
}, this, true, this).sendRequest();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});}).call(this);
|
|
||||||
|
|
213
api/js/etemplate/et2_core_editableWidget.ts
Normal file
213
api/js/etemplate/et2_core_editableWidget.ts
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/**
|
||||||
|
* EGroupware eTemplate2 - JS Widget base class
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package etemplate
|
||||||
|
* @subpackage api
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Nathan Gray
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*egw:uses
|
||||||
|
et2_core_inputWidget;
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {et2_inputWidget} from "./et2_core_inputWidget";
|
||||||
|
import {WidgetConfig} from "./et2_core_widget";
|
||||||
|
import {ClassWithAttributes} from "./et2_core_inheritance";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* et2_editableWidget derives from et2_inputWidget and adds the ability to start
|
||||||
|
* readonly, then turn editable on double-click. If we decide to do this with
|
||||||
|
* more widgets, it should just be merged with et2_inputWidget.
|
||||||
|
*
|
||||||
|
* @augments et2_inputWidget
|
||||||
|
*/
|
||||||
|
export class et2_editableWidget extends et2_inputWidget implements et2_ISubmitListener
|
||||||
|
{
|
||||||
|
static readonly _attributes : any = {
|
||||||
|
readonly: {
|
||||||
|
name: "readonly",
|
||||||
|
type: "string", // | boolean
|
||||||
|
default: false,
|
||||||
|
description: "If set to 'editable' will start readonly, double clicking will make it editable and clicking out will save"
|
||||||
|
},
|
||||||
|
toggle_readonly: {
|
||||||
|
name: "toggle_readonly",
|
||||||
|
type: "boolean",
|
||||||
|
default: true,
|
||||||
|
description: "Double clicking makes widget editable. If off, must be made editable in some other way."
|
||||||
|
},
|
||||||
|
save_callback: {
|
||||||
|
name: "save_callback",
|
||||||
|
type: "string",
|
||||||
|
default: et2_no_init,
|
||||||
|
description: "Ajax callback to save changed value when readonly is 'editable'. If not provided, a regular submit is done."
|
||||||
|
},
|
||||||
|
save_callback_params: {
|
||||||
|
name: "readonly",
|
||||||
|
type: "string",
|
||||||
|
default: et2_no_init,
|
||||||
|
description: "Additional parameters passed to save_callback"
|
||||||
|
},
|
||||||
|
editable_height: {
|
||||||
|
name: "Editable height",
|
||||||
|
description: "Set height for widget while in edit mode",
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private _toggle_readonly : boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
constructor(_parent, _attrs? : WidgetConfig, _child? : object)
|
||||||
|
{
|
||||||
|
// 'Editable' really should be boolean for everything else to work
|
||||||
|
if(_attrs.readonly && typeof _attrs.readonly === 'string')
|
||||||
|
{
|
||||||
|
_attrs.readonly = true;
|
||||||
|
var toggle_readonly = _attrs.toggle_readonly;
|
||||||
|
}
|
||||||
|
// Call the inherited constructor
|
||||||
|
super(_parent, _attrs, ClassWithAttributes.extendAttributes(et2_editableWidget._attributes, _child || {}));
|
||||||
|
if (typeof toggle_readonly != 'undefined') this._toggle_readonly = toggle_readonly;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy()
|
||||||
|
{
|
||||||
|
let node = this.getInputNode();
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
jQuery(node).off('.et2_editableWidget');
|
||||||
|
}
|
||||||
|
super.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the validation errors from the server
|
||||||
|
*
|
||||||
|
* @param {object} _attrs
|
||||||
|
*/
|
||||||
|
transformAttributes(_attrs)
|
||||||
|
{
|
||||||
|
super.transformAttributes(_attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
attachToDOM()
|
||||||
|
{
|
||||||
|
let res = super.attachToDOM();
|
||||||
|
let node = this.getDOMNode();
|
||||||
|
if (node && this._toggle_readonly)
|
||||||
|
{
|
||||||
|
jQuery(node)
|
||||||
|
.off('.et2_editableWidget')
|
||||||
|
.on("dblclick.et2_editableWidget", this, function(e) {
|
||||||
|
e.data.dblclick.call(e.data, this);
|
||||||
|
})
|
||||||
|
.addClass('et2_clickable et2_editable');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jQuery(node).addClass('et2_editable_readonly');
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
detatchFromDOM()
|
||||||
|
{
|
||||||
|
super.detatchFromDOM();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle double click
|
||||||
|
*
|
||||||
|
* Turn widget editable
|
||||||
|
*
|
||||||
|
* @param {DOMNode} _node
|
||||||
|
*/
|
||||||
|
dblclick(_node)
|
||||||
|
{
|
||||||
|
// Turn off readonly
|
||||||
|
this.set_readonly(false);
|
||||||
|
|
||||||
|
jQuery('body').on("click.et2_editableWidget", this, function(e) {
|
||||||
|
// Make sure click comes from body, not a popup
|
||||||
|
if(jQuery.contains(this, e.target) && e.target.type != 'textarea')
|
||||||
|
{
|
||||||
|
jQuery(this).off("click.et2_editableWidget");
|
||||||
|
e.data.focusout.call(e.data, this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User clicked somewhere else, save and turn back to readonly
|
||||||
|
*
|
||||||
|
* @param {DOMNode} _node Body node
|
||||||
|
* @returns {et2_core_editableWidgetet2_editableWidget.et2_core_editableWidgetAnonym$0@call;getInstanceManager@call;submit}
|
||||||
|
*/
|
||||||
|
focusout(_node)
|
||||||
|
{
|
||||||
|
var value = this.get_value();
|
||||||
|
var oldValue = this._oldValue;
|
||||||
|
|
||||||
|
// Change back to readonly
|
||||||
|
this.set_readonly(true);
|
||||||
|
|
||||||
|
// No change, do nothing
|
||||||
|
if(value == oldValue) return;
|
||||||
|
|
||||||
|
|
||||||
|
// Submit
|
||||||
|
if(this.options.save_callback)
|
||||||
|
{
|
||||||
|
var params = [value];
|
||||||
|
if(this.options.save_callback_params)
|
||||||
|
{
|
||||||
|
params = params.concat(this.options.save_callback_params.split(','));
|
||||||
|
}
|
||||||
|
|
||||||
|
egw.json(this.options.save_callback, params, function() {
|
||||||
|
}, this, true, this).sendRequest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.set_value(value);
|
||||||
|
return this.getInstanceManager().submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever the template gets submitted.
|
||||||
|
* If we have a save_callback, we call that before the submit (no check on
|
||||||
|
* the result)
|
||||||
|
*
|
||||||
|
* @param _values contains the values which will be sent to the server.
|
||||||
|
* Listeners may change these values before they get submitted.
|
||||||
|
*/
|
||||||
|
submit(_values)
|
||||||
|
{
|
||||||
|
if(this.options.readonly)
|
||||||
|
{
|
||||||
|
// Not currently editing, just continue on
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Change back to readonly
|
||||||
|
this.set_readonly(true);
|
||||||
|
|
||||||
|
var params = [this.get_value()];
|
||||||
|
if(this.options.save_callback_params)
|
||||||
|
{
|
||||||
|
params = params.concat(this.options.save_callback_params.split(','));
|
||||||
|
}
|
||||||
|
if(this.options.save_callback)
|
||||||
|
{
|
||||||
|
egw.json(this.options.save_callback, params, function() {
|
||||||
|
}, this, true, this).sendRequest();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
5
api/js/etemplate/et2_types.d.ts
vendored
5
api/js/etemplate/et2_types.d.ts
vendored
@ -30,7 +30,9 @@ declare var et2_placeholder : any;
|
|||||||
declare var et2_validTypes : string[];
|
declare var et2_validTypes : string[];
|
||||||
declare var et2_typeDefaults : object;
|
declare var et2_typeDefaults : object;
|
||||||
//declare const et2_no_init : object;
|
//declare const et2_no_init : object;
|
||||||
declare var et2_editableWidget : any;
|
declare class et2_editableWidget extends et2_inputWidget {
|
||||||
|
public set_readonly(value : boolean);
|
||||||
|
}
|
||||||
/*declare var et2_IDOMNode : any;
|
/*declare var et2_IDOMNode : any;
|
||||||
declare var et2_IInput : any;
|
declare var et2_IInput : any;
|
||||||
declare var et2_IResizeable : any;
|
declare var et2_IResizeable : any;
|
||||||
@ -161,6 +163,7 @@ declare var et2_vfsUpload : any;
|
|||||||
declare var et2_vfsSelect : any;
|
declare var et2_vfsSelect : any;
|
||||||
declare var et2_video : any;
|
declare var et2_video : any;
|
||||||
declare var et2_IExposable : any;
|
declare var et2_IExposable : any;
|
||||||
|
declare var tinymce : any;
|
||||||
declare class et2_nextmatch_sortheader extends et2_nextmatch_header {}
|
declare class et2_nextmatch_sortheader extends et2_nextmatch_header {}
|
||||||
declare class et2_nextmatch_filterheader extends et2_nextmatch_header {}
|
declare class et2_nextmatch_filterheader extends et2_nextmatch_header {}
|
||||||
declare class et2_nextmatch_accountfilterheader extends et2_nextmatch_header {}
|
declare class et2_nextmatch_accountfilterheader extends et2_nextmatch_header {}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
"use strict";
|
||||||
/**
|
/**
|
||||||
* EGroupware eTemplate2 - JS widget for HTML editing
|
* EGroupware eTemplate2 - JS widget for HTML editing
|
||||||
*
|
*
|
||||||
@ -9,499 +10,465 @@
|
|||||||
* @copyright Hadi Nategh <hn@egroupware.org>
|
* @copyright Hadi Nategh <hn@egroupware.org>
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
|
var __extends = (this && this.__extends) || (function () {
|
||||||
|
var extendStatics = function (d, b) {
|
||||||
|
extendStatics = Object.setPrototypeOf ||
|
||||||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||||
|
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||||
|
return extendStatics(d, b);
|
||||||
|
};
|
||||||
|
return function (d, b) {
|
||||||
|
extendStatics(d, b);
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
/*egw:uses
|
/*egw:uses
|
||||||
jsapi.jsapi; // Needed for egw_seperateJavaScript
|
jsapi.jsapi; // Needed for egw_seperateJavaScript
|
||||||
/vendor/tinymce/tinymce/tinymce.min.js;
|
/vendor/tinymce/tinymce/tinymce.min.js;
|
||||||
et2_core_editableWidget;
|
et2_core_editableWidget;
|
||||||
*/
|
*/
|
||||||
|
var et2_core_editableWidget_1 = require("./et2_core_editableWidget");
|
||||||
|
var et2_core_inheritance_1 = require("./et2_core_inheritance");
|
||||||
|
var et2_core_widget_1 = require("./et2_core_widget");
|
||||||
/**
|
/**
|
||||||
* @augments et2_inputWidget
|
* @augments et2_inputWidget
|
||||||
*/
|
*/
|
||||||
var et2_htmlarea = (function(){ "use strict"; return et2_editableWidget.extend([et2_IResizeable],
|
var et2_htmlarea = /** @class */ (function (_super) {
|
||||||
{
|
__extends(et2_htmlarea, _super);
|
||||||
attributes: {
|
/**
|
||||||
mode: {
|
* Constructor
|
||||||
'name': 'Mode',
|
*/
|
||||||
'description': 'One of {ascii|simple|extended|advanced}',
|
function et2_htmlarea(_parent, _attrs, _child) {
|
||||||
'default': '',
|
var _this =
|
||||||
'type': 'string'
|
// Call the inherited constructor
|
||||||
},
|
_super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_htmlarea._attributes, _child || {})) || this;
|
||||||
height: {
|
_this.editor = null;
|
||||||
'name': 'Height',
|
_this.htmlNode = null;
|
||||||
'default': et2_no_init,
|
_this.editor = null; // TinyMce editor instance
|
||||||
'type': 'string'
|
_this.supportedWidgetClasses = []; // Allow no child widgets
|
||||||
},
|
_this.htmlNode = jQuery(document.createElement(_this.options.readonly ? "div" : "textarea"))
|
||||||
width: {
|
.addClass('et2_textbox_ro');
|
||||||
'name': 'Width',
|
if (_this.options.height) {
|
||||||
'default': et2_no_init,
|
_this.htmlNode.css('height', _this.options.height);
|
||||||
'type': 'string'
|
}
|
||||||
},
|
_this.setDOMNode(_this.htmlNode[0]);
|
||||||
value: {
|
return _this;
|
||||||
name: "Value",
|
}
|
||||||
description: "The value of the widget",
|
/**
|
||||||
type: "html", // "string" would remove html tags by running html_entity_decode
|
*
|
||||||
default: et2_no_init
|
* @returns {undefined}
|
||||||
},
|
*/
|
||||||
imageUpload: {
|
et2_htmlarea.prototype.doLoadingFinished = function () {
|
||||||
name: "imageUpload",
|
_super.prototype.doLoadingFinished.call(this);
|
||||||
description: "Url to upload images dragged in or id of link_to widget to it's vfs upload. Can also be just a name for which content array contains a path to upload the picture.",
|
this.init_editor();
|
||||||
type: "string",
|
return true;
|
||||||
default: null
|
};
|
||||||
},
|
et2_htmlarea.prototype.init_editor = function () {
|
||||||
file_picker_callback: {
|
if (this.mode == 'ascii' || this.editor != null || this.options.readonly)
|
||||||
name: "File picker callback",
|
return;
|
||||||
description: "Callback function to get called when file picker is clicked",
|
var imageUpload;
|
||||||
type: 'js',
|
var self = this;
|
||||||
default: et2_no_init
|
if (this.options.imageUpload && this.options.imageUpload[0] !== '/' && this.options.imageUpload.substr(0, 4) != 'http') {
|
||||||
},
|
imageUpload = egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_htmlarea_upload") +
|
||||||
images_upload_handler: {
|
'&request_id=' + this.getInstanceManager().etemplate_exec_id + '&widget_id=' + this.options.imageUpload + '&type=htmlarea';
|
||||||
name: "Images upload handler",
|
imageUpload = imageUpload.substr(egw.webserverUrl.length + 1);
|
||||||
description: "Callback function for handling image upload",
|
}
|
||||||
type: 'js',
|
else if (imageUpload) {
|
||||||
default: et2_no_init
|
imageUpload = this.options.imageUpload.substr(egw.webserverUrl.length + 1);
|
||||||
},
|
}
|
||||||
menubar: {
|
else {
|
||||||
name: "Menubar",
|
imageUpload = egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_htmlarea_upload") +
|
||||||
description: "Display menubar at the top of the editor",
|
'&request_id=' + this.getInstanceManager().etemplate_exec_id + '&type=htmlarea';
|
||||||
type: "boolean",
|
}
|
||||||
default: true
|
// default settings for initialization
|
||||||
},
|
var settings = {
|
||||||
statusbar: {
|
target: this.htmlNode[0],
|
||||||
name: "Status bar",
|
body_id: this.dom_id + '_htmlarea',
|
||||||
description: "Enable/disable status bar on the bottom of editor",
|
menubar: false,
|
||||||
type: "boolean",
|
statusbar: this.options.statusbar,
|
||||||
default: true
|
branding: false,
|
||||||
},
|
resize: false,
|
||||||
valid_children: {
|
height: this.options.height,
|
||||||
name: "Valid children",
|
width: this.options.width,
|
||||||
description: "Enables to control what child tag is allowed or not allowed of the present tag. For instance: +body[style], makes style tag allowed inside body",
|
mobile: {
|
||||||
type: "string",
|
theme: 'silver'
|
||||||
default: "+body[style]"
|
},
|
||||||
}
|
formats: {
|
||||||
},
|
customparagraph: { block: 'p', styles: { "margin-block-start": "0px", "margin-block-end": "0px" } }
|
||||||
|
},
|
||||||
/**
|
min_height: 100,
|
||||||
* Constructor
|
convert_urls: false,
|
||||||
*
|
language: et2_htmlarea.LANGUAGE_CODE[egw.preference('lang', 'common')],
|
||||||
* @param _parent
|
language_url: egw.webserverUrl + '/api/js/tinymce/langs/' + et2_htmlarea.LANGUAGE_CODE[egw.preference('lang', 'common')] + '.js',
|
||||||
* @param _attrs
|
paste_data_images: true,
|
||||||
* @memberOf et2_htmlarea
|
paste_filter_drop: true,
|
||||||
*/
|
browser_spellcheck: true,
|
||||||
init: function(_parent, _attrs) {
|
contextmenu: false,
|
||||||
this._super.apply(this, arguments);
|
images_upload_url: imageUpload,
|
||||||
this.editor = null; // TinyMce editor instance
|
file_picker_callback: jQuery.proxy(this._file_picker_callback, this),
|
||||||
this.supportedWidgetClasses = []; // Allow no child widgets
|
images_upload_handler: this.options.images_upload_handler,
|
||||||
this.htmlNode = jQuery(document.createElement(this.options.readonly ? "div" : "textarea"))
|
init_instance_callback: jQuery.proxy(this._instanceIsReady, this),
|
||||||
.addClass('et2_textbox_ro');
|
auto_focus: false,
|
||||||
if(this.options.height)
|
valid_children: this.options.valid_children,
|
||||||
{
|
plugins: [
|
||||||
this.htmlNode.css('height', this.options.height);
|
"print searchreplace autolink directionality ",
|
||||||
}
|
"visualblocks visualchars image link media template ",
|
||||||
this.setDOMNode(this.htmlNode[0]);
|
"codesample table charmap hr pagebreak nonbreaking anchor toc ",
|
||||||
},
|
"insertdatetime advlist lists textcolor wordcount imagetools ",
|
||||||
|
"colorpicker textpattern help paste code searchreplace tabfocus"
|
||||||
/**
|
],
|
||||||
*
|
toolbar: et2_htmlarea.TOOLBAR_SIMPLE,
|
||||||
* @returns {undefined}
|
block_formats: "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;" +
|
||||||
*/
|
"Heading 4=h4;Heading 5=h5;Heading 6=h6;Preformatted=pre;Custom Paragraph=customparagraph",
|
||||||
doLoadingFinished: function() {
|
font_formats: "Andale Mono=andale mono,times;Arial=arial,helvetica," +
|
||||||
this._super.apply(this, arguments);
|
"sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book " +
|
||||||
|
"antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;" +
|
||||||
this.init_editor();
|
"Courier New=courier new,courier;Georgia=georgia,palatino;" +
|
||||||
},
|
"Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;" +
|
||||||
|
"Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal," +
|
||||||
init_editor: function() {
|
"monaco;Times New Roman=times new roman,times;Trebuchet " +
|
||||||
if(this.mode == 'ascii' || this.editor != null || this.options.readonly) return;
|
"MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;" +
|
||||||
var imageUpload = '';
|
"Wingdings=wingdings,zapf dingbats",
|
||||||
var self = this;
|
fontsize_formats: '8pt 10pt 12pt 14pt 18pt 24pt 36pt',
|
||||||
if (this.options.imageUpload && this.options.imageUpload[0] !== '/' && this.options.imageUpload.substr(0, 4) != 'http')
|
setup: function (ed) {
|
||||||
{
|
ed.on('init', function () {
|
||||||
imageUpload = egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_htmlarea_upload")+
|
|
||||||
'&request_id='+this.getInstanceManager().etemplate_exec_id+'&widget_id='+this.options.imageUpload+'&type=htmlarea';
|
|
||||||
imageUpload = imageUpload.substr(egw.webserverUrl.length+1);
|
|
||||||
}
|
|
||||||
else if (imageUpload)
|
|
||||||
{
|
|
||||||
imageUpload = this.options.imageUpload.substr(egw.webserverUrl.length+1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
imageUpload = egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_htmlarea_upload")+
|
|
||||||
'&request_id='+this.getInstanceManager().etemplate_exec_id+'&type=htmlarea';
|
|
||||||
}
|
|
||||||
// default settings for initialization
|
|
||||||
var settings = {
|
|
||||||
target: this.htmlNode[0],
|
|
||||||
body_id: this.dom + '_htmlarea',
|
|
||||||
menubar: false,
|
|
||||||
statusbar: this.options.statusbar,
|
|
||||||
branding: false,
|
|
||||||
resize: false,
|
|
||||||
height: this.options.height,
|
|
||||||
width: this.options.width,
|
|
||||||
mobile: {
|
|
||||||
theme: 'silver'
|
|
||||||
},
|
|
||||||
formats: {
|
|
||||||
customparagraph: { block: 'p', styles: {"margin-block-start": "0px", "margin-block-end": "0px"}}
|
|
||||||
},
|
|
||||||
min_height: 100,
|
|
||||||
convert_urls: false,
|
|
||||||
language: et2_htmlarea.LANGUAGE_CODE[egw.preference('lang', 'common')],
|
|
||||||
language_url: egw.webserverUrl+'/api/js/tinymce/langs/'+et2_htmlarea.LANGUAGE_CODE[egw.preference('lang', 'common')]+'.js',
|
|
||||||
paste_data_images: true,
|
|
||||||
paste_filter_drop: true,
|
|
||||||
browser_spellcheck: true,
|
|
||||||
contextmenu: false,
|
|
||||||
images_upload_url: imageUpload,
|
|
||||||
file_picker_callback: jQuery.proxy(this._file_picker_callback, this),
|
|
||||||
images_upload_handler: this.options.images_upload_handler,
|
|
||||||
init_instance_callback : jQuery.proxy(this._instanceIsReady, this),
|
|
||||||
auto_focus: false,
|
|
||||||
valid_children : this.options.valid_children,
|
|
||||||
plugins: [
|
|
||||||
"print searchreplace autolink directionality ",
|
|
||||||
"visualblocks visualchars image link media template ",
|
|
||||||
"codesample table charmap hr pagebreak nonbreaking anchor toc ",
|
|
||||||
"insertdatetime advlist lists textcolor wordcount imagetools ",
|
|
||||||
"colorpicker textpattern help paste code searchreplace tabfocus"
|
|
||||||
],
|
|
||||||
toolbar: et2_htmlarea.TOOLBAR_SIMPLE,
|
|
||||||
block_formats: "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;"+
|
|
||||||
"Heading 4=h4;Heading 5=h5;Heading 6=h6;Preformatted=pre;Custom Paragraph=customparagraph",
|
|
||||||
font_formats: "Andale Mono=andale mono,times;Arial=arial,helvetica,"+
|
|
||||||
"sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book "+
|
|
||||||
"antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;"+
|
|
||||||
"Courier New=courier new,courier;Georgia=georgia,palatino;"+
|
|
||||||
"Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;"+
|
|
||||||
"Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,"+
|
|
||||||
"monaco;Times New Roman=times new roman,times;Trebuchet "+
|
|
||||||
"MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;"+
|
|
||||||
"Wingdings=wingdings,zapf dingbats",
|
|
||||||
fontsize_formats: '8pt 10pt 12pt 14pt 18pt 24pt 36pt',
|
|
||||||
setup : function(ed)
|
|
||||||
{
|
|
||||||
ed.on('init', function()
|
|
||||||
{
|
|
||||||
this.getDoc().body.style.fontSize = egw.preference('rte_font_size', 'common')
|
this.getDoc().body.style.fontSize = egw.preference('rte_font_size', 'common')
|
||||||
+ egw.preference('rte_font_unit', 'common');
|
+ egw.preference('rte_font_unit', 'common');
|
||||||
this.getDoc().body.style.fontFamily = egw.preference('rte_font', 'common');
|
this.getDoc().body.style.fontFamily = egw.preference('rte_font', 'common');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// extend default settings with configured options and preferences
|
||||||
// extend default settings with configured options and preferences
|
jQuery.extend(settings, this._extendedSettings());
|
||||||
jQuery.extend(settings, this._extendedSettings());
|
this.tinymce = tinymce.init(settings);
|
||||||
this.tinymce = tinymce.init(settings);
|
// make sure value gets set in case of widget gets loaded by delay like
|
||||||
// make sure value gets set in case of widget gets loaded by delay like
|
// inside an inactive tabs
|
||||||
// inside an inactive tabs
|
this.tinymce.then(function () {
|
||||||
this.tinymce.then(function() {
|
self.set_value(self.htmlNode.val());
|
||||||
self.set_value(self.htmlNode.val());
|
if (self.editor && self.editor.editorContainer) {
|
||||||
if (self.editor && self.editor.editorContainer)
|
self.editor.formatter.toggle(egw.preference('rte_formatblock', 'common'));
|
||||||
{
|
jQuery(self.editor.editorContainer).height(self.options.height);
|
||||||
self.editor.formatter.toggle(egw.preference('rte_formatblock', 'common'));
|
jQuery(self.editor.iframeElement.contentWindow.document).on('dragenter', function () {
|
||||||
jQuery(self.editor.editorContainer).height(self.options.height);
|
if (jQuery('#dragover-tinymce').length < 1)
|
||||||
jQuery(self.editor.iframeElement.contentWindow.document).on('dragenter', function(){
|
jQuery("<style id='dragover-tinymce'>.dragover:after {height:calc(100% - " + jQuery(this).height() + "px) !important;}</style>").appendTo('head');
|
||||||
if (jQuery('#dragover-tinymce').length < 1) jQuery("<style id='dragover-tinymce'>.dragover:after {height:calc(100% - "+jQuery(this).height()+"px) !important;}</style>").appendTo('head');
|
});
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
});
|
};
|
||||||
},
|
/**
|
||||||
|
* set disabled
|
||||||
/**
|
*
|
||||||
* set disabled
|
* @param {type} _value
|
||||||
*
|
* @returns {undefined}
|
||||||
* @param {type} _value
|
*/
|
||||||
* @returns {undefined}
|
et2_htmlarea.prototype.set_disabled = function (_value) {
|
||||||
*/
|
_super.prototype.set_disabled.call(this, _value);
|
||||||
set_disabled: function(_value)
|
if (_value) {
|
||||||
{
|
jQuery(this.tinymce_container).css('display', 'none');
|
||||||
this._super.apply(this, arguments);
|
}
|
||||||
if (_value)
|
else {
|
||||||
{
|
jQuery(this.tinymce_container).css('display', 'flex');
|
||||||
jQuery(this.tinymce_container).css('display', 'none');
|
}
|
||||||
}
|
};
|
||||||
else
|
et2_htmlarea.prototype.set_readonly = function (_value) {
|
||||||
{
|
if (this.options.readonly === _value)
|
||||||
jQuery(this.tinymce_container).css('display', 'flex');
|
return;
|
||||||
}
|
var value = this.get_value();
|
||||||
},
|
this.options.readonly = _value;
|
||||||
|
if (this.options.readonly) {
|
||||||
set_readonly: function(_value)
|
if (this.editor)
|
||||||
{
|
this.editor.remove();
|
||||||
if(this.options.readonly === _value) return;
|
this.htmlNode = jQuery(document.createElement(this.options.readonly ? "div" : "textarea"))
|
||||||
var value = this.get_value();
|
.addClass('et2_textbox_ro');
|
||||||
this.options.readonly = _value;
|
if (this.options.height) {
|
||||||
if(this.options.readonly)
|
this.htmlNode.css('height', this.options.height);
|
||||||
{
|
}
|
||||||
if (this. editor) this.editor.remove();
|
this.editor = null;
|
||||||
this.htmlNode = jQuery(document.createElement(this.options.readonly ? "div" : "textarea"))
|
this.setDOMNode(this.htmlNode[0]);
|
||||||
.addClass('et2_textbox_ro');
|
this.set_value(value);
|
||||||
if(this.options.height)
|
}
|
||||||
{
|
else {
|
||||||
this.htmlNode.css('height', this.options.height)
|
if (!this.editor) {
|
||||||
}
|
this.htmlNode = jQuery(document.createElement("textarea"))
|
||||||
this.editor = null;
|
.val(value);
|
||||||
this.setDOMNode(this.htmlNode[0]);
|
if (this.options.height || this.options.editable_height) {
|
||||||
this.set_value(value);
|
this.htmlNode.css('height', (this.options.editable_height ? this.options.editable_height : this.options.height));
|
||||||
}
|
}
|
||||||
else
|
this.setDOMNode(this.htmlNode[0]);
|
||||||
{
|
this.init_editor();
|
||||||
if(!this.editor)
|
}
|
||||||
{
|
}
|
||||||
this.htmlNode = jQuery(document.createElement("textarea"))
|
};
|
||||||
.val(value);
|
/**
|
||||||
if(this.options.height || this.options.editable_height)
|
* Callback function runs when the filepicker in image dialog is clicked
|
||||||
{
|
*
|
||||||
this.htmlNode.css('height', (this.options.editable_height ? this.options.editable_height : this.options.height));
|
* @param {type} _callback
|
||||||
}
|
* @param {type} _value
|
||||||
this.setDOMNode(this.htmlNode[0]);
|
* @param {type} _meta
|
||||||
this.init_editor();
|
*/
|
||||||
}
|
et2_htmlarea.prototype._file_picker_callback = function (_callback, _value, _meta) {
|
||||||
}
|
if (typeof this.file_picker_callback == 'function')
|
||||||
},
|
return this.file_picker_callback.call(arguments, this);
|
||||||
|
var callback = _callback;
|
||||||
/**
|
// Don't rely only on app_name to fetch et2 object as app_name may not
|
||||||
* Callback function runs when the filepicker in image dialog is clicked
|
// always represent current app of the window, e.g.: mail admin account.
|
||||||
*
|
// Try to fetch et2 from its template name.
|
||||||
* @param {type} _callback
|
var etemplate = jQuery('form').data('etemplate');
|
||||||
* @param {type} _value
|
var et2;
|
||||||
* @param {type} _meta
|
if (etemplate && etemplate.name && !app[egw(window).app_name()]) {
|
||||||
* @returns {unresolved}
|
et2 = etemplate2.getByTemplate(etemplate.name)[0]['widgetContainer'];
|
||||||
*/
|
}
|
||||||
_file_picker_callback: function(_callback, _value, _meta) {
|
else {
|
||||||
if (typeof this.file_picker_callback == 'function') return this.file_picker_callback.call(arguments, this);
|
et2 = app[egw(window).app_name()].et2;
|
||||||
var callback = _callback;
|
}
|
||||||
|
var vfsSelect = et2_createWidget('vfs-select', {
|
||||||
// Don't rely only on app_name to fetch et2 object as app_name may not
|
id: 'upload',
|
||||||
// always represent current app of the window, e.g.: mail admin account.
|
mode: 'open',
|
||||||
// Try to fetch et2 from its template name.
|
name: '',
|
||||||
var etemplate = jQuery('form').data('etemplate');
|
button_caption: "Link",
|
||||||
var et2 = {};
|
button_label: "Link",
|
||||||
if (etemplate && etemplate.name && !app[egw(window).app_name()])
|
dialog_title: "Link file",
|
||||||
{
|
method: "download"
|
||||||
et2 = etemplate2.getByTemplate(etemplate.name)[0]['widgetContainer'];
|
}, et2);
|
||||||
}
|
jQuery(vfsSelect.getDOMNode()).on('change', function () {
|
||||||
else
|
callback(vfsSelect.get_value(), { alt: vfsSelect.get_value() });
|
||||||
{
|
});
|
||||||
et2 = app[egw(window).app_name()].et2;
|
// start the file selector dialog
|
||||||
}
|
vfsSelect.click();
|
||||||
|
};
|
||||||
var vfsSelect = et2_createWidget('vfs-select', {
|
/**
|
||||||
id:'upload',
|
* Callback when instance is ready
|
||||||
mode: 'open',
|
*
|
||||||
name: '',
|
* @param {type} _editor
|
||||||
button_caption:"Link",
|
*/
|
||||||
button_label:"Link",
|
et2_htmlarea.prototype._instanceIsReady = function (_editor) {
|
||||||
dialog_title: "Link file",
|
console.log("Editor: " + _editor.id + " is now initialized.");
|
||||||
method: "download"
|
// try to reserve focus state as running command on editor may steal the
|
||||||
}, et2);
|
// current focus.
|
||||||
jQuery(vfsSelect.getDOMNode()).on('change', function (){
|
var focusedEl = jQuery(':focus');
|
||||||
callback(vfsSelect.get_value(), {alt:vfsSelect.get_value()});
|
this.editor = _editor;
|
||||||
});
|
this.editor.on('drop', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
// start the file selector dialog
|
});
|
||||||
vfsSelect.click();
|
if (!this.disabled)
|
||||||
},
|
jQuery(this.editor.editorContainer).css('display', 'flex');
|
||||||
|
this.tinymce_container = this.editor.editorContainer;
|
||||||
/**
|
// go back to reserved focused element
|
||||||
* Callback when instance is ready
|
focusedEl.focus();
|
||||||
*
|
};
|
||||||
* @param {type} _editor
|
/**
|
||||||
*/
|
* Takes all relevant preferences into account and set settings accordingly
|
||||||
_instanceIsReady: function(_editor) {
|
*
|
||||||
console.log("Editor: " + _editor.id + " is now initialized.");
|
* @returns {object} returns a object including all settings
|
||||||
// try to reserve focus state as running command on editor may steal the
|
*/
|
||||||
// current focus.
|
et2_htmlarea.prototype._extendedSettings = function () {
|
||||||
var focusedEl = jQuery(':focus');
|
var rte_menubar = egw.preference('rte_menubar', 'common');
|
||||||
this.editor = _editor;
|
var rte_toolbar = egw.preference('rte_toolbar', 'common');
|
||||||
|
// we need to have rte_toolbar values as an array
|
||||||
this.editor.on('drop', function(e){
|
if (rte_toolbar && typeof rte_toolbar == "object") {
|
||||||
e.preventDefault();
|
rte_toolbar = Object.keys(rte_toolbar).map(function (key) { return rte_toolbar[key]; });
|
||||||
});
|
}
|
||||||
|
var settings = {
|
||||||
if (!this.disabled) jQuery(this.editor.editorContainer).css('display', 'flex');
|
fontsize_formats: et2_htmlarea.FONT_SIZE_FORMATS[egw.preference('rte_font_unit', 'common')],
|
||||||
this.tinymce_container = this.editor.editorContainer;
|
menubar: parseInt(rte_menubar) && this.menubar ? true : typeof rte_menubar != 'undefined' ? false : this.menubar
|
||||||
// go back to reserved focused element
|
};
|
||||||
focusedEl.focus();
|
switch (this.mode) {
|
||||||
},
|
case 'simple':
|
||||||
|
settings['toolbar'] = et2_htmlarea.TOOLBAR_SIMPLE;
|
||||||
/**
|
break;
|
||||||
* Takes all relevant preferences into account and set settings accordingly
|
case 'extended':
|
||||||
*
|
settings['toolbar'] = et2_htmlarea.TOOLBAR_EXTENDED;
|
||||||
* @returns {object} returns a object including all settings
|
break;
|
||||||
*/
|
case 'advanced':
|
||||||
_extendedSettings: function () {
|
settings['toolbar'] = et2_htmlarea.TOOLBAR_ADVANCED;
|
||||||
|
break;
|
||||||
var rte_menubar = egw.preference('rte_menubar', 'common');
|
default:
|
||||||
var rte_toolbar = egw.preference('rte_toolbar', 'common');
|
this.mode = '';
|
||||||
// we need to have rte_toolbar values as an array
|
}
|
||||||
if (rte_toolbar && typeof rte_toolbar == "object")
|
// take rte_toolbar into account if no mode restrictly set from template
|
||||||
{
|
if (rte_toolbar && !this.mode) {
|
||||||
rte_toolbar = Object.values(rte_toolbar);
|
var toolbar_diff = et2_htmlarea.TOOLBAR_LIST.filter(function (i) { return !(rte_toolbar.indexOf(i) > -1); });
|
||||||
}
|
settings['toolbar'] = et2_htmlarea.TOOLBAR_ADVANCED;
|
||||||
var settings = {
|
toolbar_diff.forEach(function (a) {
|
||||||
fontsize_formats: et2_htmlarea.FONT_SIZE_FORMATS[egw.preference('rte_font_unit', 'common')],
|
var r = new RegExp(a);
|
||||||
menubar: parseInt(rte_menubar) && this.menubar ? true : typeof rte_menubar != 'undefined' ? false : this.menubar
|
settings['toolbar'] = settings['toolbar'].replace(r, '');
|
||||||
};
|
});
|
||||||
|
}
|
||||||
switch (this.mode)
|
return settings;
|
||||||
{
|
};
|
||||||
case 'simple':
|
et2_htmlarea.prototype.destroy = function () {
|
||||||
settings.toolbar = et2_htmlarea.TOOLBAR_SIMPLE;
|
if (this.editor) {
|
||||||
break;
|
this.editor.destroy();
|
||||||
case 'extended':
|
}
|
||||||
settings.toolbar = et2_htmlarea.TOOLBAR_EXTENDED;
|
this.editor = null;
|
||||||
break;
|
this.tinymce = null;
|
||||||
case 'advanced':
|
this.tinymce_container = null;
|
||||||
settings.toolbar = et2_htmlarea.TOOLBAR_ADVANCED;
|
this.htmlNode.remove();
|
||||||
break;
|
this.htmlNode = null;
|
||||||
default:
|
_super.prototype.destroy.call(this);
|
||||||
this.mode = '';
|
};
|
||||||
}
|
et2_htmlarea.prototype.set_value = function (_value) {
|
||||||
|
this._oldValue = _value;
|
||||||
// take rte_toolbar into account if no mode restrictly set from template
|
if (this.editor) {
|
||||||
if (rte_toolbar && !this.mode)
|
this.editor.setContent(_value);
|
||||||
{
|
}
|
||||||
var toolbar_diff = et2_htmlarea.TOOLBAR_LIST.filter(function(i){return !(rte_toolbar.indexOf(i) > -1);});
|
else {
|
||||||
settings.toolbar = et2_htmlarea.TOOLBAR_ADVANCED;
|
if (this.options.readonly) {
|
||||||
toolbar_diff.forEach(function(a){
|
this.htmlNode.empty().append(_value);
|
||||||
var r = new RegExp(a);
|
}
|
||||||
settings.toolbar = settings.toolbar.replace(r, '');
|
else {
|
||||||
});
|
this.htmlNode.val(_value);
|
||||||
}
|
}
|
||||||
return settings;
|
}
|
||||||
},
|
this.value = _value;
|
||||||
|
};
|
||||||
destroy: function() {
|
et2_htmlarea.prototype.getValue = function () {
|
||||||
if (this.editor)
|
return this.editor ? this.editor.getContent() : (this.options.readonly ? this.value : this.htmlNode.val());
|
||||||
{
|
};
|
||||||
this.editor.destroy();
|
/**
|
||||||
}
|
* Resize htmlNode tag according to window size
|
||||||
this.editor = null;
|
* @param {type} _height excess height which comes from window resize
|
||||||
this.tinymce = null;
|
*/
|
||||||
this.tinymce_container = null;
|
et2_htmlarea.prototype.resize = function (_height) {
|
||||||
this.htmlNode.remove();
|
if (_height && this.options.resize_ratio !== '0') {
|
||||||
this.htmlNode = null;
|
// apply the ratio
|
||||||
this._super.apply(this, arguments);
|
_height = (this.options.resize_ratio != '') ? _height * this.options.resize_ratio : _height;
|
||||||
},
|
if (_height != 0) {
|
||||||
set_value: function(_value) {
|
if (this.editor) // TinyMCE HTML
|
||||||
this._oldValue = _value;
|
{
|
||||||
if (this.editor)
|
var h = void 0;
|
||||||
{
|
if (typeof this.editor.iframeElement != 'undefined' && this.editor.editorContainer.clientHeight > 0) {
|
||||||
this.editor.setContent(_value);
|
h = (this.editor.editorContainer.clientHeight + _height) > 0 ?
|
||||||
}
|
(this.editor.editorContainer.clientHeight) + _height : this.editor.settings.min_height;
|
||||||
else
|
}
|
||||||
{
|
else // fallback height size
|
||||||
if(this.options.readonly)
|
{
|
||||||
{
|
h = this.editor.settings.min_height + _height;
|
||||||
this.htmlNode.empty().append(_value);
|
}
|
||||||
}
|
jQuery(this.editor.editorContainer).height(h);
|
||||||
else
|
jQuery(this.editor.iframeElement).height(h - (this.editor.editorContainer.getElementsByClassName('tox-toolbar')[0].clientHeight +
|
||||||
{
|
this.editor.editorContainer.getElementsByClassName('tox-statusbar')[0].clientHeight));
|
||||||
this.htmlNode.val(_value);
|
}
|
||||||
}
|
else // No TinyMCE
|
||||||
}
|
{
|
||||||
this.value = _value;
|
this.htmlNode.height(this.htmlNode.height() + _height);
|
||||||
},
|
}
|
||||||
|
}
|
||||||
getValue: function() {
|
}
|
||||||
return this.editor ? this.editor.getContent() : (
|
};
|
||||||
this.options.readonly ? this.value : this.htmlNode.val()
|
et2_htmlarea._attributes = {
|
||||||
);
|
mode: {
|
||||||
},
|
'name': 'Mode',
|
||||||
|
'description': 'One of {ascii|simple|extended|advanced}',
|
||||||
/**
|
'default': '',
|
||||||
* Resize htmlNode tag according to window size
|
'type': 'string'
|
||||||
* @param {type} _height excess height which comes from window resize
|
},
|
||||||
*/
|
height: {
|
||||||
resize: function (_height)
|
'name': 'Height',
|
||||||
{
|
'default': et2_no_init,
|
||||||
if (_height && this.options.resize_ratio !== '0')
|
'type': 'string'
|
||||||
{
|
},
|
||||||
// apply the ratio
|
width: {
|
||||||
_height = (this.options.resize_ratio != '')? _height * this.options.resize_ratio: _height;
|
'name': 'Width',
|
||||||
if (_height != 0)
|
'default': et2_no_init,
|
||||||
{
|
'type': 'string'
|
||||||
if (this.editor) // TinyMCE HTML
|
},
|
||||||
{
|
value: {
|
||||||
var h = 0;
|
name: "Value",
|
||||||
if (typeof this.editor.iframeElement !='undefined' && this.editor.editorContainer.clientHeight > 0)
|
description: "The value of the widget",
|
||||||
{
|
type: "html",
|
||||||
h = (this.editor.editorContainer.clientHeight + _height) > 0 ?
|
default: et2_no_init
|
||||||
(this.editor.editorContainer.clientHeight) + _height: this.editor.settings.min_height;
|
},
|
||||||
}
|
imageUpload: {
|
||||||
else // fallback height size
|
name: "imageUpload",
|
||||||
{
|
description: "Url to upload images dragged in or id of link_to widget to it's vfs upload. Can also be just a name for which content array contains a path to upload the picture.",
|
||||||
h = this.editor.settings.min_height + _height;
|
type: "string",
|
||||||
}
|
default: null
|
||||||
jQuery(this.editor.editorContainer).height(h);
|
},
|
||||||
jQuery(this.editor.iframeElement).height(h - (this.editor.editorContainer.getElementsByClassName('tox-toolbar')[0].clientHeight +
|
file_picker_callback: {
|
||||||
this.editor.editorContainer.getElementsByClassName('tox-statusbar')[0].clientHeight));
|
name: "File picker callback",
|
||||||
}
|
description: "Callback function to get called when file picker is clicked",
|
||||||
else // No TinyMCE
|
type: 'js',
|
||||||
{
|
default: et2_no_init
|
||||||
this.htmlNode.height(this.htmlNode.height() + _height);
|
},
|
||||||
}
|
images_upload_handler: {
|
||||||
}
|
name: "Images upload handler",
|
||||||
}
|
description: "Callback function for handling image upload",
|
||||||
}
|
type: 'js',
|
||||||
});}).call(this);
|
default: et2_no_init
|
||||||
et2_register_widget(et2_htmlarea, ["htmlarea"]);
|
},
|
||||||
|
menubar: {
|
||||||
// Static class stuff
|
name: "Menubar",
|
||||||
jQuery.extend(et2_htmlarea, {
|
description: "Display menubar at the top of the editor",
|
||||||
/**
|
type: "boolean",
|
||||||
* Array of toolbars
|
default: true
|
||||||
* @constant
|
},
|
||||||
*/
|
statusbar: {
|
||||||
TOOLBAR_LIST: ['undo', 'redo', 'formatselect', 'fontselect', 'fontsizeselect',
|
name: "Status bar",
|
||||||
'bold', 'italic', 'strikethrough', 'forecolor', 'backcolor', 'link',
|
description: "Enable/disable status bar on the bottom of editor",
|
||||||
'alignleft', 'aligncenter', 'alignright', 'alignjustify', 'numlist',
|
type: "boolean",
|
||||||
'bullist', 'outdent', 'indent', 'ltr', 'rtl', 'removeformat', 'code', 'image', 'searchreplace'
|
default: true
|
||||||
],
|
},
|
||||||
/**
|
valid_children: {
|
||||||
* arranged toolbars as simple mode
|
name: "Valid children",
|
||||||
* @constant
|
description: "Enables to control what child tag is allowed or not allowed of the present tag. For instance: +body[style], makes style tag allowed inside body",
|
||||||
*/
|
type: "string",
|
||||||
TOOLBAR_SIMPLE: "undo redo|formatselect fontselect fontsizeselect | bold italic removeformat forecolor backcolor | "+
|
default: "+body[style]"
|
||||||
"alignleft aligncenter alignright alignjustify | numlist "+
|
}
|
||||||
"bullist outdent indent| link image pastetext",
|
};
|
||||||
/**
|
/**
|
||||||
* arranged toolbars as extended mode
|
* Array of toolbars
|
||||||
* @constant
|
* @constant
|
||||||
*/
|
*/
|
||||||
TOOLBAR_EXTENDED: "fontselect fontsizeselect | bold italic strikethrough forecolor backcolor | "+
|
et2_htmlarea.TOOLBAR_LIST = ['undo', 'redo', 'formatselect', 'fontselect', 'fontsizeselect',
|
||||||
"link | alignleft aligncenter alignright alignjustify | numlist "+
|
'bold', 'italic', 'strikethrough', 'forecolor', 'backcolor', 'link',
|
||||||
"bullist outdent indent | removeformat | image",
|
'alignleft', 'aligncenter', 'alignright', 'alignjustify', 'numlist',
|
||||||
/**
|
'bullist', 'outdent', 'indent', 'ltr', 'rtl', 'removeformat', 'code', 'image', 'searchreplace'
|
||||||
* arranged toolbars as advanced mode
|
];
|
||||||
* @constant
|
/**
|
||||||
*/
|
* arranged toolbars as simple mode
|
||||||
TOOLBAR_ADVANCED: "undo redo| formatselect | fontselect fontsizeselect | bold italic strikethrough forecolor backcolor | "+
|
* @constant
|
||||||
"link | alignleft aligncenter alignright alignjustify | numlist "+
|
*/
|
||||||
"bullist outdent indent ltr rtl | removeformat code| image | searchreplace",
|
et2_htmlarea.TOOLBAR_SIMPLE = "undo redo|formatselect fontselect fontsizeselect | bold italic removeformat forecolor backcolor | " +
|
||||||
/**
|
"alignleft aligncenter alignright alignjustify | numlist " +
|
||||||
* font size formats
|
"bullist outdent indent| link image pastetext";
|
||||||
* @constant
|
/**
|
||||||
*/
|
* arranged toolbars as extended mode
|
||||||
FONT_SIZE_FORMATS: {
|
* @constant
|
||||||
pt: "8pt 10pt 12pt 14pt 18pt 24pt 36pt 48pt 72pt",
|
*/
|
||||||
px:"8px 10px 12px 14px 18px 24px 36px 48px 72px"
|
et2_htmlarea.TOOLBAR_EXTENDED = "fontselect fontsizeselect | bold italic strikethrough forecolor backcolor | " +
|
||||||
},
|
"link | alignleft aligncenter alignright alignjustify | numlist " +
|
||||||
|
"bullist outdent indent | removeformat | image";
|
||||||
/**
|
/**
|
||||||
* language code represention for TinyMCE lang code
|
* arranged toolbars as advanced mode
|
||||||
*/
|
* @constant
|
||||||
LANGUAGE_CODE: {
|
*/
|
||||||
bg: "bg_BG", ca: "ca", cs: "cs", da: "da", de: "de", en:"en_CA",
|
et2_htmlarea.TOOLBAR_ADVANCED = "undo redo| formatselect | fontselect fontsizeselect | bold italic strikethrough forecolor backcolor | " +
|
||||||
el:"el", "es-es":"es", et: "et", eu: "eu" , fa: "fa_IR", fi: "fi",
|
"link | alignleft aligncenter alignright alignjustify | numlist " +
|
||||||
fr: "fr_FR", hi:"", hr:"hr", hu:"hu_HU", id: "id", it: "it", iw: "",
|
"bullist outdent indent ltr rtl | removeformat code| image | searchreplace";
|
||||||
ja: "ja", ko: "ko_KR", lo: "", lt: "lt", lv: "lv", nl: "nl", no: "nb_NO",
|
/**
|
||||||
pl: "pl", pt: "pt_PT", "pt-br": "pt_BR", ru: "ru", sk: "sk", sl: "sl_SI",
|
* font size formats
|
||||||
sv: "sv_SE", th: "th_TH", tr: "tr_TR", uk: "en_GB", vi: "vi_VN", zh: "zh_CN",
|
* @constant
|
||||||
"zh-tw": "zh_TW"
|
*/
|
||||||
}
|
et2_htmlarea.FONT_SIZE_FORMATS = {
|
||||||
});
|
pt: "8pt 10pt 12pt 14pt 18pt 24pt 36pt 48pt 72pt",
|
||||||
|
px: "8px 10px 12px 14px 18px 24px 36px 48px 72px"
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* language code represention for TinyMCE lang code
|
||||||
|
*/
|
||||||
|
et2_htmlarea.LANGUAGE_CODE = {
|
||||||
|
bg: "bg_BG", ca: "ca", cs: "cs", da: "da", de: "de", en: "en_CA",
|
||||||
|
el: "el", "es-es": "es", et: "et", eu: "eu", fa: "fa_IR", fi: "fi",
|
||||||
|
fr: "fr_FR", hi: "", hr: "hr", hu: "hu_HU", id: "id", it: "it", iw: "",
|
||||||
|
ja: "ja", ko: "ko_KR", lo: "", lt: "lt", lv: "lv", nl: "nl", no: "nb_NO",
|
||||||
|
pl: "pl", pt: "pt_PT", "pt-br": "pt_BR", ru: "ru", sk: "sk", sl: "sl_SI",
|
||||||
|
sv: "sv_SE", th: "th_TH", tr: "tr_TR", uk: "en_GB", vi: "vi_VN", zh: "zh_CN",
|
||||||
|
"zh-tw": "zh_TW"
|
||||||
|
};
|
||||||
|
return et2_htmlarea;
|
||||||
|
}(et2_core_editableWidget_1.et2_editableWidget));
|
||||||
|
et2_core_widget_1.et2_register_widget(et2_htmlarea, ["htmlarea"]);
|
||||||
|
//# sourceMappingURL=et2_widget_htmlarea.js.map
|
525
api/js/etemplate/et2_widget_htmlarea.ts
Normal file
525
api/js/etemplate/et2_widget_htmlarea.ts
Normal file
@ -0,0 +1,525 @@
|
|||||||
|
/**
|
||||||
|
* EGroupware eTemplate2 - JS widget for HTML editing
|
||||||
|
*
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package etemplate
|
||||||
|
* @subpackage api
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @author Hadi Nategh <hn@egroupware.org>
|
||||||
|
* @copyright Hadi Nategh <hn@egroupware.org>
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*egw:uses
|
||||||
|
jsapi.jsapi; // Needed for egw_seperateJavaScript
|
||||||
|
/vendor/tinymce/tinymce/tinymce.min.js;
|
||||||
|
et2_core_editableWidget;
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {et2_editableWidget} from "./et2_core_editableWidget";
|
||||||
|
import {ClassWithAttributes} from "./et2_core_inheritance";
|
||||||
|
import {WidgetConfig, et2_register_widget} from "./et2_core_widget";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @augments et2_inputWidget
|
||||||
|
*/
|
||||||
|
class et2_htmlarea extends et2_editableWidget implements et2_IResizeable
|
||||||
|
{
|
||||||
|
static readonly _attributes : any = {
|
||||||
|
mode: {
|
||||||
|
'name': 'Mode',
|
||||||
|
'description': 'One of {ascii|simple|extended|advanced}',
|
||||||
|
'default': '',
|
||||||
|
'type': 'string'
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
'name': 'Height',
|
||||||
|
'default': et2_no_init,
|
||||||
|
'type': 'string'
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
'name': 'Width',
|
||||||
|
'default': et2_no_init,
|
||||||
|
'type': 'string'
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
name: "Value",
|
||||||
|
description: "The value of the widget",
|
||||||
|
type: "html", // "string" would remove html tags by running html_entity_decode
|
||||||
|
default: et2_no_init
|
||||||
|
},
|
||||||
|
imageUpload: {
|
||||||
|
name: "imageUpload",
|
||||||
|
description: "Url to upload images dragged in or id of link_to widget to it's vfs upload. Can also be just a name for which content array contains a path to upload the picture.",
|
||||||
|
type: "string",
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
file_picker_callback: {
|
||||||
|
name: "File picker callback",
|
||||||
|
description: "Callback function to get called when file picker is clicked",
|
||||||
|
type: 'js',
|
||||||
|
default: et2_no_init
|
||||||
|
},
|
||||||
|
images_upload_handler: {
|
||||||
|
name: "Images upload handler",
|
||||||
|
description: "Callback function for handling image upload",
|
||||||
|
type: 'js',
|
||||||
|
default: et2_no_init
|
||||||
|
},
|
||||||
|
menubar: {
|
||||||
|
name: "Menubar",
|
||||||
|
description: "Display menubar at the top of the editor",
|
||||||
|
type: "boolean",
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
statusbar: {
|
||||||
|
name: "Status bar",
|
||||||
|
description: "Enable/disable status bar on the bottom of editor",
|
||||||
|
type: "boolean",
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
valid_children: {
|
||||||
|
name: "Valid children",
|
||||||
|
description: "Enables to control what child tag is allowed or not allowed of the present tag. For instance: +body[style], makes style tag allowed inside body",
|
||||||
|
type: "string",
|
||||||
|
default: "+body[style]"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of toolbars
|
||||||
|
* @constant
|
||||||
|
*/
|
||||||
|
public static readonly TOOLBAR_LIST : string[] = ['undo', 'redo', 'formatselect', 'fontselect', 'fontsizeselect',
|
||||||
|
'bold', 'italic', 'strikethrough', 'forecolor', 'backcolor', 'link',
|
||||||
|
'alignleft', 'aligncenter', 'alignright', 'alignjustify', 'numlist',
|
||||||
|
'bullist', 'outdent', 'indent', 'ltr', 'rtl', 'removeformat', 'code', 'image', 'searchreplace'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* arranged toolbars as simple mode
|
||||||
|
* @constant
|
||||||
|
*/
|
||||||
|
public static readonly TOOLBAR_SIMPLE : string = "undo redo|formatselect fontselect fontsizeselect | bold italic removeformat forecolor backcolor | "+
|
||||||
|
"alignleft aligncenter alignright alignjustify | numlist "+
|
||||||
|
"bullist outdent indent| link image pastetext";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* arranged toolbars as extended mode
|
||||||
|
* @constant
|
||||||
|
*/
|
||||||
|
public static readonly TOOLBAR_EXTENDED : string = "fontselect fontsizeselect | bold italic strikethrough forecolor backcolor | "+
|
||||||
|
"link | alignleft aligncenter alignright alignjustify | numlist "+
|
||||||
|
"bullist outdent indent | removeformat | image";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* arranged toolbars as advanced mode
|
||||||
|
* @constant
|
||||||
|
*/
|
||||||
|
public static readonly TOOLBAR_ADVANCED : string = "undo redo| formatselect | fontselect fontsizeselect | bold italic strikethrough forecolor backcolor | "+
|
||||||
|
"link | alignleft aligncenter alignright alignjustify | numlist "+
|
||||||
|
"bullist outdent indent ltr rtl | removeformat code| image | searchreplace";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* font size formats
|
||||||
|
* @constant
|
||||||
|
*/
|
||||||
|
public static readonly FONT_SIZE_FORMATS : {pt : string, px : string} = {
|
||||||
|
pt: "8pt 10pt 12pt 14pt 18pt 24pt 36pt 48pt 72pt",
|
||||||
|
px:"8px 10px 12px 14px 18px 24px 36px 48px 72px"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* language code represention for TinyMCE lang code
|
||||||
|
*/
|
||||||
|
public static readonly LANGUAGE_CODE : {} = {
|
||||||
|
bg: "bg_BG", ca: "ca", cs: "cs", da: "da", de: "de", en:"en_CA",
|
||||||
|
el:"el", "es-es":"es", et: "et", eu: "eu" , fa: "fa_IR", fi: "fi",
|
||||||
|
fr: "fr_FR", hi:"", hr:"hr", hu:"hu_HU", id: "id", it: "it", iw: "",
|
||||||
|
ja: "ja", ko: "ko_KR", lo: "", lt: "lt", lv: "lv", nl: "nl", no: "nb_NO",
|
||||||
|
pl: "pl", pt: "pt_PT", "pt-br": "pt_BR", ru: "ru", sk: "sk", sl: "sl_SI",
|
||||||
|
sv: "sv_SE", th: "th_TH", tr: "tr_TR", uk: "en_GB", vi: "vi_VN", zh: "zh_CN",
|
||||||
|
"zh-tw": "zh_TW"
|
||||||
|
};
|
||||||
|
|
||||||
|
editor : any = null;
|
||||||
|
supportedWidgetClasses : any;
|
||||||
|
htmlNode : JQuery = null;
|
||||||
|
mode : string;
|
||||||
|
tinymce : any;
|
||||||
|
tinymce_container : HTMLElement;
|
||||||
|
file_picker_callback : Function;
|
||||||
|
menubar : boolean;
|
||||||
|
protected value : string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
constructor(_parent, _attrs? : WidgetConfig, _child? : object)
|
||||||
|
{
|
||||||
|
// Call the inherited constructor
|
||||||
|
super(_parent, _attrs, ClassWithAttributes.extendAttributes(et2_htmlarea._attributes, _child || {}));
|
||||||
|
this.editor = null; // TinyMce editor instance
|
||||||
|
this.supportedWidgetClasses = []; // Allow no child widgets
|
||||||
|
this.htmlNode = jQuery(document.createElement(this.options.readonly ? "div" : "textarea"))
|
||||||
|
.addClass('et2_textbox_ro');
|
||||||
|
if(this.options.height)
|
||||||
|
{
|
||||||
|
this.htmlNode.css('height', this.options.height);
|
||||||
|
}
|
||||||
|
this.setDOMNode(this.htmlNode[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
doLoadingFinished()
|
||||||
|
{
|
||||||
|
super.doLoadingFinished();
|
||||||
|
this.init_editor();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_editor() {
|
||||||
|
if(this.mode == 'ascii' || this.editor != null || this.options.readonly) return;
|
||||||
|
let imageUpload;
|
||||||
|
let self = this;
|
||||||
|
if (this.options.imageUpload && this.options.imageUpload[0] !== '/' && this.options.imageUpload.substr(0, 4) != 'http')
|
||||||
|
{
|
||||||
|
imageUpload = egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_htmlarea_upload")+
|
||||||
|
'&request_id='+this.getInstanceManager().etemplate_exec_id+'&widget_id='+this.options.imageUpload+'&type=htmlarea';
|
||||||
|
imageUpload = imageUpload.substr(egw.webserverUrl.length+1);
|
||||||
|
}
|
||||||
|
else if (imageUpload)
|
||||||
|
{
|
||||||
|
imageUpload = this.options.imageUpload.substr(egw.webserverUrl.length+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
imageUpload = egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_htmlarea_upload")+
|
||||||
|
'&request_id='+this.getInstanceManager().etemplate_exec_id+'&type=htmlarea';
|
||||||
|
}
|
||||||
|
// default settings for initialization
|
||||||
|
let settings = {
|
||||||
|
target: this.htmlNode[0],
|
||||||
|
body_id: this.dom_id + '_htmlarea',
|
||||||
|
menubar: false,
|
||||||
|
statusbar: this.options.statusbar,
|
||||||
|
branding: false,
|
||||||
|
resize: false,
|
||||||
|
height: this.options.height,
|
||||||
|
width: this.options.width,
|
||||||
|
mobile: {
|
||||||
|
theme: 'silver'
|
||||||
|
},
|
||||||
|
formats: {
|
||||||
|
customparagraph: { block: 'p', styles: {"margin-block-start": "0px", "margin-block-end": "0px"}}
|
||||||
|
},
|
||||||
|
min_height: 100,
|
||||||
|
convert_urls: false,
|
||||||
|
language: et2_htmlarea.LANGUAGE_CODE[<string><unknown>egw.preference('lang', 'common')],
|
||||||
|
language_url: egw.webserverUrl+'/api/js/tinymce/langs/'+et2_htmlarea.LANGUAGE_CODE[<string><unknown>egw.preference('lang', 'common')]+'.js',
|
||||||
|
paste_data_images: true,
|
||||||
|
paste_filter_drop: true,
|
||||||
|
browser_spellcheck: true,
|
||||||
|
contextmenu: false,
|
||||||
|
images_upload_url: imageUpload,
|
||||||
|
file_picker_callback: jQuery.proxy(this._file_picker_callback, this),
|
||||||
|
images_upload_handler: this.options.images_upload_handler,
|
||||||
|
init_instance_callback : jQuery.proxy(this._instanceIsReady, this),
|
||||||
|
auto_focus: false,
|
||||||
|
valid_children : this.options.valid_children,
|
||||||
|
plugins: [
|
||||||
|
"print searchreplace autolink directionality ",
|
||||||
|
"visualblocks visualchars image link media template ",
|
||||||
|
"codesample table charmap hr pagebreak nonbreaking anchor toc ",
|
||||||
|
"insertdatetime advlist lists textcolor wordcount imagetools ",
|
||||||
|
"colorpicker textpattern help paste code searchreplace tabfocus"
|
||||||
|
],
|
||||||
|
toolbar: et2_htmlarea.TOOLBAR_SIMPLE,
|
||||||
|
block_formats: "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;"+
|
||||||
|
"Heading 4=h4;Heading 5=h5;Heading 6=h6;Preformatted=pre;Custom Paragraph=customparagraph",
|
||||||
|
font_formats: "Andale Mono=andale mono,times;Arial=arial,helvetica,"+
|
||||||
|
"sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book "+
|
||||||
|
"antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;"+
|
||||||
|
"Courier New=courier new,courier;Georgia=georgia,palatino;"+
|
||||||
|
"Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;"+
|
||||||
|
"Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,"+
|
||||||
|
"monaco;Times New Roman=times new roman,times;Trebuchet "+
|
||||||
|
"MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;"+
|
||||||
|
"Wingdings=wingdings,zapf dingbats",
|
||||||
|
fontsize_formats: '8pt 10pt 12pt 14pt 18pt 24pt 36pt',
|
||||||
|
setup : function(ed)
|
||||||
|
{
|
||||||
|
ed.on('init', function()
|
||||||
|
{
|
||||||
|
this.getDoc().body.style.fontSize = <string><unknown>egw.preference('rte_font_size', 'common')
|
||||||
|
+ egw.preference('rte_font_unit', 'common');
|
||||||
|
this.getDoc().body.style.fontFamily = egw.preference('rte_font', 'common');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// extend default settings with configured options and preferences
|
||||||
|
jQuery.extend(settings, this._extendedSettings());
|
||||||
|
this.tinymce = tinymce.init(settings);
|
||||||
|
// make sure value gets set in case of widget gets loaded by delay like
|
||||||
|
// inside an inactive tabs
|
||||||
|
this.tinymce.then(function() {
|
||||||
|
self.set_value(self.htmlNode.val());
|
||||||
|
if (self.editor && self.editor.editorContainer)
|
||||||
|
{
|
||||||
|
self.editor.formatter.toggle(<string><unknown>egw.preference('rte_formatblock', 'common'));
|
||||||
|
jQuery(self.editor.editorContainer).height(self.options.height);
|
||||||
|
jQuery(self.editor.iframeElement.contentWindow.document).on('dragenter', function(){
|
||||||
|
if (jQuery('#dragover-tinymce').length < 1) jQuery("<style id='dragover-tinymce'>.dragover:after {height:calc(100% - "+jQuery(this).height()+"px) !important;}</style>").appendTo('head');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set disabled
|
||||||
|
*
|
||||||
|
* @param {type} _value
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
set_disabled(_value)
|
||||||
|
{
|
||||||
|
super.set_disabled(_value);
|
||||||
|
if (_value)
|
||||||
|
{
|
||||||
|
jQuery(this.tinymce_container).css('display', 'none');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jQuery(this.tinymce_container).css('display', 'flex');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_readonly(_value)
|
||||||
|
{
|
||||||
|
if(this.options.readonly === _value) return;
|
||||||
|
let value = this.get_value();
|
||||||
|
this.options.readonly = _value;
|
||||||
|
if(this.options.readonly)
|
||||||
|
{
|
||||||
|
if (this. editor) this.editor.remove();
|
||||||
|
this.htmlNode = jQuery(document.createElement(this.options.readonly ? "div" : "textarea"))
|
||||||
|
.addClass('et2_textbox_ro');
|
||||||
|
if(this.options.height)
|
||||||
|
{
|
||||||
|
this.htmlNode.css('height', this.options.height)
|
||||||
|
}
|
||||||
|
this.editor = null;
|
||||||
|
this.setDOMNode(this.htmlNode[0]);
|
||||||
|
this.set_value(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!this.editor)
|
||||||
|
{
|
||||||
|
this.htmlNode = jQuery(document.createElement("textarea"))
|
||||||
|
.val(value);
|
||||||
|
if(this.options.height || this.options.editable_height)
|
||||||
|
{
|
||||||
|
this.htmlNode.css('height', (this.options.editable_height ? this.options.editable_height : this.options.height));
|
||||||
|
}
|
||||||
|
this.setDOMNode(this.htmlNode[0]);
|
||||||
|
this.init_editor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function runs when the filepicker in image dialog is clicked
|
||||||
|
*
|
||||||
|
* @param {type} _callback
|
||||||
|
* @param {type} _value
|
||||||
|
* @param {type} _meta
|
||||||
|
*/
|
||||||
|
private _file_picker_callback(_callback : Function, _value, _meta)
|
||||||
|
{
|
||||||
|
if (typeof this.file_picker_callback == 'function') return this.file_picker_callback.call(arguments, this);
|
||||||
|
let callback = _callback;
|
||||||
|
|
||||||
|
// Don't rely only on app_name to fetch et2 object as app_name may not
|
||||||
|
// always represent current app of the window, e.g.: mail admin account.
|
||||||
|
// Try to fetch et2 from its template name.
|
||||||
|
let etemplate = jQuery('form').data('etemplate');
|
||||||
|
let et2;
|
||||||
|
if (etemplate && etemplate.name && !app[egw(window).app_name()])
|
||||||
|
{
|
||||||
|
et2 = etemplate2.getByTemplate(etemplate.name)[0]['widgetContainer'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
et2 = app[egw(window).app_name()].et2;
|
||||||
|
}
|
||||||
|
|
||||||
|
let vfsSelect = et2_createWidget('vfs-select', {
|
||||||
|
id:'upload',
|
||||||
|
mode: 'open',
|
||||||
|
name: '',
|
||||||
|
button_caption:"Link",
|
||||||
|
button_label:"Link",
|
||||||
|
dialog_title: "Link file",
|
||||||
|
method: "download"
|
||||||
|
}, et2);
|
||||||
|
jQuery(vfsSelect.getDOMNode()).on('change', function (){
|
||||||
|
callback(vfsSelect.get_value(), {alt:vfsSelect.get_value()});
|
||||||
|
});
|
||||||
|
|
||||||
|
// start the file selector dialog
|
||||||
|
vfsSelect.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback when instance is ready
|
||||||
|
*
|
||||||
|
* @param {type} _editor
|
||||||
|
*/
|
||||||
|
private _instanceIsReady(_editor)
|
||||||
|
{
|
||||||
|
console.log("Editor: " + _editor.id + " is now initialized.");
|
||||||
|
// try to reserve focus state as running command on editor may steal the
|
||||||
|
// current focus.
|
||||||
|
let focusedEl = jQuery(':focus');
|
||||||
|
this.editor = _editor;
|
||||||
|
|
||||||
|
this.editor.on('drop', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!this.disabled) jQuery(this.editor.editorContainer).css('display', 'flex');
|
||||||
|
this.tinymce_container = this.editor.editorContainer;
|
||||||
|
// go back to reserved focused element
|
||||||
|
focusedEl.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes all relevant preferences into account and set settings accordingly
|
||||||
|
*
|
||||||
|
* @returns {object} returns a object including all settings
|
||||||
|
*/
|
||||||
|
private _extendedSettings() : object
|
||||||
|
{
|
||||||
|
let rte_menubar = <string>egw.preference('rte_menubar', 'common');
|
||||||
|
let rte_toolbar = egw.preference('rte_toolbar', 'common');
|
||||||
|
// we need to have rte_toolbar values as an array
|
||||||
|
if (rte_toolbar && typeof rte_toolbar == "object")
|
||||||
|
{
|
||||||
|
rte_toolbar = Object.keys(rte_toolbar).map(function(key){return rte_toolbar[key]});
|
||||||
|
}
|
||||||
|
let settings = {
|
||||||
|
fontsize_formats: et2_htmlarea.FONT_SIZE_FORMATS[<string>egw.preference('rte_font_unit', 'common')],
|
||||||
|
menubar: parseInt(rte_menubar) && this.menubar ? true : typeof rte_menubar != 'undefined' ? false : this.menubar
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (this.mode)
|
||||||
|
{
|
||||||
|
case 'simple':
|
||||||
|
settings['toolbar'] = et2_htmlarea.TOOLBAR_SIMPLE;
|
||||||
|
break;
|
||||||
|
case 'extended':
|
||||||
|
settings['toolbar']= et2_htmlarea.TOOLBAR_EXTENDED;
|
||||||
|
break;
|
||||||
|
case 'advanced':
|
||||||
|
settings['toolbar'] = et2_htmlarea.TOOLBAR_ADVANCED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.mode = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// take rte_toolbar into account if no mode restrictly set from template
|
||||||
|
if (rte_toolbar && !this.mode)
|
||||||
|
{
|
||||||
|
let toolbar_diff = et2_htmlarea.TOOLBAR_LIST.filter(function(i){return !((<string[]>rte_toolbar).indexOf(i) > -1);});
|
||||||
|
settings['toolbar'] = et2_htmlarea.TOOLBAR_ADVANCED;
|
||||||
|
toolbar_diff.forEach(function(a){
|
||||||
|
let r = new RegExp(a);
|
||||||
|
settings['toolbar'] = settings['toolbar'].replace(r, '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy()
|
||||||
|
{
|
||||||
|
if (this.editor)
|
||||||
|
{
|
||||||
|
this.editor.destroy();
|
||||||
|
}
|
||||||
|
this.editor = null;
|
||||||
|
this.tinymce = null;
|
||||||
|
this.tinymce_container = null;
|
||||||
|
this.htmlNode.remove();
|
||||||
|
this.htmlNode = null;
|
||||||
|
super.destroy();
|
||||||
|
}
|
||||||
|
set_value(_value)
|
||||||
|
{
|
||||||
|
this._oldValue = _value;
|
||||||
|
if (this.editor)
|
||||||
|
{
|
||||||
|
this.editor.setContent(_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(this.options.readonly)
|
||||||
|
{
|
||||||
|
this.htmlNode.empty().append(_value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.htmlNode.val(_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.value = _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue()
|
||||||
|
{
|
||||||
|
return this.editor ? this.editor.getContent() : (
|
||||||
|
this.options.readonly ? this.value : this.htmlNode.val()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize htmlNode tag according to window size
|
||||||
|
* @param {type} _height excess height which comes from window resize
|
||||||
|
*/
|
||||||
|
resize(_height)
|
||||||
|
{
|
||||||
|
if (_height && this.options.resize_ratio !== '0')
|
||||||
|
{
|
||||||
|
// apply the ratio
|
||||||
|
_height = (this.options.resize_ratio != '')? _height * this.options.resize_ratio: _height;
|
||||||
|
if (_height != 0)
|
||||||
|
{
|
||||||
|
if (this.editor) // TinyMCE HTML
|
||||||
|
{
|
||||||
|
let h;
|
||||||
|
if (typeof this.editor.iframeElement !='undefined' && this.editor.editorContainer.clientHeight > 0)
|
||||||
|
{
|
||||||
|
h = (this.editor.editorContainer.clientHeight + _height) > 0 ?
|
||||||
|
(this.editor.editorContainer.clientHeight) + _height: this.editor.settings.min_height;
|
||||||
|
}
|
||||||
|
else // fallback height size
|
||||||
|
{
|
||||||
|
h = this.editor.settings.min_height + _height;
|
||||||
|
}
|
||||||
|
jQuery(this.editor.editorContainer).height(h);
|
||||||
|
jQuery(this.editor.iframeElement).height(h - (this.editor.editorContainer.getElementsByClassName('tox-toolbar')[0].clientHeight +
|
||||||
|
this.editor.editorContainer.getElementsByClassName('tox-statusbar')[0].clientHeight));
|
||||||
|
}
|
||||||
|
else // No TinyMCE
|
||||||
|
{
|
||||||
|
this.htmlNode.height(this.htmlNode.height() + _height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
et2_register_widget(et2_htmlarea, ["htmlarea"]);
|
Loading…
Reference in New Issue
Block a user