Diff widget

This commit is contained in:
nathangray 2020-02-12 13:19:21 -07:00
parent 7a79bfad93
commit fa95142954
2 changed files with 380 additions and 176 deletions

View File

@ -1,3 +1,4 @@
"use strict";
/** /**
* EGroupware eTemplate2 - JS Diff object * EGroupware eTemplate2 - JS Diff object
* *
@ -9,186 +10,180 @@
* @copyright Nathan Gray 2012 * @copyright Nathan Gray 2012
* @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
/vendor/bower-asset/jquery/dist/jquery.js; /vendor/bower-asset/jquery/dist/jquery.js;
/vendor/bower-asset/jquery-ui/jquery-ui.js; /vendor/bower-asset/jquery-ui/jquery-ui.js;
/vendor/bower-asset/diff2html/dist/diff2html.min.js; /vendor/bower-asset/diff2html/dist/diff2html.min.js;
et2_core_valueWidget; et2_core_valueWidget;
*/ */
var et2_core_widget_1 = require("./et2_core_widget");
var et2_core_inheritance_1 = require("./et2_core_inheritance");
var et2_core_valueWidget_1 = require("./et2_core_valueWidget");
/** /**
* Class that displays the diff between two [text] values * Class that displays the diff between two [text] values
* *
* @augments et2_valueWidget * @augments et2_valueWidget
*/ */
var et2_diff = (function(){ "use strict"; return et2_valueWidget.extend([et2_IDetachedDOM], var et2_diff = /** @class */ (function (_super) {
{ __extends(et2_diff, _super);
attributes: { /**
"value": { * Constructor
"type": "any" */
} function et2_diff(_parent, _attrs, _child) {
}, var _this =
// Call the inherited constructor
diff_options: { _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_diff._attributes, _child || {})) || this;
"inputFormat":"diff", _this.mini = true;
"matching": "words" // included via etemplate2.css
}, //this.egw().includeCSS('../../../vendor/bower-asset/dist/dist2html.css');
_this.div = document.createElement("div");
/** jQuery(_this.div).addClass('et2_diff');
* Constructor return _this;
* }
* @memberOf et2_diff et2_diff.prototype.set_value = function (value) {
*/ jQuery(this.div).empty();
init: function() { if (typeof value == 'string') {
this._super.apply(this, arguments); // Diff2Html likes to have files, we don't have them
this.mini = true; if (value.indexOf('---') !== 0) {
value = "--- diff\n+++ diff\n" + value;
// included via etemplate2.css }
//this.egw().includeCSS('../../../vendor/bower-asset/dist/dist2html.css'); // @ts-ignore
this.div = document.createElement("div"); var diff = Diff2Html.getPrettyHtml(value, this.diff_options);
jQuery(this.div).addClass('et2_diff'); // var ui = new Diff2HtmlUI({diff: diff});
}, // ui.draw(jQuery(this.div), this.diff_options);
jQuery(this.div).append(diff);
set_value: function(value) { }
jQuery(this.div).empty(); else if (typeof value != 'object') {
if(typeof value == 'string') { jQuery(this.div).append(value);
}
// Diff2Html likes to have files, we don't have them this.check_mini();
if(value.indexOf('---') !== 0) };
{ et2_diff.prototype.check_mini = function () {
value = "--- diff\n+++ diff\n"+value; if (!this.mini) {
} return false;
var diff = Diff2Html.getPrettyHtml(value, this.diff_options); }
// var ui = new Diff2HtmlUI({diff: diff}); var view = jQuery(this.div).children();
// ui.draw(jQuery(this.div), this.diff_options); this.minify(view);
jQuery(this.div).append(diff); var self = this;
} jQuery('<span class="ui-icon ui-icon-circle-plus">&nbsp;</span>')
else if(typeof value != 'object') .appendTo(self.div)
{ .css("cursor", "pointer")
jQuery(this.div).append(value); .click({ diff: view, div: self.div, label: self.options.label }, function (e) {
} var diff = e.data.diff;
this.check_mini(); var div = e.data.div;
}, self.un_minify(diff);
var dialog_div = jQuery('<div>')
check_mini: function() { .append(diff);
if(!this.mini) dialog_div.dialog({
{ title: e.data.label,
return false; width: 'auto',
} modal: true,
var view = jQuery(this.div).children(); buttons: [{ text: self.egw().lang('ok'), click: function () { jQuery(this).dialog("close"); } }],
this.minify(view); open: function () {
var self = this; if (jQuery(this).parent().height() > jQuery(window).height()) {
jQuery('<span class="ui-icon ui-icon-circle-plus">&nbsp;</span>') jQuery(this).height(jQuery(window).height() * 0.7);
.appendTo(self.div) }
.css("cursor", "pointer") jQuery(this).addClass('et2_diff').dialog({ position: "center" });
.click({diff: view, div: self.div, label: self.options.label}, function(e) { },
var diff = e.data.diff; close: function (event, ui) {
var div = e.data.div; // Need to destroy the dialog, etemplate widget needs divs back where they were
self.un_minify(diff); dialog_div.dialog("destroy");
var dialog_div = jQuery('<div>') self.minify(this);
.append(diff); // Put it back where it came from, or et2 will error when clear() is called
diff.prependTo(div);
dialog_div.dialog({ }
title: e.data.label, });
width: 'auto', });
autoResize: true, };
modal: true, et2_diff.prototype.set_label = function (_label) {
buttons: [{text: self.egw().lang('ok'), click: function() {jQuery(this).dialog("close");}}], this.options.label = _label;
open: function() { };
if(jQuery(this).parent().height() > jQuery(window).height()) /**
{ * Make the diff into a mini-diff
jQuery(this).height(jQuery(window).height() *0.7); *
} * @param {DOMNode|String} view
jQuery(this).addClass('et2_diff').dialog({position: "center"}); */
}, et2_diff.prototype.minify = function (view) {
close: function(event, ui) { view = jQuery(view)
// Need to destroy the dialog, etemplate widget needs divs back where they were .addClass('mini')
dialog_div.dialog("destroy"); // Dialog changes these, if resized
self.minify(this); .width('100%').css('height', 'inherit')
.show();
// Put it back where it came from, or et2 will error when clear() is called jQuery('th', view).hide();
diff.prependTo(div); jQuery('td.equal', view).hide()
} .prevAll().hide();
}); };
}); /**
}, * Expand mini-diff
set_label: function(_label) { *
this.options.label = _label; * @param {DOMNode|String} view
*/
}, et2_diff.prototype.un_minify = function (view) {
jQuery(view).removeClass('mini').show();
/** jQuery('th', view).show();
* Make the diff into a mini-diff jQuery('td.equal', view).show();
* };
* @param {DOMNode|String} view /**
*/ * Code for implementing et2_IDetachedDOM
minify: function(view) { * Fast-clonable read-only widget that only deals with DOM nodes, not the widget tree
view = jQuery(view) */
.addClass('mini') /**
// Dialog changes these, if resized * Build a list of attributes which can be set when working in the
.width('100%').css('height', 'inherit') * "detached" mode in the _attrs array which is provided
.show(); * by the calling code.
jQuery('th', view).hide(); *
jQuery('td.equal',view).hide() * @param {object} _attrs
.prevAll().hide(); */
}, et2_diff.prototype.getDetachedAttributes = function (_attrs) {
_attrs.push("value", "label");
/** };
* Expand mini-diff /**
* * Returns an array of DOM nodes. The (relativly) same DOM-Nodes have to be
* @param {DOMNode|String} view * passed to the "setDetachedAttributes" function in the same order.
*/ */
un_minify: function(view) { et2_diff.prototype.getDetachedNodes = function () {
jQuery(view).removeClass('mini').show(); return [this.div];
jQuery('th',view).show(); };
jQuery('td.equal',view).show(); /**
}, * Sets the given associative attribute->value array and applies the
* attributes to the given DOM-Node.
/** *
* Code for implementing et2_IDetachedDOM * @param _nodes is an array of nodes which has to be in the same order as
* Fast-clonable read-only widget that only deals with DOM nodes, not the widget tree * 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.
* Build a list of attributes which can be set when working in the */
* "detached" mode in the _attrs array which is provided et2_diff.prototype.setDetachedAttributes = function (_nodes, _values) {
* by the calling code. this.div = _nodes[0];
* if (typeof _values['label'] != 'undefined') {
* @param {object} _attrs this.set_label(_values['label']);
*/ }
getDetachedAttributes: function(_attrs) { if (typeof _values['value'] != 'undefined') {
_attrs.push("value", "label"); this.set_value(_values['value']);
}, }
};
/** et2_diff._attributes = {
* Returns an array of DOM nodes. The (relativly) same DOM-Nodes have to be "value": {
* passed to the "setDetachedAttributes" function in the same order. "type": "any"
*/ }
getDetachedNodes: function() { };
return [this.div]; return et2_diff;
}, }(et2_core_valueWidget_1.et2_valueWidget));
exports.et2_diff = et2_diff;
/** et2_core_widget_1.et2_register_widget(et2_diff, ["diff"]);
* Sets the given associative attribute->value array and applies the //# sourceMappingURL=et2_widget_diff.js.map
* attributes to the given DOM-Node.
*
* @param _nodes is an array of nodes which has 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.
*/
setDetachedAttributes: function(_nodes, _values) {
this.div = _nodes[0];
if(typeof _values['label'] != 'undefined')
{
this.set_label(_values['label']);
}
if(typeof _values['value'] != 'undefined')
{
this.set_value(_values['value']);
}
}
});}).call(this);
et2_register_widget(et2_diff, ["diff"]);

