Fixed a lot of problems regarding centralized JavaScript code; et2_dataview_view_resizeable is current WIP; now building etemplate2 DOM-Tree to a DocumentFragment first, which brings a significant performance gain

This commit is contained in:
Andreas Stöckel 2012-03-07 15:33:21 +00:00
parent 292f18bc1a
commit c0db2e36a9
8 changed files with 54 additions and 143 deletions

View File

@ -584,16 +584,6 @@ function et2_hasChild(_nodes, _child)
return false;
}
/**
* Generates a localy unique id and returns it
*/
var _et2_uniqueId = 0;
function et2_uniqueId()
{
return _et2_uniqueId++;
}
/**
* Functions to work with ranges and range intersection (used in the dataview)
*/

View File

@ -267,7 +267,7 @@
// Do some tracing of the getMem_freeMem_trace is activated
if (getMem_freeMem_trace)
{
this.__OBJ_UID = "obj_" + et2_uniqueId();
this.__OBJ_UID = "obj_" + egw.uid();
var className = this.className();
tracedObjects[this.__OBJ_UID] = {
"created": new Date().getTime(),

View File

@ -1,95 +0,0 @@
/**
* eGroupWare eTemplate2 - Stylesheet class
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage api
* @link http://www.egroupware.org
* @author Andreas Stöckel
* @copyright Stylite 2011
* @version $Id$
*/
"use strict"
/**
* Contains the egwDynStyleSheet class which allows dynamic generation of stylesheet
* rules - updating a single stylesheet rule is way more efficient than updating
* the element style of many objects.
*/
var ET2_DYNAMIC_STYLESHEET = null;
/**
* Main egwDynStyleSheet class - all egwDynStyleSheets share the same stylesheet
* which is dynamically inserted into the head section of the DOM-Tree.
* This stylesheet is created with the first egwDynStyleSheet class.
*/
function et2_dynStyleSheet()
{
// Check whether the ET2_DYNAMIC_STYLESHEET has already be created
if (!ET2_DYNAMIC_STYLESHEET)
{
var style = document.createElement("style");
document.getElementsByTagName("head")[0].appendChild(style);
this.styleSheet = style.sheet ? style.sheet : style.styleSheet;
this.selectors = {};
this.selectorCount = 0;
ET2_DYNAMIC_STYLESHEET = this;
return this;
}
else
{
return ET2_DYNAMIC_STYLESHEET;
}
}
/**
* Creates/Updates the given stylesheet rule. Example call:
*
* styleSheet.updateRule("#container", "background-color: blue; font-family: sans;")
*
* @param string _selector is the css selector to which the given rule should apply
* @param string _rule is the rule which is bound to the selector.
*/
et2_dynStyleSheet.prototype.updateRule = function (_selector, _rule)
{
var ruleObj = {
"index": this.selectorCount
}
// Remove any existing rule first
if (typeof this.selectors[_selector] !== "undefined")
{
var ruleObj = this.selectors[_selector];
if (typeof this.styleSheet.removeRule !== "undefined")
{
this.styleSheet.removeRule(ruleObj.index);
}
else
{
this.styleSheet.deleteRule(ruleObj.index);
}
delete (this.selectors[_selector]);
}
else
{
this.selectorCount++;
}
// Add the rule to the stylesheet
if (typeof this.styleSheet.addRule !== "undefined")
{
this.styleSheet.addRule(_selector, _rule, ruleObj.index);
}
else
{
this.styleSheet.insertRule(_selector + "{" + _rule + "}", ruleObj.index);
}
this.selectors[_selector] = ruleObj;
}

View File

@ -15,10 +15,9 @@
/*egw:uses
jquery.jquery;
et2_core_common;
et2_core_stylesheet;
et2_dataview_view_grid;
et2_dataview_view_resizeable;
// et2_dataview_view_resizeable;
*/
/**
@ -50,11 +49,12 @@ var et2_dataview_gridContainer = Class.extend({
* Constructor for the grid container
* @param object _parentNode is the DOM-Node into which the grid view will be inserted
*/
init: function(_parentNode, _dataProvider) {
init: function(_parentNode, _dataProvider, _egw) {
// Copy the arguments
this.parentNode = $j(_parentNode);
this.dataProvider = _dataProvider;
this.egw = _egw;
// Initialize some variables
this.columnNodes = []; // Array with the header containers
@ -67,7 +67,7 @@ var et2_dataview_gridContainer = Class.extend({
this.width = 0;
this.height = 0;
this.uniqueId = "gridCont_" + et2_uniqueId();
this.uniqueId = "gridCont_" + this.egw.uid();
// Build the base nodes
this._createElements();
@ -256,9 +256,6 @@ var et2_dataview_gridContainer = Class.extend({
* The columns will be updated.
*/
_updateColumns: function() {
// Get the stylesheet singleton
var styleSheet = new et2_dynStyleSheet();
// Copy the columns data
this.columns = this.columnMgr.getColumnData();
@ -289,7 +286,7 @@ var et2_dataview_gridContainer = Class.extend({
this.visibleColumnCount++;
// Update the visibility of the column
styleSheet.updateRule("." + col.tdClass,
this.egw.css("." + col.tdClass,
"display: table-cell; " +
((vis_col == total_cnt) ? "border-right-width: 0 " : "border-right-width: 1px ") +
"!important;");
@ -327,12 +324,12 @@ var et2_dataview_gridContainer = Class.extend({
// Write the width of the header columns
var headerWidth = Math.max(0, (col.width - this.headerBorderWidth - subHBorder));
styleSheet.updateRule(".egwGridView_outer ." + col.divClass,
this.egw.css(".egwGridView_outer ." + col.divClass,
"width: " + headerWidth + "px;");
// Write the width of the body-columns
var columnWidth = Math.max(0, (col.width - this.columnBorderWidth - subBorder));
styleSheet.updateRule(".egwGridView_grid ." + col.divClass,
this.egw.css(".egwGridView_grid ." + col.divClass,
"width: " + columnWidth + "px;");
totalWidth += col.width;
@ -341,14 +338,14 @@ var et2_dataview_gridContainer = Class.extend({
}
else
{
styleSheet.updateRule("." + col.tdClass, "display: none;");
this.egw.css("." + col.tdClass, "display: none;");
}
}
// Add the full row and spacer class
styleSheet.updateRule(".egwGridView_grid ." + this.uniqueId + "_div_fullRow",
this.egw.css(".egwGridView_grid ." + this.uniqueId + "_div_fullRow",
"width: " + (totalWidth - this.columnBorderWidth - 1) + "px; border-right-width: 0 !important;");
styleSheet.updateRule(".egwGridView_outer ." + this.uniqueId + "_spacer_fullRow",
this.egw.css(".egwGridView_outer ." + this.uniqueId + "_spacer_fullRow",
"width: " + (totalWidth - 1) + "px; border-right-width: 0 !important;");
},
@ -376,11 +373,11 @@ var et2_dataview_gridContainer = Class.extend({
// Every column but last can be resized // TODO: This won't work as the last column could be hidden
if(i < this.columns.length-1) {
var enc_column = self.columnMgr.getColumnById(col.id);
et2_dataview_makeResizeable(column, function(_w) {
/* et2_dataview_makeResizeable(column, function(_w) {
this.set_width(_w + "px");
self.columnMgr.updated = true;
self.updateColumns();
}, enc_column);
}, enc_column);*/
}
// Store both nodes in the columnNodes array

View File

@ -16,7 +16,8 @@
* This set of functions is currently only supporting resizing in ew-direction
*/
(function() {
(function ()
{
// Define some constants
var RESIZE_BORDER = 7;
@ -31,14 +32,9 @@
return (ol > (_elem.outerWidth(true) - RESIZE_BORDER));
}
var helper = null;
var overlay = null;
var didResize = false;
var resizeWidth = 0;
function startResize(_outerElem, _elem, _callback)
{
if (overlay == null || helper == null)
if (this.overlay == null || this.helper == null)
{
// Prevent text selection
_elem[0].onselectstart = function() {
@ -46,11 +42,11 @@
}
// Reset the "didResize" flag
didResize = false;
this.didResize = false;
// Create the resize helper
var left = _elem.offset().left;
helper = $j(document.createElement("div"))
this.helper = $j(document.createElement("div"))
.addClass("egwResizeHelper")
.appendTo("body")
.css("top", _elem.offset().top + "px")
@ -58,7 +54,7 @@
.css("height", _outerElem.outerHeight(true) + "px");
// Create the overlay which will be catching the mouse movements
overlay = $j(document.createElement("div"))
this.overlay = $j(document.createElement("div"))
.addClass("egwResizeOverlay")
.bind("mousemove", function(e) {
@ -69,7 +65,7 @@
})
.bind("mouseup", function() {
stopResize();
stopResize.call();
// Reset text selection
_elem[0].onselectstart = null;
@ -99,7 +95,19 @@
}
}
this.et2_dataview_makeResizeable = function(_elem, _callback, _context)
/**
* Constructor of the et2_dataview_resizeable class. et2_dataview_resizeable
* is instanciated for each dataview grid.
*/
function et2_dataview_resizeable(_body)
{
var helper = null;
var overlay = null;
var didResize = false;
var resizeWidth = 0;
}
et2_dataview_resizeable.prototype.makeResizeable = function(_elem, _callback, _context)
{
// Get the table surrounding the given element - this element is used to
// align the helper properly
@ -115,7 +123,7 @@
if (inResizeRegion(e.clientX, _elem))
{
// Start the resizing
startResize(outerTable, _elem, function(_w) {
startResize.call(this, outerTable, _elem, function(_w) {
_callback.call(_context, _w);
});
}
@ -124,10 +132,15 @@
});
}
this.et2_dataview_resetResizeable = function(_elem)
et2_dataview_resizeable.prototype.resetResizeable = function(_elem)
{
// Remove all events in the ".resize" namespace from the element
_elem.unbind(".resize");
}
// Publish the et2_dataview_resizeable class
this.et2_dataview_resizeable = et2_dataview_resizeable;
}
}).call(window);

View File

@ -112,7 +112,7 @@ var et2_nextmatch = et2_DOMWidget.extend(et2_IResizeable, {
// Create the outer grid container
this.dataviewContainer = new et2_dataview_gridContainer(this.div,
this.dataProvider);
this.dataProvider, this.egw());
this.activeFilters = {};
},

View File

@ -36,15 +36,15 @@ var et2_styles = et2_widget.extend({
this.styleNode = document.createElement("style");
this.styleNode.setAttribute("type", "text/css");
(document.getElementsByTagName("head")[0]).appendChild(this.styleNode);
this.head = this.egw().window.document.getElementsByTagName("head")[0];
this.head.appendChild(this.styleNode);
},
destroy: function() {
this._super.apply(this, arguments);
// Remove the style node again and delete any reference to it
(document.getElementsByTagName("head")[0]).removeChild(this.styleNode);
this.styleNode = null;
this.head.removeChild(this.styleNode);
this._super.apply(this, arguments);
},
loadContent: function(_content) {

View File

@ -154,6 +154,9 @@ etemplate2.prototype._createArrayManagers = function(_data)
*/
etemplate2.prototype.load = function(_url, _data)
{
// Create the document fragment into which the HTML will be injected
var frag = document.createDocumentFragment();
// Asynchronously load the XET file (code below is executed ahead of the
// code in the callback function)
et2_loadXMLFromURL(_url, function(_xmldoc) {
@ -163,6 +166,9 @@ etemplate2.prototype.load = function(_url, _data)
// Inform the widget tree that it has been successfully loaded.
this.widgetContainer.loadingFinished();
// Insert the document fragment to the DOM Container
this.DOMContainer.appendChild(frag);
// Trigger the "resize" event
this.resize();
}, this);
@ -174,7 +180,7 @@ etemplate2.prototype.load = function(_url, _data)
this.widgetContainer = new et2_container(null);
this.widgetContainer.setApiInstance(egw(egw.elemWindow(this.DOMContainer)));
this.widgetContainer.setInstanceManager(this);
this.widgetContainer.setParentDOMNode(this.DOMContainer);
this.widgetContainer.setParentDOMNode(frag);
// store the id to submit it back to server
if(_data) {