forked from extern/egroupware
Convert expose to TS and apply it to all exposable widgets
This commit is contained in:
parent
2d5012d208
commit
9a4f2d1e69
@ -428,6 +428,7 @@ function et2_activateLinks(_content) {
|
||||
* Inserts the structure generated by et2_activateLinks into the given DOM-Node
|
||||
*/
|
||||
function et2_insertLinkText(_text, _node, _target) {
|
||||
var _a;
|
||||
if (!_node) {
|
||||
egw.debug("warn", "et2_insertLinkText called without node", _text, _node, _target);
|
||||
return;
|
||||
@ -449,8 +450,7 @@ function et2_insertLinkText(_text, _node, _target) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s.text) // no need to generate a link, if there is no content in it
|
||||
{
|
||||
else if ((_a = s) === null || _a === void 0 ? void 0 : _a.text) {
|
||||
if (!s.href) {
|
||||
egw.debug("warn", "et2_activateLinks gave bad data", s, _node, _target);
|
||||
s.href = "";
|
||||
|
@ -606,7 +606,7 @@ function et2_insertLinkText(_text, _node, _target)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(s.text) // no need to generate a link, if there is no content in it
|
||||
else if(s?.text) // no need to generate a link, if there is no content in it
|
||||
{
|
||||
if(!s.href)
|
||||
{
|
||||
|
@ -49,4 +49,8 @@ var et2_IPrint = "et2_IPrint";
|
||||
function implements_et2_IPrint(obj) {
|
||||
return implements_methods(obj, ["beforePrint", "afterPrint"]);
|
||||
}
|
||||
var et2_IExposable = "et2_IExposable";
|
||||
function implements_et2_IExposable(obj) {
|
||||
return implements_methods(obj, ["getMedia"]);
|
||||
}
|
||||
//# sourceMappingURL=et2_core_interfaces.js.map
|
@ -211,3 +211,20 @@ function implements_et2_IPrint(obj : et2_widget)
|
||||
{
|
||||
return implements_methods(obj, ["beforePrint", "afterPrint"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface all exposed widget must support in order to getMedia for the blueimp Gallery.
|
||||
*/
|
||||
interface et2_IExposable
|
||||
{
|
||||
/**
|
||||
* get media an array of media objects to pass to blueimp Gallery
|
||||
* @param {array} _attrs
|
||||
*/
|
||||
getMedia(_attrs) : void;
|
||||
}
|
||||
var et2_IExposable = "et2_IExposable";
|
||||
function implements_et2_IExposable(obj : et2_widget)
|
||||
{
|
||||
return implements_methods(obj, ["getMedia"]);
|
||||
}
|
4
api/js/etemplate/et2_types.d.ts
vendored
4
api/js/etemplate/et2_types.d.ts
vendored
@ -167,7 +167,6 @@ declare var et2_vfsUid : any;
|
||||
declare var et2_vfsUpload : any;
|
||||
declare var et2_vfsSelect : any;
|
||||
declare var et2_video : any;
|
||||
declare var et2_IExposable : any;
|
||||
declare var tinymce : any;
|
||||
declare var date : any;
|
||||
declare var tinyMCE : any;
|
||||
@ -199,4 +198,5 @@ declare class Resumable {
|
||||
}
|
||||
declare class dhtmlXTreeObject {
|
||||
constructor(options : any);
|
||||
}
|
||||
}
|
||||
declare function expose(widget:any) : any;
|
@ -21,6 +21,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/*egw:uses
|
||||
/vendor/bower-asset/jquery/dist/jquery.js;
|
||||
@ -35,239 +36,241 @@ require("./et2_types");
|
||||
/**
|
||||
* Class which implements the "description" XET-Tag
|
||||
*/
|
||||
var et2_description = /** @class */ (function (_super) {
|
||||
__extends(et2_description, _super);
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function et2_description(_parent, _attrs, _child) {
|
||||
var _this =
|
||||
// Call the inherited constructor
|
||||
_super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_description._attributes, _child || {})) || this;
|
||||
_this.legacyOptions = ["font_style", "href", "activate_links", "for",
|
||||
"extra_link_target", "extra_link_popup", "statustext"];
|
||||
_this._labelContainer = null;
|
||||
// Create the span/label tag which contains the label text
|
||||
_this.span = jQuery(document.createElement(_this.options["for"] ? "label" : "span"))
|
||||
.addClass("et2_label");
|
||||
et2_insertLinkText(_this._parseText(_this.options.value), _this.span[0], _this.options.href ? _this.options.extra_link_target : '_blank');
|
||||
_this.setDOMNode(_this.span[0]);
|
||||
return _this;
|
||||
}
|
||||
et2_description.prototype.transformAttributes = function (_attrs) {
|
||||
_super.prototype.transformAttributes.call(this, _attrs);
|
||||
if (this.id) {
|
||||
var val = this.getArrayMgr("content").getEntry(this.id);
|
||||
if (val) {
|
||||
_attrs["value"] = val;
|
||||
}
|
||||
exports.et2_description = expose((_a = /** @class */ (function (_super) {
|
||||
__extends(et2_description, _super);
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function et2_description(_parent, _attrs, _child) {
|
||||
var _this =
|
||||
// Call the inherited constructor
|
||||
_super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_description._attributes, _child || {})) || this;
|
||||
_this.legacyOptions = ["font_style", "href", "activate_links", "for",
|
||||
"extra_link_target", "extra_link_popup", "statustext"];
|
||||
_this._labelContainer = null;
|
||||
// Create the span/label tag which contains the label text
|
||||
_this.span = jQuery(document.createElement(_this.options["for"] ? "label" : "span"))
|
||||
.addClass("et2_label");
|
||||
et2_insertLinkText(_this._parseText(_this.options.value), _this.span[0], _this.options.href ? _this.options.extra_link_target : '_blank');
|
||||
_this.setDOMNode(_this.span[0]);
|
||||
return _this;
|
||||
}
|
||||
};
|
||||
et2_description.prototype.doLoadingFinished = function () {
|
||||
_super.prototype.doLoadingFinished.call(this);
|
||||
// Get the real id of the 'for' widget
|
||||
var for_widget = null;
|
||||
if (this.options["for"] && ((for_widget = this.getParent().getWidgetById(this.options.for)) ||
|
||||
(for_widget = this.getRoot().getWidgetById(this.options.for))) && for_widget && for_widget.id) {
|
||||
if (for_widget.dom_id) {
|
||||
this.span.attr("for", for_widget.dom_id);
|
||||
et2_description.prototype.transformAttributes = function (_attrs) {
|
||||
_super.prototype.transformAttributes.call(this, _attrs);
|
||||
if (this.id) {
|
||||
var val = this.getArrayMgr("content").getEntry(this.id);
|
||||
if (val) {
|
||||
_attrs["value"] = val;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Target widget is not done yet, need to wait
|
||||
var tab_deferred = jQuery.Deferred();
|
||||
window.setTimeout(function () {
|
||||
};
|
||||
et2_description.prototype.doLoadingFinished = function () {
|
||||
_super.prototype.doLoadingFinished.call(this);
|
||||
// Get the real id of the 'for' widget
|
||||
var for_widget = null;
|
||||
if (this.options["for"] && ((for_widget = this.getParent().getWidgetById(this.options.for)) ||
|
||||
(for_widget = this.getRoot().getWidgetById(this.options.for))) && for_widget && for_widget.id) {
|
||||
if (for_widget.dom_id) {
|
||||
this.span.attr("for", for_widget.dom_id);
|
||||
tab_deferred.resolve();
|
||||
}.bind(this), 0);
|
||||
return tab_deferred.promise();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
et2_description.prototype.set_label = function (_value) {
|
||||
// Abort if ther was no change in the label
|
||||
if (_value == this.label) {
|
||||
return;
|
||||
}
|
||||
if (_value) {
|
||||
// Create the label container if it didn't exist yet
|
||||
if (this._labelContainer == null) {
|
||||
this._labelContainer = jQuery(document.createElement("label"))
|
||||
.addClass("et2_label");
|
||||
this.getSurroundings().insertDOMNode(this._labelContainer[0]);
|
||||
}
|
||||
// Clear the label container.
|
||||
this._labelContainer.empty();
|
||||
// Create the placeholder element and set it
|
||||
var ph = document.createElement("span");
|
||||
this.getSurroundings().setWidgetPlaceholder(ph);
|
||||
// Split the label at the "%s"
|
||||
var parts = et2_csvSplit(_value, 2, "%s");
|
||||
// Update the content of the label container
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
if (parts[i]) {
|
||||
this._labelContainer.append(document.createTextNode(parts[i]));
|
||||
}
|
||||
if (i == 0) {
|
||||
this._labelContainer.append(ph);
|
||||
}
|
||||
}
|
||||
// add class if label is empty
|
||||
this._labelContainer.toggleClass('et2_label_empty', !_value || !parts[0]);
|
||||
}
|
||||
else {
|
||||
// Delete the labelContainer from the surroundings object
|
||||
if (this._labelContainer) {
|
||||
this.getSurroundings().removeDOMNode(this._labelContainer[0]);
|
||||
}
|
||||
this._labelContainer = null;
|
||||
}
|
||||
// Update the surroundings in order to reflect the change in the label
|
||||
this.getSurroundings().update();
|
||||
// Copy the given value
|
||||
this.label = _value;
|
||||
};
|
||||
/**
|
||||
* Function to get media content to feed the expose
|
||||
* @param {type} _value
|
||||
* @returns {Array|Array.getMedia.mediaContent}
|
||||
*/
|
||||
et2_description.prototype.getMedia = function (_value) {
|
||||
var base_url = egw.webserverUrl.match(new RegExp(/^\//, 'ig')) ? egw(window).window.location.origin : '';
|
||||
var mediaContent = [];
|
||||
if (_value) {
|
||||
mediaContent = [{
|
||||
title: this.options.label,
|
||||
href: base_url + _value,
|
||||
type: this.options.type + "/*",
|
||||
thumbnail: base_url + _value
|
||||
}];
|
||||
if (_value.match(/\/webdav.php/, 'ig'))
|
||||
mediaContent[0]["download_href"] = base_url + _value + '?download';
|
||||
}
|
||||
return mediaContent;
|
||||
};
|
||||
et2_description.prototype.set_value = function (_value) {
|
||||
if (!_value)
|
||||
_value = "";
|
||||
if (!this.options.no_lang)
|
||||
_value = this.egw().lang(_value);
|
||||
if (this.options.value && (this.options.value + "").indexOf('%s') != -1) {
|
||||
_value = this.options.value.replace(/%s/g, _value);
|
||||
}
|
||||
et2_insertLinkText(this._parseText(_value), this.span[0], this.options.href ? this.options.extra_link_target : '_blank');
|
||||
// Add hover action button (Edit)
|
||||
if (this.options.hover_action) {
|
||||
this._build_hover_action();
|
||||
}
|
||||
if (this.options.extra_link_popup || this.options.mime) {
|
||||
var href = this.options.href;
|
||||
var mime_data = this.options.mime_data;
|
||||
var self = this;
|
||||
var $span = this.options.mime_data ? jQuery(this.span) : jQuery('a', this.span);
|
||||
$span.click(function (e) {
|
||||
if (self.options.expose_view && typeof self.options.mime != 'undefined' && self.options.mime.match(self.mime_regexp, 'ig')) {
|
||||
// ToDoExpose: self._init_blueimp_gallery(e, href);
|
||||
}
|
||||
else {
|
||||
egw(window).open_link(mime_data || href, self.options.extra_link_target, self.options.extra_link_popup, null, null, self.options.mime);
|
||||
// Target widget is not done yet, need to wait
|
||||
var tab_deferred = jQuery.Deferred();
|
||||
window.setTimeout(function () {
|
||||
this.span.attr("for", for_widget.dom_id);
|
||||
tab_deferred.resolve();
|
||||
}.bind(this), 0);
|
||||
return tab_deferred.promise();
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
et2_description.prototype._parseText = function (_value) {
|
||||
if (this.options.href) {
|
||||
var href = this.options.href;
|
||||
if (href.indexOf('/') == -1 && href.split('.').length >= 3 &&
|
||||
!(href.indexOf('mailto:') != -1 || href.indexOf('://') != -1 || href.indexOf('javascript:') != -1)) {
|
||||
href = "/index.php?menuaction=" + href;
|
||||
}
|
||||
if (href.charAt(0) == '/') // link relative to eGW
|
||||
{
|
||||
href = egw.link(href);
|
||||
return true;
|
||||
};
|
||||
et2_description.prototype.set_label = function (_value) {
|
||||
// Abort if ther was no change in the label
|
||||
if (_value == this.label) {
|
||||
return;
|
||||
}
|
||||
return [{
|
||||
"href": href,
|
||||
"text": _value
|
||||
}];
|
||||
}
|
||||
else if (this.options.activate_links) {
|
||||
return et2_activateLinks(_value);
|
||||
}
|
||||
else {
|
||||
return [_value];
|
||||
}
|
||||
};
|
||||
et2_description.prototype.set_font_style = function (_value) {
|
||||
this.font_style = _value;
|
||||
this.span.toggleClass("et2_bold", _value.indexOf("b") >= 0);
|
||||
this.span.toggleClass("et2_italic", _value.indexOf("i") >= 0);
|
||||
};
|
||||
/**
|
||||
* Code for implementing et2_IDetachedDOM
|
||||
*
|
||||
* @param {array} _attrs
|
||||
*/
|
||||
et2_description.prototype.getDetachedAttributes = function (_attrs) {
|
||||
_attrs.push("value", "class", "href");
|
||||
};
|
||||
et2_description.prototype.getDetachedNodes = function () {
|
||||
return [this.span[0]];
|
||||
};
|
||||
et2_description.prototype.setDetachedAttributes = function (_nodes, _values, _data) {
|
||||
// Update the properties
|
||||
var updateLink = false;
|
||||
if (typeof _values["href"] != "undefined") {
|
||||
updateLink = true;
|
||||
this.options.href = _values["href"];
|
||||
}
|
||||
if (typeof _values["value"] != "undefined" || (updateLink && (_values["value"] || this.options.value))) {
|
||||
this.span = jQuery(_nodes[0]);
|
||||
this.set_value(_values["value"]);
|
||||
}
|
||||
if (typeof _values["class"] != "undefined") {
|
||||
_nodes[0].setAttribute("class", _values["class"]);
|
||||
}
|
||||
// Add hover action button (Edit), _data is nm's row data
|
||||
if (this.options.hover_action) {
|
||||
this._build_hover_action(_data);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Builds button for hover action
|
||||
* @param {object} _data
|
||||
*/
|
||||
et2_description.prototype._build_hover_action = function (_data) {
|
||||
var content = _data && _data.content ? _data.content : undefined;
|
||||
var widget = this;
|
||||
this.span.off().on('mouseenter', jQuery.proxy(function (event) {
|
||||
event.stopImmediatePropagation();
|
||||
var self = this;
|
||||
this.span.tooltip({
|
||||
items: 'span.et2_label',
|
||||
position: { my: "right top", at: "left top", collision: "flipfit" },
|
||||
tooltipClass: "et2_email_popup",
|
||||
content: function () {
|
||||
return jQuery('<a href="#" class= "et2_url_email_contactPlus" title="' + egw.lang(widget.options.hover_action_title) + '"><img src="'
|
||||
+ egw.image("edit") + '"/></a>')
|
||||
.on('click', function () {
|
||||
widget.options.hover_action.call(self, self.widget, content);
|
||||
});
|
||||
},
|
||||
close: function (event, ui) {
|
||||
ui.tooltip.hover(function () {
|
||||
jQuery(this).stop(true).fadeTo(400, 1);
|
||||
}, function () {
|
||||
jQuery(this).fadeOut("400", function () { jQuery(this).remove(); });
|
||||
});
|
||||
if (_value) {
|
||||
// Create the label container if it didn't exist yet
|
||||
if (this._labelContainer == null) {
|
||||
this._labelContainer = jQuery(document.createElement("label"))
|
||||
.addClass("et2_label");
|
||||
this.getSurroundings().insertDOMNode(this._labelContainer[0]);
|
||||
}
|
||||
})
|
||||
.tooltip("open");
|
||||
}, { widget: this, span: this.span }));
|
||||
};
|
||||
et2_description._attributes = {
|
||||
// Clear the label container.
|
||||
this._labelContainer.empty();
|
||||
// Create the placeholder element and set it
|
||||
var ph = document.createElement("span");
|
||||
this.getSurroundings().setWidgetPlaceholder(ph);
|
||||
// Split the label at the "%s"
|
||||
var parts = et2_csvSplit(_value, 2, "%s");
|
||||
// Update the content of the label container
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
if (parts[i]) {
|
||||
this._labelContainer.append(document.createTextNode(parts[i]));
|
||||
}
|
||||
if (i == 0) {
|
||||
this._labelContainer.append(ph);
|
||||
}
|
||||
}
|
||||
// add class if label is empty
|
||||
this._labelContainer.toggleClass('et2_label_empty', !_value || !parts[0]);
|
||||
}
|
||||
else {
|
||||
// Delete the labelContainer from the surroundings object
|
||||
if (this._labelContainer) {
|
||||
this.getSurroundings().removeDOMNode(this._labelContainer[0]);
|
||||
}
|
||||
this._labelContainer = null;
|
||||
}
|
||||
// Update the surroundings in order to reflect the change in the label
|
||||
this.getSurroundings().update();
|
||||
// Copy the given value
|
||||
this.label = _value;
|
||||
};
|
||||
/**
|
||||
* Function to get media content to feed the expose
|
||||
* @param {type} _value
|
||||
* @returns {Array|Array.getMedia.mediaContent}
|
||||
*/
|
||||
et2_description.prototype.getMedia = function (_value) {
|
||||
var base_url = egw.webserverUrl.match(new RegExp(/^\//, 'ig')) ? egw(window).window.location.origin : '';
|
||||
var mediaContent = [];
|
||||
if (_value) {
|
||||
mediaContent = [{
|
||||
title: this.options.label,
|
||||
href: base_url + _value,
|
||||
type: this.options.type + "/*",
|
||||
thumbnail: base_url + _value
|
||||
}];
|
||||
if (_value.match(/\/webdav.php/, 'ig'))
|
||||
mediaContent[0]["download_href"] = base_url + _value + '?download';
|
||||
}
|
||||
return mediaContent;
|
||||
};
|
||||
et2_description.prototype.set_value = function (_value) {
|
||||
if (!_value)
|
||||
_value = "";
|
||||
if (!this.options.no_lang)
|
||||
_value = this.egw().lang(_value);
|
||||
if (this.options.value && (this.options.value + "").indexOf('%s') != -1) {
|
||||
_value = this.options.value.replace(/%s/g, _value);
|
||||
}
|
||||
et2_insertLinkText(this._parseText(_value), this.span[0], this.options.href ? this.options.extra_link_target : '_blank');
|
||||
// Add hover action button (Edit)
|
||||
if (this.options.hover_action) {
|
||||
this._build_hover_action();
|
||||
}
|
||||
if (this.options.extra_link_popup || this.options.mime) {
|
||||
var href = this.options.href;
|
||||
var mime_data = this.options.mime_data;
|
||||
var self = this;
|
||||
var $span = this.options.mime_data ? jQuery(this.span) : jQuery('a', this.span);
|
||||
$span.click(function (e) {
|
||||
if (self.options.expose_view && typeof self.options.mime != 'undefined' && self.options.mime.match(self.mime_regexp, 'ig')) {
|
||||
self._init_blueimp_gallery(e, href);
|
||||
}
|
||||
else {
|
||||
egw(window).open_link(mime_data || href, self.options.extra_link_target, self.options.extra_link_popup, null, null, self.options.mime);
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
et2_description.prototype._parseText = function (_value) {
|
||||
if (this.options.href) {
|
||||
var href = this.options.href;
|
||||
if (href.indexOf('/') == -1 && href.split('.').length >= 3 &&
|
||||
!(href.indexOf('mailto:') != -1 || href.indexOf('://') != -1 || href.indexOf('javascript:') != -1)) {
|
||||
href = "/index.php?menuaction=" + href;
|
||||
}
|
||||
if (href.charAt(0) == '/') // link relative to eGW
|
||||
{
|
||||
href = egw.link(href);
|
||||
}
|
||||
return [{
|
||||
"href": href,
|
||||
"text": _value
|
||||
}];
|
||||
}
|
||||
else if (this.options.activate_links) {
|
||||
return et2_activateLinks(_value);
|
||||
}
|
||||
else {
|
||||
return [_value];
|
||||
}
|
||||
};
|
||||
et2_description.prototype.set_font_style = function (_value) {
|
||||
this.font_style = _value;
|
||||
this.span.toggleClass("et2_bold", _value.indexOf("b") >= 0);
|
||||
this.span.toggleClass("et2_italic", _value.indexOf("i") >= 0);
|
||||
};
|
||||
/**
|
||||
* Code for implementing et2_IDetachedDOM
|
||||
*
|
||||
* @param {array} _attrs
|
||||
*/
|
||||
et2_description.prototype.getDetachedAttributes = function (_attrs) {
|
||||
_attrs.push("value", "class", "href");
|
||||
};
|
||||
et2_description.prototype.getDetachedNodes = function () {
|
||||
return [this.span[0]];
|
||||
};
|
||||
et2_description.prototype.setDetachedAttributes = function (_nodes, _values, _data) {
|
||||
// Update the properties
|
||||
var updateLink = false;
|
||||
if (typeof _values["href"] != "undefined") {
|
||||
updateLink = true;
|
||||
this.options.href = _values["href"];
|
||||
}
|
||||
if (typeof _values["value"] != "undefined" || (updateLink && (_values["value"] || this.options.value))) {
|
||||
this.span = jQuery(_nodes[0]);
|
||||
this.set_value(_values["value"]);
|
||||
}
|
||||
if (typeof _values["class"] != "undefined") {
|
||||
_nodes[0].setAttribute("class", _values["class"]);
|
||||
}
|
||||
// Add hover action button (Edit), _data is nm's row data
|
||||
if (this.options.hover_action) {
|
||||
this._build_hover_action(_data);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Builds button for hover action
|
||||
* @param {object} _data
|
||||
*/
|
||||
et2_description.prototype._build_hover_action = function (_data) {
|
||||
var content = _data && _data.content ? _data.content : undefined;
|
||||
var widget = this;
|
||||
this.span.off().on('mouseenter', jQuery.proxy(function (event) {
|
||||
event.stopImmediatePropagation();
|
||||
var self = this;
|
||||
this.span.tooltip({
|
||||
items: 'span.et2_label',
|
||||
position: { my: "right top", at: "left top", collision: "flipfit" },
|
||||
tooltipClass: "et2_email_popup",
|
||||
content: function () {
|
||||
return jQuery('<a href="#" class= "et2_url_email_contactPlus" title="' + egw.lang(widget.options.hover_action_title) + '"><img src="'
|
||||
+ egw.image("edit") + '"/></a>')
|
||||
.on('click', function () {
|
||||
widget.options.hover_action.call(self, self.widget, content);
|
||||
});
|
||||
},
|
||||
close: function (event, ui) {
|
||||
ui.tooltip.hover(function () {
|
||||
jQuery(this).stop(true).fadeTo(400, 1);
|
||||
}, function () {
|
||||
jQuery(this).fadeOut("400", function () { jQuery(this).remove(); });
|
||||
});
|
||||
}
|
||||
})
|
||||
.tooltip("open");
|
||||
}, { widget: this, span: this.span }));
|
||||
};
|
||||
return et2_description;
|
||||
}(et2_core_baseWidget_1.et2_baseWidget)),
|
||||
_a._attributes = {
|
||||
"label": {
|
||||
"name": "Label",
|
||||
"default": "",
|
||||
@ -349,9 +352,7 @@ var et2_description = /** @class */ (function (_super) {
|
||||
"default": "Edit",
|
||||
"description": "Text to show as tooltip of defined action"
|
||||
}
|
||||
};
|
||||
return et2_description;
|
||||
}(et2_core_baseWidget_1.et2_baseWidget));
|
||||
exports.et2_description = et2_description;
|
||||
et2_core_widget_1.et2_register_widget(et2_description, ["description", "label"]);
|
||||
},
|
||||
_a));
|
||||
et2_core_widget_1.et2_register_widget(exports.et2_description, ["description", "label"]);
|
||||
//# sourceMappingURL=et2_widget_description.js.map
|
@ -23,7 +23,7 @@ import './et2_types';
|
||||
/**
|
||||
* Class which implements the "description" XET-Tag
|
||||
*/
|
||||
export class et2_description extends et2_baseWidget implements et2_IDetachedDOM
|
||||
export const et2_description = expose(class et2_description extends et2_baseWidget implements et2_IDetachedDOM, et2_IExposable
|
||||
{
|
||||
static readonly _attributes : any = {
|
||||
"label": {
|
||||
@ -292,7 +292,7 @@ export class et2_description extends et2_baseWidget implements et2_IDetachedDOM
|
||||
$span.click(function(e) {
|
||||
if (self.options.expose_view && typeof self.options.mime !='undefined' && self.options.mime.match(self.mime_regexp,'ig'))
|
||||
{
|
||||
// ToDoExpose: self._init_blueimp_gallery(e, href);
|
||||
self._init_blueimp_gallery(e, href);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -423,6 +423,5 @@ export class et2_description extends et2_baseWidget implements et2_IDetachedDOM
|
||||
.tooltip("open");
|
||||
}, {widget: this, span: this.span}));
|
||||
}
|
||||
}
|
||||
});
|
||||
et2_register_widget(et2_description, ["description", "label"]);
|
||||
|
||||
|
@ -22,6 +22,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/*egw:uses
|
||||
/vendor/bower-asset/jquery/dist/jquery.js;
|
||||
@ -528,7 +529,7 @@ var et2_link_entry = /** @class */ (function (_super) {
|
||||
buttonItem.css('background-image', 'url(' + url + ')');
|
||||
},
|
||||
_renderItem: function (ul, item) {
|
||||
var li = jQuery("<li>", { "class": "et2_link_entry_app_option" }), wrapper = jQuery("<div>", { text: item.label });
|
||||
var li = jQuery("<li>", { class: "et2_link_entry_app_option" }), wrapper = jQuery("<div>", { text: item.label });
|
||||
if (item.disabled) {
|
||||
li.addClass("ui-state-disabled");
|
||||
}
|
||||
@ -1229,188 +1230,190 @@ et2_core_widget_1.et2_register_widget(et2_link, ["link", "link-entry_ro"]);
|
||||
*
|
||||
* TODO: This one used to have expose
|
||||
*/
|
||||
var et2_link_string = /** @class */ (function (_super) {
|
||||
__extends(et2_link_string, _super);
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @memberOf et2_link_string
|
||||
*/
|
||||
function et2_link_string(_parent, _attrs, _child) {
|
||||
var _this = _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_link_string._attributes, _child || {})) || this;
|
||||
_this.list = jQuery(document.createElement("ul"))
|
||||
.addClass("et2_link_string");
|
||||
if (_this.options['class'])
|
||||
_this.list.addClass(_this.options['class']);
|
||||
_this.setDOMNode(_this.list[0]);
|
||||
return _this;
|
||||
}
|
||||
et2_link_string.prototype.destroy = function () {
|
||||
_super.prototype.destroy.apply(this, arguments);
|
||||
if (this.node != null) {
|
||||
jQuery(this.node).children().unbind();
|
||||
exports.et2_link_string = expose((_a = /** @class */ (function (_super) {
|
||||
__extends(et2_link_string, _super);
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @memberOf et2_link_string
|
||||
*/
|
||||
function et2_link_string(_parent, _attrs, _child) {
|
||||
var _this = _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_link_string._attributes, _child || {})) || this;
|
||||
_this.list = jQuery(document.createElement("ul"))
|
||||
.addClass("et2_link_string");
|
||||
if (_this.options['class'])
|
||||
_this.list.addClass(_this.options['class']);
|
||||
_this.setDOMNode(_this.list[0]);
|
||||
return _this;
|
||||
}
|
||||
};
|
||||
et2_link_string.prototype.set_value = function (_value) {
|
||||
// Get data
|
||||
if (!_value || _value == null || !this.list) {
|
||||
// List can be missing if the AJAX call returns after the form is destroyed
|
||||
if (this.list) {
|
||||
this.list.empty();
|
||||
et2_link_string.prototype.destroy = function () {
|
||||
_super.prototype.destroy.apply(this, arguments);
|
||||
if (this.node != null) {
|
||||
jQuery(this.node).children().unbind();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (typeof _value == "string" && _value.indexOf(',') > 0) {
|
||||
_value = _value.split(',');
|
||||
}
|
||||
if (!_value.to_app && typeof _value == "object" && this.options.application) {
|
||||
_value.to_app = this.options.application;
|
||||
}
|
||||
if (typeof _value == 'object' && _value.to_app && _value.to_id) {
|
||||
this.value = _value;
|
||||
this._get_links();
|
||||
return;
|
||||
}
|
||||
this.list.empty();
|
||||
if (typeof _value == 'object' && _value.length > 0) {
|
||||
// Have full info
|
||||
// Don't store new value, just update display
|
||||
// Make new links
|
||||
for (var i = 0; i < _value.length; i++) {
|
||||
if (!this.options.only_app || this.options.only_app && _value[i].app == this.options.only_app) {
|
||||
this._add_link(_value[i].id ? _value[i] : { id: _value[i], app: _value.to_app });
|
||||
};
|
||||
et2_link_string.prototype.set_value = function (_value) {
|
||||
// Get data
|
||||
if (!_value || _value == null || !this.list) {
|
||||
// List can be missing if the AJAX call returns after the form is destroyed
|
||||
if (this.list) {
|
||||
this.list.empty();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (typeof _value == "string" && _value.indexOf(',') > 0) {
|
||||
_value = _value.split(',');
|
||||
}
|
||||
if (!_value.to_app && typeof _value == "object" && this.options.application) {
|
||||
_value.to_app = this.options.application;
|
||||
}
|
||||
if (typeof _value == 'object' && _value.to_app && _value.to_id) {
|
||||
this.value = _value;
|
||||
this._get_links();
|
||||
return;
|
||||
}
|
||||
this.list.empty();
|
||||
if (typeof _value == 'object' && _value.length > 0) {
|
||||
// Have full info
|
||||
// Don't store new value, just update display
|
||||
// Make new links
|
||||
for (var i = 0; i < _value.length; i++) {
|
||||
if (!this.options.only_app || this.options.only_app && _value[i].app == this.options.only_app) {
|
||||
this._add_link(_value[i].id ? _value[i] : { id: _value[i], app: _value.to_app });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this.options.application) {
|
||||
this._add_link({ id: _value, app: this.options.application });
|
||||
}
|
||||
};
|
||||
et2_link_string.prototype._get_links = function () {
|
||||
var _value = this.value;
|
||||
// Just IDs - get from server
|
||||
if (this.options.only_app) {
|
||||
_value.only_app = this.options.only_app;
|
||||
}
|
||||
this.egw().jsonq('EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link_list', [_value], this.set_value, this);
|
||||
return;
|
||||
};
|
||||
/**
|
||||
* Function to get media content to feed the expose
|
||||
* @param {type} _value
|
||||
* @returns {Array|Array.getMedia.mediaContent}
|
||||
*/
|
||||
et2_link_string.prototype.getMedia = function (_value) {
|
||||
var base_url = egw.webserverUrl.match(/^\//, 'ig') ? egw(window).window.location.origin + egw.webserverUrl : egw.webserverUrl;
|
||||
var mediaContent = [];
|
||||
if (_value && typeof _value.type != 'undefined' && _value.type.match(/video\//, 'ig')) {
|
||||
mediaContent = [{
|
||||
title: _value.id,
|
||||
type: _value.type,
|
||||
poster: '',
|
||||
href: base_url + egw().mime_open(_value),
|
||||
download_href: base_url + egw().mime_open(_value) + '?download'
|
||||
}];
|
||||
}
|
||||
else if (_value) {
|
||||
mediaContent = [{
|
||||
title: _value.id,
|
||||
href: base_url + egw().mime_open(_value).url,
|
||||
download_href: base_url + egw().mime_open(_value).url + '?download',
|
||||
type: _value.type
|
||||
}];
|
||||
}
|
||||
if (mediaContent[0].href && mediaContent[0].href.match(/\/webdav.php/, 'ig'))
|
||||
mediaContent[0]["download_href"] = mediaContent[0].href + '?download';
|
||||
return mediaContent;
|
||||
};
|
||||
et2_link_string.prototype._add_link = function (_link_data) {
|
||||
var self = this;
|
||||
var link = jQuery(document.createElement("li"))
|
||||
.appendTo(this.list)
|
||||
.addClass("et2_link loading")
|
||||
.click(function (e) {
|
||||
var fe = egw_get_file_editor_prefered_mimes(_link_data.type);
|
||||
if (self.options.expose_view && typeof _link_data.type != 'undefined'
|
||||
&& _link_data.type.match(self.mime_regexp, 'ig')) {
|
||||
self._init_blueimp_gallery(e, _link_data);
|
||||
else if (this.options.application) {
|
||||
this._add_link({ id: _value, app: this.options.application });
|
||||
}
|
||||
else if (typeof _link_data.type != 'undefined' && fe && fe.mime && fe.mime[_link_data.type]) {
|
||||
egw.open_link(egw.link('/index.php', {
|
||||
menuaction: fe.edit.menuaction,
|
||||
path: egw().mime_open(_link_data).url.replace('/webdav.php', '')
|
||||
}), '', fe.edit_popup);
|
||||
};
|
||||
et2_link_string.prototype._get_links = function () {
|
||||
var _value = this.value;
|
||||
// Just IDs - get from server
|
||||
if (this.options.only_app) {
|
||||
_value.only_app = this.options.only_app;
|
||||
}
|
||||
else {
|
||||
self.egw().open(_link_data, "", "view", null, _link_data.app, _link_data.app);
|
||||
this.egw().jsonq('EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link_list', [_value], this.set_value, this);
|
||||
return;
|
||||
};
|
||||
/**
|
||||
* Function to get media content to feed the expose
|
||||
* @param {type} _value
|
||||
* @returns {Array|Array.getMedia.mediaContent}
|
||||
*/
|
||||
et2_link_string.prototype.getMedia = function (_value) {
|
||||
var base_url = egw.webserverUrl.match(/^\//, 'ig') ? egw(window).window.location.origin + egw.webserverUrl : egw.webserverUrl;
|
||||
var mediaContent = [];
|
||||
if (_value && typeof _value.type != 'undefined' && _value.type.match(/video\//, 'ig')) {
|
||||
mediaContent = [{
|
||||
title: _value.id,
|
||||
type: _value.type,
|
||||
poster: '',
|
||||
href: base_url + egw().mime_open(_value),
|
||||
download_href: base_url + egw().mime_open(_value) + '?download'
|
||||
}];
|
||||
}
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
if (_link_data.title)
|
||||
link.text(_link_data.title);
|
||||
// Now that link is created, get title from server & update
|
||||
if (!_link_data.title) {
|
||||
this.egw().link_title(_link_data.app, _link_data.id, function (title) {
|
||||
if (title)
|
||||
this.removeClass("loading").text(title);
|
||||
else
|
||||
this.remove(); // no rights or not found
|
||||
}, link);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Creates a list of attributes which can be set when working in the
|
||||
* "detached" mode. The result is stored in the _attrs array which is provided
|
||||
* by the calling code.
|
||||
*
|
||||
* @param {Array} _attrs an array of attributes
|
||||
*/
|
||||
et2_link_string.prototype.getDetachedAttributes = function (_attrs) {
|
||||
// Create the label container if it didn't exist yet
|
||||
if (this._labelContainer == null) {
|
||||
this._labelContainer = jQuery(document.createElement("label"))
|
||||
.addClass("et2_label");
|
||||
this.getSurroundings().insertDOMNode(this._labelContainer[0]);
|
||||
this.getSurroundings().update();
|
||||
}
|
||||
_attrs.push("value", "label");
|
||||
};
|
||||
/**
|
||||
* Returns an array of DOM nodes. The (relatively) same DOM-Nodes have to be
|
||||
* passed to the "setDetachedAttributes" function in the same order.
|
||||
*/
|
||||
et2_link_string.prototype.getDetachedNodes = function () {
|
||||
// Create the label container if it didn't exist yet
|
||||
if (this._labelContainer == null) {
|
||||
this._labelContainer = jQuery(document.createElement("label"))
|
||||
.addClass("et2_label");
|
||||
this.getSurroundings().insertDOMNode(this._labelContainer[0]);
|
||||
}
|
||||
return [this.list[0], this._labelContainer[0]];
|
||||
};
|
||||
/**
|
||||
* Sets the given associative attribute->value array and applies the
|
||||
* attributes to the given DOM-Node.
|
||||
*
|
||||
* @param _nodes is an array of nodes which have to be in the same order as
|
||||
* the nodes returned by "getDetachedNodes"
|
||||
* @param _values is an associative array which contains a subset of attributes
|
||||
* returned by the "getDetachedAttributes" function and sets them to the
|
||||
* given values.
|
||||
*/
|
||||
et2_link_string.prototype.setDetachedAttributes = function (_nodes, _values) {
|
||||
this.list = jQuery(_nodes[0]);
|
||||
this.set_value(_values["value"]);
|
||||
// Special detached, to prevent DOM node modification of the normal method
|
||||
this._labelContainer = _nodes.length > 1 ? jQuery(_nodes[1]) : null;
|
||||
if (_values['label']) {
|
||||
this.set_label(_values['label']);
|
||||
}
|
||||
else if (this._labelContainer) {
|
||||
this._labelContainer.contents().not(this.list).remove();
|
||||
}
|
||||
};
|
||||
et2_link_string._attributes = {
|
||||
else if (_value) {
|
||||
mediaContent = [{
|
||||
title: _value.id,
|
||||
href: base_url + egw().mime_open(_value).url,
|
||||
download_href: base_url + egw().mime_open(_value).url + '?download',
|
||||
type: _value.type
|
||||
}];
|
||||
}
|
||||
if (mediaContent[0].href && mediaContent[0].href.match(/\/webdav.php/, 'ig'))
|
||||
mediaContent[0]["download_href"] = mediaContent[0].href + '?download';
|
||||
return mediaContent;
|
||||
};
|
||||
et2_link_string.prototype._add_link = function (_link_data) {
|
||||
var self = this;
|
||||
var link = jQuery(document.createElement("li"))
|
||||
.appendTo(this.list)
|
||||
.addClass("et2_link loading")
|
||||
.click(function (e) {
|
||||
var fe = egw_get_file_editor_prefered_mimes(_link_data.type);
|
||||
if (self.options.expose_view && typeof _link_data.type != 'undefined'
|
||||
&& _link_data.type.match(self.mime_regexp, 'ig')) {
|
||||
self._init_blueimp_gallery(e, _link_data);
|
||||
}
|
||||
else if (typeof _link_data.type != 'undefined' && fe && fe.mime && fe.mime[_link_data.type]) {
|
||||
egw.open_link(egw.link('/index.php', {
|
||||
menuaction: fe.edit.menuaction,
|
||||
path: egw().mime_open(_link_data).url.replace('/webdav.php', '')
|
||||
}), '', fe.edit_popup);
|
||||
}
|
||||
else {
|
||||
self.egw().open(_link_data, "", "view", null, _link_data.app, _link_data.app);
|
||||
}
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
if (_link_data.title)
|
||||
link.text(_link_data.title);
|
||||
// Now that link is created, get title from server & update
|
||||
if (!_link_data.title) {
|
||||
this.egw().link_title(_link_data.app, _link_data.id, function (title) {
|
||||
if (title)
|
||||
this.removeClass("loading").text(title);
|
||||
else
|
||||
this.remove(); // no rights or not found
|
||||
}, link);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Creates a list of attributes which can be set when working in the
|
||||
* "detached" mode. The result is stored in the _attrs array which is provided
|
||||
* by the calling code.
|
||||
*
|
||||
* @param {Array} _attrs an array of attributes
|
||||
*/
|
||||
et2_link_string.prototype.getDetachedAttributes = function (_attrs) {
|
||||
// Create the label container if it didn't exist yet
|
||||
if (this._labelContainer == null) {
|
||||
this._labelContainer = jQuery(document.createElement("label"))
|
||||
.addClass("et2_label");
|
||||
this.getSurroundings().insertDOMNode(this._labelContainer[0]);
|
||||
this.getSurroundings().update();
|
||||
}
|
||||
_attrs.push("value", "label");
|
||||
};
|
||||
/**
|
||||
* Returns an array of DOM nodes. The (relatively) same DOM-Nodes have to be
|
||||
* passed to the "setDetachedAttributes" function in the same order.
|
||||
*/
|
||||
et2_link_string.prototype.getDetachedNodes = function () {
|
||||
// Create the label container if it didn't exist yet
|
||||
if (this._labelContainer == null) {
|
||||
this._labelContainer = jQuery(document.createElement("label"))
|
||||
.addClass("et2_label");
|
||||
this.getSurroundings().insertDOMNode(this._labelContainer[0]);
|
||||
}
|
||||
return [this.list[0], this._labelContainer[0]];
|
||||
};
|
||||
/**
|
||||
* Sets the given associative attribute->value array and applies the
|
||||
* attributes to the given DOM-Node.
|
||||
*
|
||||
* @param _nodes is an array of nodes which have to be in the same order as
|
||||
* the nodes returned by "getDetachedNodes"
|
||||
* @param _values is an associative array which contains a subset of attributes
|
||||
* returned by the "getDetachedAttributes" function and sets them to the
|
||||
* given values.
|
||||
*/
|
||||
et2_link_string.prototype.setDetachedAttributes = function (_nodes, _values) {
|
||||
this.list = jQuery(_nodes[0]);
|
||||
this.set_value(_values["value"]);
|
||||
// Special detached, to prevent DOM node modification of the normal method
|
||||
this._labelContainer = _nodes.length > 1 ? jQuery(_nodes[1]) : null;
|
||||
if (_values['label']) {
|
||||
this.set_label(_values['label']);
|
||||
}
|
||||
else if (this._labelContainer) {
|
||||
this._labelContainer.contents().not(this.list).remove();
|
||||
}
|
||||
};
|
||||
return et2_link_string;
|
||||
}(et2_core_valueWidget_1.et2_valueWidget)),
|
||||
_a._attributes = {
|
||||
"application": {
|
||||
"name": "Application",
|
||||
"type": "string",
|
||||
@ -1436,14 +1439,12 @@ var et2_link_string = /** @class */ (function (_super) {
|
||||
"expose_view": {
|
||||
name: "Expose view",
|
||||
type: "boolean",
|
||||
"default": true,
|
||||
default: true,
|
||||
description: "Clicking on description with href value would popup an expose view, and will show content referenced by href."
|
||||
}
|
||||
};
|
||||
return et2_link_string;
|
||||
}(et2_core_valueWidget_1.et2_valueWidget));
|
||||
exports.et2_link_string = et2_link_string;
|
||||
et2_core_widget_1.et2_register_widget(et2_link_string, ["link-string"]);
|
||||
},
|
||||
_a));
|
||||
et2_core_widget_1.et2_register_widget(exports.et2_link_string, ["link-string"]);
|
||||
/**
|
||||
* UI widget for one or more links in a list (table)
|
||||
*/
|
||||
@ -1882,7 +1883,7 @@ var et2_link_list = /** @class */ (function (_super) {
|
||||
}
|
||||
};
|
||||
return et2_link_list;
|
||||
}(et2_link_string));
|
||||
}(exports.et2_link_string));
|
||||
exports.et2_link_list = et2_link_list;
|
||||
et2_core_widget_1.et2_register_widget(et2_link_list, ["link-list"]);
|
||||
/**
|
||||
@ -1948,3 +1949,4 @@ var et2_link_add = /** @class */ (function (_super) {
|
||||
}(et2_core_inputWidget_1.et2_inputWidget));
|
||||
exports.et2_link_add = et2_link_add;
|
||||
et2_core_widget_1.et2_register_widget(et2_link_add, ["link-add"]);
|
||||
//# sourceMappingURL=et2_widget_link.js.map
|
@ -1496,7 +1496,7 @@ et2_register_widget(et2_link, ["link", "link-entry_ro"]);
|
||||
*
|
||||
* TODO: This one used to have expose
|
||||
*/
|
||||
export class et2_link_string extends et2_valueWidget implements et2_IDetachedDOM
|
||||
export const et2_link_string = expose(class et2_link_string extends et2_valueWidget implements et2_IDetachedDOM, et2_IExposable
|
||||
{
|
||||
static readonly _attributes : any = {
|
||||
"application": {
|
||||
@ -1751,7 +1751,7 @@ export class et2_link_string extends et2_valueWidget implements et2_IDetachedDOM
|
||||
this._labelContainer.contents().not(this.list).remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
et2_register_widget(et2_link_string, ["link-string"]);
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/*egw:uses
|
||||
/vendor/bower-asset/jquery/dist/jquery.js;
|
||||
@ -429,157 +430,158 @@ et2_core_widget_1.et2_register_widget(et2_vfsName_ro, ["vfs-name_ro"]);
|
||||
* </span>
|
||||
*
|
||||
* span.overlayContainer is optional and only generated for symlinks
|
||||
* @todo implement mixin Expose class
|
||||
* @augments et2_valueWidget
|
||||
*/
|
||||
var et2_vfsMime = /** @class */ (function (_super) {
|
||||
__extends(et2_vfsMime, _super);
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @memberOf et2_vfsMime
|
||||
*/
|
||||
function et2_vfsMime(_parent, _attrs, _child) {
|
||||
var _this =
|
||||
// Call the inherited constructor
|
||||
_super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_vfsMime._attributes, _child || {})) || this;
|
||||
_this.legacyOptions = ["size"];
|
||||
_this.iconOverlayContainer = null;
|
||||
_this.image = null;
|
||||
_this.iconOverlayContainer = jQuery(document.createElement('span')).addClass('iconOverlayContainer');
|
||||
_this.image = jQuery(document.createElement("img"));
|
||||
_this.image.addClass("et2_vfs vfsMimeIcon");
|
||||
_this.iconOverlayContainer.append(_this.image);
|
||||
_this.setDOMNode(_this.iconOverlayContainer[0]);
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* Handler for expose slide action, from expose
|
||||
* Returns data needed for the given index, or false to let expose handle it
|
||||
*
|
||||
* @param {Gallery} gallery
|
||||
* @param {integer} index
|
||||
* @param {DOMNode} slide
|
||||
* @return {Array} array of objects consist of media contnet
|
||||
*/
|
||||
et2_vfsMime.prototype.expose_onslide = function (gallery, index, slide) {
|
||||
var content = false;
|
||||
if (this.options.expose_callback && typeof this.options.expose_callback == 'function') {
|
||||
//Call the callback to load more items
|
||||
content = this.options.expose_callback.call(this, [gallery, index]);
|
||||
if (content)
|
||||
this.add(content);
|
||||
exports.et2_vfsMime = expose((_a = /** @class */ (function (_super) {
|
||||
__extends(et2_vfsMime, _super);
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @memberOf et2_vfsMime
|
||||
*/
|
||||
function et2_vfsMime(_parent, _attrs, _child) {
|
||||
var _this =
|
||||
// Call the inherited constructor
|
||||
_super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_vfsMime._attributes, _child || {})) || this;
|
||||
_this.legacyOptions = ["size"];
|
||||
_this.iconOverlayContainer = null;
|
||||
_this.image = null;
|
||||
_this.iconOverlayContainer = jQuery(document.createElement('span')).addClass('iconOverlayContainer');
|
||||
_this.image = jQuery(document.createElement("img"));
|
||||
_this.image.addClass("et2_vfs vfsMimeIcon");
|
||||
_this.iconOverlayContainer.append(_this.image);
|
||||
_this.setDOMNode(_this.iconOverlayContainer[0]);
|
||||
return _this;
|
||||
}
|
||||
return content;
|
||||
};
|
||||
/**
|
||||
* Function to get media content to feed the expose
|
||||
*
|
||||
* @param {type} _value
|
||||
* @returns {Array} return an array of object consists of media content
|
||||
*/
|
||||
et2_vfsMime.prototype.getMedia = function (_value) {
|
||||
var base_url = egw.webserverUrl.match(/^\/ig/) ? egw(window).window.location.origin + egw.webserverUrl : egw.webserverUrl;
|
||||
var mediaContent = [{
|
||||
title: _value.name,
|
||||
type: _value.mime,
|
||||
href: _value.download_url
|
||||
}];
|
||||
// check if download_url is not already an url (some stream-wrappers allow to specify that!)
|
||||
if (_value.download_url && (_value.download_url[0] == '/' || _value.download_url.substr(0, 4) != 'http')) {
|
||||
mediaContent[0].href = base_url + _value.download_url;
|
||||
if (mediaContent[0].href && mediaContent[0].href.match(/\/webdav.php/, 'ig')) {
|
||||
mediaContent[0]["download_href"] = mediaContent[0].href + '?download';
|
||||
/**
|
||||
* Handler for expose slide action, from expose
|
||||
* Returns data needed for the given index, or false to let expose handle it
|
||||
*
|
||||
* @param {Gallery} gallery
|
||||
* @param {integer} index
|
||||
* @param {DOMNode} slide
|
||||
* @return {Array} array of objects consist of media contnet
|
||||
*/
|
||||
et2_vfsMime.prototype.expose_onslide = function (gallery, index, slide) {
|
||||
var content = false;
|
||||
if (this.options.expose_callback && typeof this.options.expose_callback == 'function') {
|
||||
//Call the callback to load more items
|
||||
content = this.options.expose_callback.call(this, [gallery, index]);
|
||||
if (content)
|
||||
this.add(content);
|
||||
}
|
||||
}
|
||||
if (_value && _value.mime && _value.mime.match(/video\//, 'ig')) {
|
||||
mediaContent[0]["thumbnail"] = this.egw().mime_icon(_value.mime, _value.path, undefined, _value.mtime);
|
||||
}
|
||||
else {
|
||||
mediaContent[0]["thumbnail"] = _value.path && _value.mime ?
|
||||
this.egw().mime_icon(_value.mime, _value.path, undefined, _value.mtime) :
|
||||
this.image.attr('src') + '&thheight=128';
|
||||
}
|
||||
return mediaContent;
|
||||
};
|
||||
et2_vfsMime.prototype.set_value = function (_value) {
|
||||
if (typeof _value !== 'object') {
|
||||
this.egw().debug("warn", "%s only has path, needs array with path & mime", this.id, _value);
|
||||
// Keep going, will be 'unknown type'
|
||||
}
|
||||
var src = this.egw().mime_icon(_value.mime, _value.path, undefined, _value.mtime);
|
||||
if (src) {
|
||||
// Set size of thumbnail
|
||||
if (src.indexOf("thumbnail.php") > -1) {
|
||||
if (this.options.size) {
|
||||
src += "&thsize=" + this.options.size;
|
||||
return content;
|
||||
};
|
||||
/**
|
||||
* Function to get media content to feed the expose
|
||||
*
|
||||
* @param {type} _value
|
||||
* @returns {Array} return an array of object consists of media content
|
||||
*/
|
||||
et2_vfsMime.prototype.getMedia = function (_value) {
|
||||
var base_url = egw.webserverUrl.match(/^\/ig/) ? egw(window).window.location.origin + egw.webserverUrl : egw.webserverUrl;
|
||||
var mediaContent = [{
|
||||
title: _value.name,
|
||||
type: _value.mime,
|
||||
href: _value.download_url
|
||||
}];
|
||||
// check if download_url is not already an url (some stream-wrappers allow to specify that!)
|
||||
if (_value.download_url && (_value.download_url[0] == '/' || _value.download_url.substr(0, 4) != 'http')) {
|
||||
mediaContent[0].href = base_url + _value.download_url;
|
||||
if (mediaContent[0].href && mediaContent[0].href.match(/\/webdav.php/, 'ig')) {
|
||||
mediaContent[0]["download_href"] = mediaContent[0].href + '?download';
|
||||
}
|
||||
else if (this.options.thumb_mime_size) {
|
||||
var mime_size = this.options.thumb_mime_size.split(',');
|
||||
var mime_regex = RegExp(_value.mime.split('/')[0]);
|
||||
if (typeof mime_size != 'undefined' && jQuery.isArray(mime_size)
|
||||
&& !isNaN(mime_size[mime_size.length - 1]) && isNaN(mime_size[0]) && this.options.thumb_mime_size.match(mime_regex[0], 'ig')) {
|
||||
src += "&thsize=" + mime_size[mime_size.length - 1];
|
||||
}
|
||||
if (_value && _value.mime && _value.mime.match(/video\//, 'ig')) {
|
||||
mediaContent[0]["thumbnail"] = this.egw().mime_icon(_value.mime, _value.path, undefined, _value.mtime);
|
||||
}
|
||||
else {
|
||||
mediaContent[0]["thumbnail"] = _value.path && _value.mime ?
|
||||
this.egw().mime_icon(_value.mime, _value.path, undefined, _value.mtime) :
|
||||
this.image.attr('src') + '&thheight=128';
|
||||
}
|
||||
return mediaContent;
|
||||
};
|
||||
et2_vfsMime.prototype.set_value = function (_value) {
|
||||
if (typeof _value !== 'object') {
|
||||
this.egw().debug("warn", "%s only has path, needs array with path & mime", this.id, _value);
|
||||
// Keep going, will be 'unknown type'
|
||||
}
|
||||
var src = this.egw().mime_icon(_value.mime, _value.path, undefined, _value.mtime);
|
||||
if (src) {
|
||||
// Set size of thumbnail
|
||||
if (src.indexOf("thumbnail.php") > -1) {
|
||||
if (this.options.size) {
|
||||
src += "&thsize=" + this.options.size;
|
||||
}
|
||||
else if (this.options.thumb_mime_size) {
|
||||
var mime_size = this.options.thumb_mime_size.split(',');
|
||||
var mime_regex = RegExp(_value.mime.split('/')[0]);
|
||||
if (typeof mime_size != 'undefined' && jQuery.isArray(mime_size)
|
||||
&& !isNaN(mime_size[mime_size.length - 1]) && isNaN(mime_size[0]) && this.options.thumb_mime_size.match(mime_regex[0], 'ig')) {
|
||||
src += "&thsize=" + mime_size[mime_size.length - 1];
|
||||
}
|
||||
}
|
||||
this.image.css("max-width", "100%");
|
||||
}
|
||||
this.image.attr("src", src);
|
||||
// tooltip for mimetypes with available detailed thumbnail
|
||||
if (_value.mime && _value.mime.match(/application\/vnd\.oasis\.opendocument\.(text|presentation|spreadsheet|chart)/)) {
|
||||
var tooltip_target = this.image.parent().parent().parent().length > 0 ?
|
||||
// Nextmatch row
|
||||
this.image.parent().parent().parent() :
|
||||
// Not in nextmatch
|
||||
this.image.parent();
|
||||
tooltip_target.tooltip({
|
||||
items: "img",
|
||||
position: { my: "right top", at: "left top", collision: "flipfit" },
|
||||
content: function () {
|
||||
return '<img src="' + this.src + '&thsize=512"/>';
|
||||
}
|
||||
});
|
||||
}
|
||||
this.image.css("max-width", "100%");
|
||||
}
|
||||
this.image.attr("src", src);
|
||||
// tooltip for mimetypes with available detailed thumbnail
|
||||
if (_value.mime && _value.mime.match(/application\/vnd\.oasis\.opendocument\.(text|presentation|spreadsheet|chart)/)) {
|
||||
var tooltip_target = this.image.parent().parent().parent().length > 0 ?
|
||||
// Nextmatch row
|
||||
this.image.parent().parent().parent() :
|
||||
// Not in nextmatch
|
||||
this.image.parent();
|
||||
tooltip_target.tooltip({
|
||||
items: "img",
|
||||
position: { my: "right top", at: "left top", collision: "flipfit" },
|
||||
content: function () {
|
||||
return '<img src="' + this.src + '&thsize=512"/>';
|
||||
}
|
||||
});
|
||||
// add/remove link icon, if file is (not) a symlink
|
||||
if ((_value.mode & et2_vfsMode.types.l) == et2_vfsMode.types.l) {
|
||||
if (typeof this.overlayContainer == 'undefined') {
|
||||
this.overlayContainer = jQuery(document.createElement('span')).addClass('overlayContainer');
|
||||
this.overlayContainer.append(jQuery(document.createElement('img'))
|
||||
.addClass('overlay').attr('src', this.egw().image('link', 'etemplate')));
|
||||
this.iconOverlayContainer.append(this.overlayContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
// add/remove link icon, if file is (not) a symlink
|
||||
if ((_value.mode & et2_vfsMode.types.l) == et2_vfsMode.types.l) {
|
||||
if (typeof this.overlayContainer == 'undefined') {
|
||||
this.overlayContainer = jQuery(document.createElement('span')).addClass('overlayContainer');
|
||||
this.overlayContainer.append(jQuery(document.createElement('img'))
|
||||
.addClass('overlay').attr('src', this.egw().image('link', 'etemplate')));
|
||||
this.iconOverlayContainer.append(this.overlayContainer);
|
||||
else if (typeof this.overlayContainer != 'undefined') {
|
||||
this.overlayContainer.remove();
|
||||
delete this.overlayContainer;
|
||||
}
|
||||
}
|
||||
else if (typeof this.overlayContainer != 'undefined') {
|
||||
this.overlayContainer.remove();
|
||||
delete this.overlayContainer;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Implementation of "et2_IDetachedDOM" for fast viewing in gridview
|
||||
* Override to add needed attributes
|
||||
*
|
||||
* @param {array} _attrs array of attribute-names to push further names onto
|
||||
*/
|
||||
et2_vfsMime.prototype.getDetachedAttributes = function (_attrs) {
|
||||
_attrs.push("value", "class");
|
||||
};
|
||||
et2_vfsMime.prototype.getDetachedNodes = function () {
|
||||
return [this.node, this.iconOverlayContainer[0], this.image[0]];
|
||||
};
|
||||
et2_vfsMime.prototype.setDetachedAttributes = function (_nodes, _values) {
|
||||
this.iconOverlayContainer = jQuery(_nodes[1]);
|
||||
this.image = jQuery(_nodes[2]);
|
||||
this.node = _nodes[0];
|
||||
this.overlayContainer = _nodes[0].children[1];
|
||||
if (typeof _values['class'] != "undefined") {
|
||||
this.image.addClass(_values['class']);
|
||||
}
|
||||
if (typeof _values['value'] != "undefined") {
|
||||
this.set_value(_values['value']);
|
||||
}
|
||||
};
|
||||
et2_vfsMime._attributes = {
|
||||
};
|
||||
/**
|
||||
* Implementation of "et2_IDetachedDOM" for fast viewing in gridview
|
||||
* Override to add needed attributes
|
||||
*
|
||||
* @param {array} _attrs array of attribute-names to push further names onto
|
||||
*/
|
||||
et2_vfsMime.prototype.getDetachedAttributes = function (_attrs) {
|
||||
_attrs.push("value", "class");
|
||||
};
|
||||
et2_vfsMime.prototype.getDetachedNodes = function () {
|
||||
return [this.node, this.iconOverlayContainer[0], this.image[0]];
|
||||
};
|
||||
et2_vfsMime.prototype.setDetachedAttributes = function (_nodes, _values) {
|
||||
this.iconOverlayContainer = jQuery(_nodes[1]);
|
||||
this.image = jQuery(_nodes[2]);
|
||||
this.node = _nodes[0];
|
||||
this.overlayContainer = _nodes[0].children[1];
|
||||
if (typeof _values['class'] != "undefined") {
|
||||
this.image.addClass(_values['class']);
|
||||
}
|
||||
if (typeof _values['value'] != "undefined") {
|
||||
this.set_value(_values['value']);
|
||||
}
|
||||
};
|
||||
return et2_vfsMime;
|
||||
}(et2_core_valueWidget_1.et2_valueWidget)),
|
||||
_a._attributes = {
|
||||
"value": {
|
||||
"type": "any",
|
||||
"description": "Array of (stat) information about the file"
|
||||
@ -608,10 +610,9 @@ var et2_vfsMime = /** @class */ (function (_super) {
|
||||
default: "",
|
||||
description: " Size of thumbnail in pixel for specified mime type with syntax of: mime_type(s),size (eg. image,video,128)"
|
||||
}
|
||||
};
|
||||
return et2_vfsMime;
|
||||
}(et2_core_valueWidget_1.et2_valueWidget));
|
||||
et2_core_widget_1.et2_register_widget(et2_vfsMime, ["vfs-mime"]);
|
||||
},
|
||||
_a));
|
||||
et2_core_widget_1.et2_register_widget(exports.et2_vfsMime, ["vfs-mime"]);
|
||||
/**
|
||||
* vfs-size
|
||||
* Human readable file sizes
|
||||
|
@ -483,10 +483,9 @@ et2_register_widget(et2_vfsName_ro, ["vfs-name_ro"]);
|
||||
* </span>
|
||||
*
|
||||
* span.overlayContainer is optional and only generated for symlinks
|
||||
* @todo implement mixin Expose class
|
||||
* @augments et2_valueWidget
|
||||
*/
|
||||
class et2_vfsMime extends et2_valueWidget implements et2_IDetachedDOM
|
||||
export const et2_vfsMime = expose(class et2_vfsMime extends et2_valueWidget implements et2_IDetachedDOM, et2_IExposable
|
||||
{
|
||||
static readonly _attributes : any = {
|
||||
"value": {
|
||||
@ -694,7 +693,7 @@ class et2_vfsMime extends et2_valueWidget implements et2_IDetachedDOM
|
||||
this.set_value(_values['value']);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
et2_register_widget(et2_vfsMime, ["vfs-mime"]);
|
||||
|
||||
/**
|
||||
|
File diff suppressed because it is too large
Load Diff
589
api/js/etemplate/expose.ts
Normal file
589
api/js/etemplate/expose.ts
Normal file
@ -0,0 +1,589 @@
|
||||
/**
|
||||
* EGroupware eTemplate2 - JS object implementing expose view of media and a gallery view
|
||||
*
|
||||
* @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[at]stylite.de>
|
||||
* @copyright Stylite AG
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/*egw:uses
|
||||
/vendor/bower-asset/jquery/dist/jquery.js;
|
||||
/api/js/jquery/blueimp/js/blueimp-gallery.min.js;
|
||||
*/
|
||||
|
||||
|
||||
import {WidgetConfig} from "./et2_core_widget";
|
||||
import {ClassWithAttributes} from "./et2_core_inheritance";
|
||||
|
||||
type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
|
||||
/**
|
||||
* This function extends the given widget with blueimp gallery plugin
|
||||
*
|
||||
* @param {type} widget
|
||||
* @returns {widget}
|
||||
*/
|
||||
function expose<TBase extends Constructor>(Base: TBase) {
|
||||
"use strict";
|
||||
|
||||
// Minimum data to qualify as an image and not cause errors
|
||||
const IMAGE_DEFAULT = {
|
||||
title: egw.lang('loading'),
|
||||
href: '',
|
||||
type: 'image/png',
|
||||
thumbnail: '',
|
||||
loading: true
|
||||
};
|
||||
|
||||
// For filtering to only show things we can handle
|
||||
const MIME_REGEX = (navigator.userAgent.match(/(MSIE|Trident)/)) ?
|
||||
// IE only supports video/mp4 mime type
|
||||
new RegExp(/(video\/mp4)|(image\/:*(?!tif|x-xcf|pdf))/) :
|
||||
new RegExp(/(video\/(mp4|ogg|webm))|(image\/:*(?!tif|x-xcf|pdf))/);
|
||||
|
||||
|
||||
// open office document mime type currently supported by webodf editor
|
||||
const MIME_ODF_REGEX = new RegExp(/application\/vnd\.oasis\.opendocument\.text/);
|
||||
|
||||
// Only one gallery
|
||||
var gallery = null;
|
||||
|
||||
/**
|
||||
* See if the current widget is in a nextmatch, as this allows us to display
|
||||
* thumbnails underneath
|
||||
*
|
||||
* @param {et2_IExposable} widget
|
||||
* @returns {et2_nextmatch | null}
|
||||
*/
|
||||
var find_nextmatch = function (widget) {
|
||||
var current = widget;
|
||||
var nextmatch = null;
|
||||
while (nextmatch == null && current) {
|
||||
current = current.getParent();
|
||||
if (typeof current != 'undefined' && current.instanceOf(et2_nextmatch)) {
|
||||
nextmatch = current;
|
||||
}
|
||||
}
|
||||
// No nextmatch, or nextmatch not quite ready
|
||||
// At the moment only filemanger nm would work
|
||||
// as gallery, thus we disable other nestmatches
|
||||
// to build up gallery but filemanager
|
||||
if (nextmatch == null || nextmatch.controller == null || !nextmatch.dom_id.match(/filemanager/, 'ig')) return null;
|
||||
|
||||
return nextmatch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read images out of the data for the nextmatch
|
||||
*
|
||||
* @param {et2_nextmatch} nm
|
||||
* @param {Object[]} images
|
||||
* @param {number} start_at
|
||||
* @returns {undefined}
|
||||
*/
|
||||
var read_from_nextmatch = function (nm, images, start_at) {
|
||||
if (!start_at) start_at = 0;
|
||||
var image_index = start_at;
|
||||
var stop = Math.max.apply(null, Object.keys(nm.controller._indexMap));
|
||||
|
||||
for (var i = start_at; i <= stop; i++) {
|
||||
if (!nm.controller._indexMap[i] || !nm.controller._indexMap[i].uid) {
|
||||
// Returning instead of using IMAGE_DEFAULT means we stop as
|
||||
// soon as a hole is found, instead of getting everything that is
|
||||
// available. The gallery can't fill in the holes.
|
||||
images[image_index++] = IMAGE_DEFAULT;
|
||||
continue;
|
||||
}
|
||||
var uid = nm.controller._indexMap[i].uid;
|
||||
if (!uid) continue;
|
||||
var data = egw.dataGetUIDdata(uid);
|
||||
if (data && data.data && data.data.mime && MIME_REGEX.test(data.data.mime)) {
|
||||
var media = this.getMedia(data.data);
|
||||
images[image_index++] = jQuery.extend({}, data.data, media[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a particular index/image in the gallery instead of just appending
|
||||
* it to the end
|
||||
*
|
||||
* @param {integer} index
|
||||
* @param {Object} image
|
||||
* @returns {undefined}
|
||||
*/
|
||||
var set_slide = function (index, image) {
|
||||
var active = (index == gallery.index);
|
||||
|
||||
// Pad with blanks until length is right
|
||||
while (index > gallery.getNumber()) {
|
||||
gallery.add([jQuery.extend({}, IMAGE_DEFAULT)]);
|
||||
}
|
||||
|
||||
// Don't bother with adding a default, we just did that
|
||||
if (image.loading) {
|
||||
//Add load class if it's really a slide with error
|
||||
if (gallery.slidesContainer.find('[data-index="' + index + '"]').hasClass(gallery.options.slideErrorClass))
|
||||
jQuery(gallery.slides[index])
|
||||
.addClass(gallery.options.slideLoadingClass)
|
||||
.removeClass(gallery.options.slideErrorClass);
|
||||
return;
|
||||
}
|
||||
// Remove the loading class if the slide is loaded
|
||||
else {
|
||||
jQuery(gallery.slides[index]).removeClass(gallery.options.slideLoadingClass);
|
||||
}
|
||||
|
||||
// Just use add to let gallery create everything it needs
|
||||
var new_index = gallery.num;
|
||||
gallery.add([image]);
|
||||
|
||||
// Move it to where we want it.
|
||||
// Gallery uses arrays and indexes and has several internal variables
|
||||
// that need to be updated.
|
||||
//
|
||||
// list
|
||||
gallery.list[index] = gallery.list[new_index];
|
||||
gallery.list.splice(new_index, 1);
|
||||
|
||||
// indicators & slides
|
||||
var dom_nodes = ['indicators', 'slides'];
|
||||
for (var i in dom_nodes) {
|
||||
var var_name = dom_nodes[i];
|
||||
// Remove old one from DOM
|
||||
jQuery(gallery[var_name][index]).remove();
|
||||
// Move new one into it's place in gallery
|
||||
gallery[var_name][index] = gallery[var_name][new_index];
|
||||
// Move into place in DOM
|
||||
var node = jQuery(gallery[var_name][index]);
|
||||
node.attr('data-index', index)
|
||||
.insertAfter(jQuery("[data-index='" + (index - 1) + "']", node.parent()));
|
||||
if (active) node.addClass(gallery.options.activeIndicatorClass);
|
||||
gallery[var_name].splice(new_index, 1);
|
||||
}
|
||||
if (active) {
|
||||
gallery.activeIndicator = jQuery(gallery.indicators[index]);
|
||||
}
|
||||
|
||||
// positions
|
||||
gallery.positions[index] = active ? 0 : (index > gallery.index ? gallery.slideWidth : -gallery.slideWidth);
|
||||
gallery.positions.splice(new_index, 1);
|
||||
|
||||
// elements - removing will allow to re-do the slide
|
||||
if (gallery.elements[index]) {
|
||||
delete gallery.elements[index];
|
||||
gallery.loadElement(index);
|
||||
}
|
||||
|
||||
// Remove the one we just added
|
||||
gallery.num -= 1;
|
||||
};
|
||||
|
||||
return class exposable extends Base {
|
||||
private mime_regexp: RegExp;
|
||||
private mime_odf_regex: RegExp;
|
||||
private expose_options: {
|
||||
container: string; toggleControlsOnReturn: boolean; closeOnSwipeUpOrDown: boolean; clearSlides: boolean; onopen: any; emulateTouchEvents: boolean; onslideend: (index, slide) => void; rightEdgeClass: string; thumbnailWithImgTag: boolean; onslidecomplete: (index, slide) => void; continuous: boolean; startSlideshow: boolean; fullscreenClass: string; onslide: (index, slide) => void; playingClass: string; slideClass: string; urlProperty: string; closeOnEscape: boolean; singleClass: string; slideErrorClass: string; index: number; preloadRange: number; slideContentClass: string; onclosed: any; hidePageScrollbars: boolean; displayTransition: boolean; indicatorContainer: string; disableScroll: boolean; unloadElements: boolean; nextClass: string; stopTouchEventsPropagation: boolean; transitionSpeed: number; carousel: boolean; titleProperty: string; prevClass: string; typeProperty: string; enableKeyboardNavigation: boolean; slidesContainer: string; closeOnSlideClick: boolean; stretchImages: boolean; onclose: any; onopened: any; playPauseClass: string; thumbnailProperty: string; titleElement: string; slideLoadingClass: string; toggleSlideshowOnSpace: boolean; thumbnailIndicators: boolean; activeIndicatorClass: string; displayClass: string; closeClass: string; slideshowInterval: number; toggleClass: string; hideControlsOnSlideshow: boolean; controlsClass: string; toggleFullscreenOnSlideShow: boolean; leftEdgeClass: string; slideshowTransitionSpeed: undefined
|
||||
};
|
||||
|
||||
constructor(...args: any[])
|
||||
{
|
||||
// Call the inherited constructor
|
||||
super(...args);
|
||||
this.mime_regexp = MIME_REGEX;
|
||||
this.mime_odf_regex = MIME_ODF_REGEX;
|
||||
let self = this;
|
||||
this.expose_options = {
|
||||
// The Id, element or querySelector of the gallery widget:
|
||||
container: '#blueimp-gallery',
|
||||
// The tag name, Id, element or querySelector of the slides container:
|
||||
slidesContainer: 'div',
|
||||
// The tag name, Id, element or querySelector of the title element:
|
||||
titleElement: 'h3',
|
||||
// The class to add when the gallery is visible:
|
||||
displayClass: 'blueimp-gallery-display',
|
||||
// The class to add when the gallery controls are visible:
|
||||
controlsClass: 'blueimp-gallery-controls',
|
||||
// The class to add when the gallery only displays one element:
|
||||
singleClass: 'blueimp-gallery-single',
|
||||
// The class to add when the left edge has been reached:
|
||||
leftEdgeClass: 'blueimp-gallery-left',
|
||||
// The class to add when the right edge has been reached:
|
||||
rightEdgeClass: 'blueimp-gallery-right',
|
||||
// The class to add when the automatic slideshow is active:
|
||||
playingClass: 'blueimp-gallery-playing',
|
||||
// The class for all slides:
|
||||
slideClass: 'slide',
|
||||
// The slide class for loading elements:
|
||||
slideLoadingClass: '',
|
||||
// The slide class for elements that failed to load:
|
||||
slideErrorClass: 'slide-error',
|
||||
// The class for the content element loaded into each slide:
|
||||
slideContentClass: 'slide-content',
|
||||
// The class for the "toggle" control:
|
||||
toggleClass: 'toggle',
|
||||
// The class for the "prev" control:
|
||||
prevClass: 'prev',
|
||||
// The class for the "next" control:
|
||||
nextClass: 'next',
|
||||
// The class for the "close" control:
|
||||
closeClass: 'close',
|
||||
// The class for the "play-pause" toggle control:
|
||||
playPauseClass: 'play-pause',
|
||||
// The class to add for fullscreen button option
|
||||
fullscreenClass: 'fullscreen',
|
||||
// The list object property (or data attribute) with the object type:
|
||||
typeProperty: 'type',
|
||||
// The list object property (or data attribute) with the object title:
|
||||
titleProperty: 'title',
|
||||
// The list object property (or data attribute) with the object URL:
|
||||
urlProperty: 'href',
|
||||
// The gallery listens for transitionend events before triggering the
|
||||
// opened and closed events, unless the following option is set to false:
|
||||
displayTransition: true,
|
||||
// Defines if the gallery slides are cleared from the gallery modal,
|
||||
// or reused for the next gallery initialization:
|
||||
clearSlides: true,
|
||||
// Defines if images should be stretched to fill the available space,
|
||||
// while maintaining their aspect ratio (will only be enabled for browsers
|
||||
// supporting background-size="contain", which excludes IE < 9).
|
||||
// Set to "cover", to make images cover all available space (requires
|
||||
// support for background-size="cover", which excludes IE < 9):
|
||||
stretchImages: true,
|
||||
// Toggle the controls on pressing the Return key:
|
||||
toggleControlsOnReturn: true,
|
||||
// Toggle the automatic slideshow interval on pressing the Space key:
|
||||
toggleSlideshowOnSpace: true,
|
||||
// Navigate the gallery by pressing left and right on the keyboard:
|
||||
enableKeyboardNavigation: true,
|
||||
// Close the gallery on pressing the ESC key:
|
||||
closeOnEscape: true,
|
||||
// Close the gallery when clicking on an empty slide area:
|
||||
closeOnSlideClick: false,
|
||||
// Close the gallery by swiping up or down:
|
||||
closeOnSwipeUpOrDown: true,
|
||||
// Emulate touch events on mouse-pointer devices such as desktop browsers:
|
||||
emulateTouchEvents: true,
|
||||
// Stop touch events from bubbling up to ancestor elements of the Gallery:
|
||||
stopTouchEventsPropagation: false,
|
||||
// Hide the page scrollbars:
|
||||
hidePageScrollbars: true,
|
||||
// Stops any touches on the container from scrolling the page:
|
||||
disableScroll: true,
|
||||
// Carousel mode (shortcut for carousel specific options):
|
||||
carousel: true,
|
||||
// Allow continuous navigation, moving from last to first
|
||||
// and from first to last slide:
|
||||
continuous: false,
|
||||
// Remove elements outside of the preload range from the DOM:
|
||||
unloadElements: true,
|
||||
// Start with the automatic slideshow:
|
||||
startSlideshow: false,
|
||||
// Delay in milliseconds between slides for the automatic slideshow:
|
||||
slideshowInterval: 3000,
|
||||
// The starting index as integer.
|
||||
// Can also be an object of the given list,
|
||||
// or an equal object with the same url property:
|
||||
index: 0,
|
||||
// The number of elements to load around the current index:
|
||||
preloadRange: 2,
|
||||
// The transition speed between slide changes in milliseconds:
|
||||
transitionSpeed: 400,
|
||||
//Hide controls when the slideshow is playing
|
||||
hideControlsOnSlideshow: true,
|
||||
//Request fullscreen on slide show
|
||||
toggleFullscreenOnSlideShow: true,
|
||||
// The transition speed for automatic slide changes, set to an integer
|
||||
// greater 0 to override the default transition speed:
|
||||
slideshowTransitionSpeed: undefined,
|
||||
// The tag name, Id, element or querySelector of the indicator container:
|
||||
indicatorContainer: 'ol',
|
||||
// The class for the active indicator:
|
||||
activeIndicatorClass: 'active',
|
||||
// The list object property (or data attribute) with the thumbnail URL,
|
||||
// used as alternative to a thumbnail child element:
|
||||
thumbnailProperty: 'thumbnail',
|
||||
// Defines if the gallery indicators should display a thumbnail:
|
||||
thumbnailIndicators: true,
|
||||
//thumbnail with image tag
|
||||
thumbnailWithImgTag: true,
|
||||
// Callback function executed when the Gallery is initialized.
|
||||
// Is called with the gallery instance as "this" object:
|
||||
onopen: jQuery.proxy(this.expose_onopen, this),
|
||||
// Callback function executed when the Gallery has been initialized
|
||||
// and the initialization transition has been completed.
|
||||
// Is called with the gallery instance as "this" object:
|
||||
onopened: jQuery.proxy(this.expose_onopened, this),
|
||||
// Callback function executed on slide change.
|
||||
// Is called with the gallery instance as "this" object and the
|
||||
// current index and slide as arguments:
|
||||
onslide: function (index, slide) {
|
||||
// Call our onslide method, and include gallery as an attribute
|
||||
self.expose_onslide.apply(self, [this, index, slide]);
|
||||
},
|
||||
// Callback function executed after the slide change transition.
|
||||
// Is called with the gallery instance as "this" object and the
|
||||
// current index and slide as arguments:
|
||||
onslideend: function (index, slide) {
|
||||
// Call our onslide method, and include gallery as an attribute
|
||||
self.expose_onslideend.apply(self, [this, index, slide]);
|
||||
},
|
||||
//// Callback function executed on slide content load.
|
||||
// Is called with the gallery instance as "this" object and the
|
||||
// slide index and slide element as arguments:
|
||||
onslidecomplete: function (index, slide) {
|
||||
// Call our onslide method, and include gallery as an attribute
|
||||
self.expose_onslidecomplete.apply(self, [this, index, slide]);
|
||||
},
|
||||
//// Callback function executed when the Gallery is about to be closed.
|
||||
// Is called with the gallery instance as "this" object:
|
||||
onclose: jQuery.proxy(this.expose_onclose, this),
|
||||
// Callback function executed when the Gallery has been closed
|
||||
// and the closing transition has been completed.
|
||||
// Is called with the gallery instance as "this" object:
|
||||
onclosed: jQuery.proxy(this.expose_onclosed, this)
|
||||
};
|
||||
let $body = jQuery('body');
|
||||
if ($body.find('#blueimp-gallery').length == 0) {
|
||||
// Gallery Main DIV container
|
||||
let $expose_node = jQuery(document.createElement('div')).attr({
|
||||
id: "blueimp-gallery",
|
||||
class: "blueimp-gallery"
|
||||
});
|
||||
// Create Gallery DOM NODE
|
||||
$expose_node.append('<div class="slides"></div><h3 class="title"></h3><a class="prev">‹</a><a class="next">›</a><a title="' + egw().lang('Close') + '" class="close">×</a><a title="' + egw().lang('Play/Pause') + '" class="play-pause"></a><a title="' + egw().lang('Fullscreen') + '" class="fullscreen"></a><a title="' + egw().lang('Save') + '" class="download"></a><ol class="indicator"></ol>');
|
||||
// Append the gallery Node to DOM
|
||||
$body.append($expose_node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
set_value(_value) {
|
||||
//todo: not sure if we need that with the new construction
|
||||
//if (typeof this._super == 'undefined') return;
|
||||
|
||||
super.set_value(_value);
|
||||
// Do not run set value of expose if expose_view is not set
|
||||
// it causes a wired error on nested image widgets which
|
||||
// seems the expose is not its child widget
|
||||
if (!this.options.expose_view) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fe = egw_get_file_editor_prefered_mimes();
|
||||
var self = this;
|
||||
// If the media type is not supported do not bind the click handler
|
||||
if (!_value || typeof _value.mime != 'string' || (!_value.mime.match(MIME_REGEX, 'ig')
|
||||
&& (!fe || fe.mime && !fe.mime[_value.mime])) || typeof _value.download_url == 'undefined') {
|
||||
return;
|
||||
}
|
||||
if (typeof this.options.expose_view != 'undefined' && this.options.expose_view) {
|
||||
jQuery(this.node).on('click', function (event) {
|
||||
// Do not trigger expose view if one of the operator keys are held
|
||||
if (!event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) {
|
||||
if (_value.mime.match(MIME_REGEX, 'ig')) {
|
||||
self._init_blueimp_gallery(event, _value);
|
||||
} else if (fe && fe.mime && fe.edit && fe.mime[_value.mime]) {
|
||||
egw.open_link(egw.link('/index.php', {
|
||||
menuaction: fe.edit.menuaction,
|
||||
path: _value.path,
|
||||
cd: 'no' // needed to not reload framework in sharing
|
||||
}), '', fe.edit_popup);
|
||||
}
|
||||
}
|
||||
event.stopImmediatePropagation();
|
||||
}).addClass('et2_clickable');
|
||||
}
|
||||
}
|
||||
|
||||
private _init_blueimp_gallery(event, _value) {
|
||||
let mediaContent = [];
|
||||
let nm = find_nextmatch(this);
|
||||
let current_index = 0;
|
||||
if (nm && !this._is_target_indepth(nm, event.target)) {
|
||||
// Get the row that was clicked, find its index in the list
|
||||
let current_entry = nm.controller.getRowByNode(event.target);
|
||||
|
||||
// But before it goes, we'll pull everything we can
|
||||
read_from_nextmatch.call(this, nm, mediaContent);
|
||||
// find current_entry in array and set it's array-index
|
||||
for (let i = 0; i < mediaContent.length; i++) {
|
||||
if ('filemanager::' + mediaContent[i].path == current_entry.uid) {
|
||||
current_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This will trigger nm to refresh and get just the ones we can handle
|
||||
// but it might take a while, so do it later - make sure our current
|
||||
// one is loaded first.
|
||||
window.setTimeout(function () {
|
||||
nm.applyFilters({col_filter: {mime: '/' + MIME_REGEX.source + '/'}});
|
||||
}, 1);
|
||||
} else {
|
||||
mediaContent = this.getMedia(_value);
|
||||
// Do not show thumbnail indicator on single expose view
|
||||
this.expose_options.thumbnailIndicators = false;
|
||||
}
|
||||
this.expose_options.index = current_index;
|
||||
gallery = blueimp.Gallery(mediaContent, this.expose_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if clicked target from nm is in depth
|
||||
*
|
||||
* @param nm nextmatch widget
|
||||
* @param target selected target dom node
|
||||
*
|
||||
* @return {boolean} returns false if target is not in depth otherwise True
|
||||
*/
|
||||
private _is_target_indepth(nm, target?)
|
||||
{
|
||||
let res = false;
|
||||
if (nm) {
|
||||
if (!target) {
|
||||
let target = this.getDOMNode();
|
||||
}
|
||||
let entry = nm.controller.getRowByNode(target);
|
||||
if (entry && entry.controller.getDepth() > 0) {
|
||||
res = true;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
expose_onopen(event) {}
|
||||
|
||||
expose_onopened(event)
|
||||
{
|
||||
// Check to see if we're in a nextmatch, do magic
|
||||
let nm = find_nextmatch(this);
|
||||
let self = this;
|
||||
if (nm) {
|
||||
// Add scrolling to the indicator list
|
||||
let total_count = nm.controller._grid.getTotalCount();
|
||||
if (total_count >= gallery.num) {
|
||||
let $indicator = gallery.container.find('.indicator');
|
||||
$indicator.off()
|
||||
.addClass('paginating')
|
||||
.swipe(function (event, direction, distance) {
|
||||
if (direction == jQuery.fn.swipe.directions.LEFT) {
|
||||
distance *= -1;
|
||||
} else if (direction == jQuery.fn.swipe.directions.RIGHT) {
|
||||
// OK.
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
jQuery(this).css('left', min(0, parseInt(jQuery(this).css('left')) - (distance * 30)) + 'px');
|
||||
});
|
||||
// Bind the mousewheel handler for FF (DOMMousewheel), and other browsers (mousewheel)
|
||||
$indicator.bind('mousewheel DOMMousewheel', function (event, _delta) {
|
||||
var delta = _delta || event.originalEvent.wheelDelta / 120;
|
||||
if (delta > 0 && parseInt(jQuery(this).css('left')) > gallery.container.width() / 2) return;
|
||||
|
||||
//Reload next pictures into the gallery by scrolling on thumbnails
|
||||
if (delta < 0 && jQuery(this).width() + parseInt(jQuery(this).css('left')) < gallery.container.width()) {
|
||||
var nextIndex = gallery.indicatorContainer.find('[title="loading"]')[0];
|
||||
if (nextIndex) self.expose_onslideend(gallery, nextIndex.dataset.index - 1);
|
||||
return;
|
||||
}
|
||||
// Move it about 5 indicators
|
||||
jQuery(this).css('left', parseInt(jQuery(this).css('left')) - (-delta * gallery.activeIndicator.width() * 5) + 'px');
|
||||
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger on slide left/right
|
||||
* @param {Gallery} gallery
|
||||
* @param {integer} index
|
||||
* @param {DOMNode} slide
|
||||
*/
|
||||
expose_onslide(gallery, index, slide)
|
||||
{
|
||||
//todo
|
||||
//if (typeof this._super == 'undefined') return;
|
||||
// First let parent try
|
||||
super(gallery, index, slide);
|
||||
let nm = find_nextmatch(this);
|
||||
if (nm) {
|
||||
// See if we need to move the indicator
|
||||
let indicator = gallery.container.find('.indicator');
|
||||
let current = jQuery('.active', indicator).position();
|
||||
|
||||
if (current) {
|
||||
indicator.animate({left: (gallery.container.width() / 2) - current.left}, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expose_onslideend(gallery, index, slide?) {
|
||||
// Check to see if we're in a nextmatch, do magic
|
||||
let nm = find_nextmatch(this);
|
||||
if (nm) {
|
||||
// Check to see if we're near the end, or maybe some pagination
|
||||
// would be good.
|
||||
let total_count = nm.controller._grid.getTotalCount();
|
||||
|
||||
// Already at the end, don't bother
|
||||
if (index == total_count - 1 || index == 0) return;
|
||||
|
||||
// Try to determine direction from state of next & previous slides
|
||||
let direction = 1;
|
||||
for (let i in gallery.elements) {
|
||||
// Loading or error
|
||||
if (gallery.elements[i] == 1 || gallery.elements[i] == 3 || gallery.list[i].loading) {
|
||||
direction = i >= index ? 1 : -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gallery.list[index + direction] || gallery.list[index + direction].loading ||
|
||||
total_count > gallery.getNumber() && index + ET2_DATAVIEW_STEPSIZE > gallery.getNumber()) {
|
||||
// This will get the next batch of rows
|
||||
let start = Math.max(0, direction > 0 ? index : index - ET2_DATAVIEW_STEPSIZE);
|
||||
let end = Math.min(total_count - 1, start + ET2_DATAVIEW_STEPSIZE);
|
||||
nm.controller._gridCallback(start, end);
|
||||
let images = [];
|
||||
read_from_nextmatch.call(this, nm, images, start);
|
||||
|
||||
// Gallery always adds to the end, causing problems with pagination
|
||||
for (let i in images) {
|
||||
//if(i == index || i < gallery.num) continue;
|
||||
set_slide(i, images[i]);
|
||||
//gallery.add([images[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expose_onslidecomplete(gallery, index, slide) {
|
||||
}
|
||||
|
||||
expose_onclose(event) {
|
||||
// Check to see if we're in a nextmatch, remove magic
|
||||
let nm = find_nextmatch(this);
|
||||
if (nm && !this._is_target_indepth(nm)) {
|
||||
// Remove scrolling from thumbnails
|
||||
gallery.container.find('.indicator')
|
||||
.removeClass('paginating')
|
||||
.off('mousewheel')
|
||||
.off('swipe');
|
||||
|
||||
// Remove applied mime filter
|
||||
nm.applyFilters({col_filter: {mime: ''}});
|
||||
}
|
||||
}
|
||||
|
||||
expose_onclosed(event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user