View File

@ -0,0 +1,209 @@
/**
* EGroupware eTemplate2 - JS Diff object
*
* @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
* @copyright Nathan Gray 2012
* @version $Id$
*/
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
/vendor/bower-asset/jquery-ui/jquery-ui.js;
/vendor/bower-asset/diff2html/dist/diff2html.min.js;
et2_core_valueWidget;
*/
import {et2_register_widget, WidgetConfig} from "./et2_core_widget";
import {ClassWithAttributes} from "./et2_core_inheritance";
import {et2_valueWidget} from "./et2_core_valueWidget";
/**
* Class that displays the diff between two [text] values
*
* @augments et2_valueWidget
*/
export class et2_diff extends et2_valueWidget implements et2_IDetachedDOM
{
static readonly _attributes = {
"value": {
"type": "any"
}
};
private readonly diff_options: {
"inputFormat":"diff",
"matching": "words"
};
private div: HTMLDivElement;
private mini: boolean = true;
/**
* Constructor
*/
constructor(_parent, _attrs? : WidgetConfig, _child? : object)
{
// Call the inherited constructor
super(_parent, _attrs, ClassWithAttributes.extendAttributes(et2_diff._attributes, _child || {}));
// included via etemplate2.css
//this.egw().includeCSS('../../../vendor/bower-asset/dist/dist2html.css');
this.div = document.createElement("div");
jQuery(this.div).addClass('et2_diff');
}
set_value( value)
{
jQuery(this.div).empty();
if(typeof value == 'string') {
// Diff2Html likes to have files, we don't have them
if(value.indexOf('---') !== 0)
{
value = "--- diff\n+++ diff\n"+value;
}
// @ts-ignore
var diff = Diff2Html.getPrettyHtml(value, this.diff_options);
// var ui = new Diff2HtmlUI({diff: diff});
// ui.draw(jQuery(this.div), this.diff_options);
jQuery(this.div).append(diff);
}
else if(typeof value != 'object')
{
jQuery(this.div).append(value);
}
this.check_mini();
}
check_mini( )
{
if(!this.mini)
{
return false;
}
var view = jQuery(this.div).children();
this.minify(view);
var self = this;
jQuery('<span class="ui-icon ui-icon-circle-plus">&nbsp;</span>')
.appendTo(self.div)
.css("cursor", "pointer")
.click({diff: view, div: self.div, label: self.options.label}, function(e) {
var diff = e.data.diff;
var div = e.data.div;
self.un_minify(diff);
var dialog_div = jQuery('<div>')
.append(diff);
dialog_div.dialog({
title: e.data.label,
width: 'auto',
modal: true,
buttons: [{text: self.egw().lang('ok'), click: function() {jQuery(this).dialog("close");}}],
open( )
{
if(jQuery(this).parent().height() > jQuery(window).height())
{
jQuery(this).height(jQuery(window).height() *0.7);
}
jQuery(this).addClass('et2_diff').dialog({position: "center"});
},
close( event, ui)
{
// Need to destroy the dialog, etemplate widget needs divs back where they were
dialog_div.dialog("destroy");
self.minify(this);
// Put it back where it came from, or et2 will error when clear() is called
diff.prependTo(div);
}
});
});
}
set_label( _label)
{
this.options.label = _label;
}
/**
* Make the diff into a mini-diff
*
* @param {DOMNode|String} view
*/
minify( view)
{
view = jQuery(view)
.addClass('mini')
// Dialog changes these, if resized
.width('100%').css('height', 'inherit')
.show();
jQuery('th', view).hide();
jQuery('td.equal',view).hide()
.prevAll().hide();
}
/**
* Expand mini-diff
*
* @param {DOMNode|String} view
*/
un_minify( view)
{
jQuery(view).removeClass('mini').show();
jQuery('th',view).show();
jQuery('td.equal',view).show();
}
/**
* Code for implementing et2_IDetachedDOM
* Fast-clonable read-only widget that only deals with DOM nodes, not the widget tree
*/
/**
* Build a list of attributes which can be set when working in the
* "detached" mode in the _attrs array which is provided
* by the calling code.
*
* @param {object} _attrs
*/
getDetachedAttributes(_attrs)
{
_attrs.push("value", "label");
}
/**
* Returns an array of DOM nodes. The (relativly) same DOM-Nodes have to be
* passed to the "setDetachedAttributes" function in the same order.
*/
getDetachedNodes()
{
return [this.div];
}
/**
* Sets the given associative attribute->value array and applies the
* attributes to the given DOM-Node.
*
* @param _nodes is an array of nodes which has 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.
*/
setDetachedAttributes(_nodes, _values)
{
this.div = _nodes[0];
if(typeof _values['label'] != 'undefined')
{
this.set_label(_values['label']);
}
if(typeof _values['value'] != 'undefined')
{
this.set_value(_values['value']);
}
}
}
et2_register_widget(et2_diff, ["diff"]);