diff --git a/api/js/etemplate/et2_widget_split.ts b/api/js/etemplate/et2_widget_split.ts
index 565cbf719d..642236e6f5 100644
--- a/api/js/etemplate/et2_widget_split.ts
+++ b/api/js/etemplate/et2_widget_split.ts
@@ -161,10 +161,12 @@ export class et2_split extends et2_DOMWidget implements et2_IResizeable, et2_IPr
super.doLoadingFinished();
// Not done yet, but widget will let you know
- return new Promise((resolve) => {
+ let p = new Promise((resolve) =>
+ {
// Use a timeout to give the children a chance to finish
- window.setTimeout(() => this._init_splitter(resolve),1);
+ window.setTimeout(() => this._init_splitter(resolve), 1);
});
+ return p;
}
/**
@@ -216,12 +218,17 @@ export class et2_split extends et2_DOMWidget implements et2_IResizeable, et2_IPr
let pref = this.egw().preference('splitter-size-' + this.id, this.egw().getAppName());
if(pref)
{
- if(this.orientation == "v" && pref['sizeLeft'] < this.dynheight.outerNode.width() ||
- this.orientation == "h" && pref['sizeTop'] < this.dynheight.outerNode.height())
+ // Change from percent back to numeric
+ if(typeof pref.sizeLeft !== "undefined")
{
- options = jQuery.extend(options, pref);
- this.prefSize = pref[this.orientation == "v" ?'sizeLeft' : 'sizeTop'];
+ pref.sizeLeft = ((parseFloat(pref.sizeLeft) / 100) * widget.dynheight.outerNode.width());
}
+ if(typeof pref.sizeTop !== "undefined")
+ {
+ pref.sizeTop = ((parseFloat(pref.sizeTop) / 100) * widget.dynheight.outerNode.height());
+ }
+ options = jQuery.extend(options, pref);
+ this.prefSize = pref[this.orientation == "v" ? 'sizeLeft' : 'sizeTop'];
}
// If there is no preference yet, set it to half size
// Otherwise the right pane gets the fullsize
diff --git a/api/js/etemplate/etemplate2.ts b/api/js/etemplate/etemplate2.ts
index 47a0a4f706..090d82d1d3 100644
--- a/api/js/etemplate/etemplate2.ts
+++ b/api/js/etemplate/etemplate2.ts
@@ -646,93 +646,97 @@ export class etemplate2
egw.window.console.groupEnd();
}
- // Wait for everything to be loaded, then finish it up
- Promise.all(deferred).then(() =>
+ // Wait for everything to be loaded, then finish it up. Use timeout to give anything else a chance
+ // to run.
+ setTimeout(() =>
{
- egw.debug("log", "Finished loading %s, triggering load event", _name);
-
- if(typeof window.framework != 'undefined' && typeof window.framework.et2_loadingFinished != 'undefined')
+ Promise.all(deferred).then(() =>
{
- //Call loading finished method of the framework with local window
- window.framework.et2_loadingFinished(egw(window).window);
- }
- // Trigger the "resize" event
- this.resize();
+ egw.debug("log", "Finished loading %s, triggering load event", _name);
- // Automatically set focus to first visible input for popups
- if(this._widgetContainer._egw.is_popup() && jQuery('[autofocus]', this._DOMContainer).focus().length == 0)
- {
- const $input = jQuery('input:visible', this._DOMContainer)
- // Date fields open the calendar popup on focus
- .not('.et2_date')
- .filter(function()
+ if(typeof window.framework != 'undefined' && typeof window.framework.et2_loadingFinished != 'undefined')
+ {
+ //Call loading finished method of the framework with local window
+ window.framework.et2_loadingFinished(egw(window).window);
+ }
+ // Trigger the "resize" event
+ this.resize();
+
+ // Automatically set focus to first visible input for popups
+ if(this._widgetContainer._egw.is_popup() && jQuery('[autofocus]', this._DOMContainer).focus().length == 0)
+ {
+ const $input = jQuery('input:visible', this._DOMContainer)
+ // Date fields open the calendar popup on focus
+ .not('.et2_date')
+ .filter(function()
+ {
+ // Skip inputs that are out of tab ordering
+ const $this = jQuery(this);
+ return !$this.attr('tabindex') || parseInt($this.attr('tabIndex')) >= 0;
+ }).first();
+
+ // mobile device, focus only if the field is empty (usually means new entry)
+ // should focus always for non-mobile one
+ if(egwIsMobile() && $input.val() == "" || !egwIsMobile())
{
- // Skip inputs that are out of tab ordering
- const $this = jQuery(this);
- return !$this.attr('tabindex') || parseInt($this.attr('tabIndex')) >= 0;
- }).first();
-
- // mobile device, focus only if the field is empty (usually means new entry)
- // should focus always for non-mobile one
- if(egwIsMobile() && $input.val() == "" || !egwIsMobile())
- {
- $input.focus();
+ $input.focus();
+ }
}
- }
- // Tell others about it
- if(typeof _callback == "function")
- {
- _callback.call(window, this, _name);
- }
- if(app_callback && _callback != app_callback && !_no_et2_ready)
- {
- app_callback.call(window, this, _name);
- }
- if(appname && appname != this.app && typeof app[this.app] == "object" && !_no_et2_ready)
- {
- // Loaded a template from a different application?
- // Let the application that loaded it know too
- app[this.app].et2_ready(this, this.name);
- }
+ // Tell others about it
+ if(typeof _callback == "function")
+ {
+ _callback.call(window, this, _name);
+ }
+ if(app_callback && _callback != app_callback && !_no_et2_ready)
+ {
+ app_callback.call(window, this, _name);
+ }
+ if(appname && appname != this.app && typeof app[this.app] == "object" && !_no_et2_ready)
+ {
+ // Loaded a template from a different application?
+ // Let the application that loaded it know too
+ app[this.app].et2_ready(this, this.name);
+ }
- // Dispatch an event that will bubble through shadow DOM boundary (pass through custom elements)
- this._DOMContainer.dispatchEvent(new CustomEvent('load', {
- bubbles: true,
- composed: true,
- detail: this
- }));
+ // Dispatch an event that will bubble through shadow DOM boundary (pass through custom elements)
+ this._DOMContainer.dispatchEvent(new CustomEvent('load', {
+ bubbles: true,
+ composed: true,
+ detail: this
+ }));
- if(etemplate2.templates[this.name].attributes.onload)
- {
- let onload = et2_checkType(etemplate2.templates[this.name].attributes.onload.value, 'js', 'onload', {});
- if(typeof onload === 'string')
+ if(etemplate2.templates[this.name].attributes.onload)
{
- onload = et2_compileLegacyJS(onload, this, this._widgetContainer);
+ let onload = et2_checkType(etemplate2.templates[this.name].attributes.onload.value, 'js', 'onload', {});
+ if(typeof onload === 'string')
+ {
+ onload = et2_compileLegacyJS(onload, this, this._widgetContainer);
+ }
+ onload.call(this._widgetContainer);
}
- onload.call(this._widgetContainer);
- }
- // Profiling
- if(egw.debug_level() >= 4)
- {
- if(console.timeEnd)
+ // Profiling
+ if(egw.debug_level() >= 4)
{
- console.timeEnd(_name);
+ if(console.timeEnd)
+ {
+ console.timeEnd(_name);
+ }
+ if(console.profileEnd)
+ {
+ console.profileEnd(_name);
+ }
+ const end_time = (new Date).getTime();
+ let gen_time_div = jQuery('#divGenTime_' + appname);
+ if(!gen_time_div.length)
+ {
+ gen_time_div = jQuery('.pageGenTime');
+ }
+ gen_time_div.find('.et2RenderTime').remove();
+ gen_time_div.append('' + egw.lang('eT2 rendering took %1s', '' + ((end_time - start_time) / 1000)) + '');
}
- if(console.profileEnd)
- {
- console.profileEnd(_name);
- }
- const end_time = (new Date).getTime();
- let gen_time_div = jQuery('#divGenTime_' + appname);
- if(!gen_time_div.length)
- {
- gen_time_div = jQuery('.pageGenTime');
- }
- gen_time_div.find('.et2RenderTime').remove();
- gen_time_div.append('' + egw.lang('eT2 rendering took %1s', '' + ((end_time - start_time) / 1000)) + '');
- }
+ });
});
};