Skip to content

Commit

Permalink
* Large memory reduction
Browse files Browse the repository at this point in the history
- Work-around for shoelace-style/shoelace#2376
- Fix some missing cleanup & a few other minor improvements for etemplate widgets
- Stop egw from holding on to registered plugins (& every instance)
  • Loading branch information
nathangray committed Feb 14, 2025
1 parent a604006 commit 389a8ee
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 13 deletions.
20 changes: 19 additions & 1 deletion api/js/etemplate/Et2Button/ButtonMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import {css, LitElement, PropertyValues} from "lit";
import '../Et2Image/Et2Image';
import shoelace from "../Styles/shoelace";
import {egw_registerGlobalShortcut} from "../../egw_action/egw_keymanager";
import {egw_registerGlobalShortcut, egw_unregisterGlobalShortcut} from "../../egw_action/egw_keymanager";

type Constructor<T = LitElement> = new (...args : any[]) => T;
export const ButtonMixin = <T extends Constructor>(superclass : T) => class extends superclass
Expand Down Expand Up @@ -184,6 +184,8 @@ so we force the button images to be square*/
}
}

private _registeredKeycode : string;

constructor(...args : any[])
{
super(...args);
Expand All @@ -198,6 +200,21 @@ so we force the button images to be square*/

}

disconnectedCallback()
{
super.disconnectedCallback && super.disconnectedCallback();

// Remove keycode handler
if(this._registeredKeycode)
{
let [keycode, modifiers] = this._registeredKeycode.split("_");
egw_unregisterGlobalShortcut(keycode, modifiers.includes("S"), modifiers.includes("C"), modifiers.includes("A"));
}

// Clean up any added image
while(this.lastChild) this.lastChild.remove();
}

set image(new_image : string)
{
let oldValue = this.__image;
Expand Down Expand Up @@ -356,6 +373,7 @@ so we force the button images to be square*/
// @ts-ignore
if(check_id.match(this.constructor.default_keys[keyindex]))
{
this._registeredKeycode = keyindex.substring(1);
let [keycode, modifiers] = keyindex.substring(1).split("_");
egw_registerGlobalShortcut(
parseInt(keycode),
Expand Down
10 changes: 6 additions & 4 deletions api/js/etemplate/Et2Link/Et2LinkTo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,11 @@ export class Et2LinkTo extends Et2InputWidget(LitElement)
this.select._searchNode.select_options = [];
}

handleSlChange(event)
{
this.dispatchEvent(new Event("change", {bubbles: true}));
}

/**
* Files have been uploaded (successfully), ready to link
*
Expand Down Expand Up @@ -578,10 +583,7 @@ export class Et2LinkTo extends Et2InputWidget(LitElement)
})}
>
${labelTemplate}
<div part="form-control-input" class="form-control-input" @sl-change=${() =>
{
this.dispatchEvent(new Event("change", {bubbles: true}));
}}>
<div part="form-control-input" class="form-control-input" @sl-change=${this.handleSlChange}>
${this._inputGroupBeforeTemplate()}
${this._inputGroupInputTemplate()}
</div>
Expand Down
9 changes: 8 additions & 1 deletion api/js/etemplate/Et2Select/Et2WidgetWithSelectMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {et2_readAttrWithDefault} from "../et2_core_xml";
import {cleanSelectOptions, find_select_options, SelectOption} from "./FindSelectOptions";

import {SearchMixinInterface} from "../Et2Widget/SearchMixin";
import {repeat} from "lit/directives/repeat.js";

/**
* @summary Base class for things that do selectbox type behaviour, to avoid putting too much or copying into read-only
Expand Down Expand Up @@ -130,6 +131,12 @@ export const Et2WidgetWithSelectMixin = <T extends Constructor<LitElement>>(supe
this.__select_options = <SelectOption[]>[];
}

destroy()
{
super.destroy && super.destroy();
this.__select_options = [];
this._xmlOptions = [];
}
async getUpdateComplete() : Promise<boolean>
{
const result = await super.getUpdateComplete();
Expand Down Expand Up @@ -291,7 +298,7 @@ export const Et2WidgetWithSelectMixin = <T extends Constructor<LitElement>>(supe
const options = Array.isArray(option.value) ? <SelectOption[]>option.value : <SelectOption[]>option.children;
return html`
<small>${this.noLang ? option.label : this.egw().lang(option.label)}</small>
${options.map(this._optionTemplate.bind(this))}
${repeat(options, o => o.value, this._optionTemplate)}
<sl-divider></sl-divider>
`;
}
Expand Down
4 changes: 4 additions & 0 deletions api/js/etemplate/Et2Select/SearchMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ export const Et2WithSearchMixin = dedupeMixin(<T extends Constructor<LitElement>
{
super.disconnectedCallback();
this._unbindListeners();

while(this.lastChild) this.lastChild.remove();
this._selected_remote = [];
this._remote_options = [];
}

async getUpdateComplete()
Expand Down
10 changes: 10 additions & 0 deletions api/js/etemplate/Et2Select/Select/Et2SelectCategory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ export class Et2SelectCategory extends Et2StaticSelectMixin(Et2TreeDropdown)
});
}

disconnectedCallback()
{
super.disconnectedCallback();
const box = this.shadowRoot?.querySelector('.tree-dropdown__combobox');
if(box)
{
this.egw().tooltipUnbind(box, this.egw().lang(this.statustext));
}
}

bindTooltip()
{
//overide so tooltip wont be bound
Expand Down
6 changes: 6 additions & 0 deletions api/js/etemplate/Et2Select/SelectAccountMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ export const SelectAccountMixin = <T extends Constructor<LitElement>>(superclass
this.account_options = [];
}

disconnectedCallback()
{
super.disconnectedCallback && super.disconnectedCallback();
this.account_options = [];
}

/**
* If the value has an account that's not already in the list, check with the server.
* We probably don't have all the accounts client side. This is similar to freeEntries,
Expand Down
5 changes: 5 additions & 0 deletions api/js/etemplate/Et2Select/StaticOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ export const Et2StaticSelectMixin = <T extends Constructor<Et2WidgetWithSelect>>
@state()
protected fetchComplete : Promise<SelectOption[] | void> = Promise.resolve();

disconnectedCallback()
{
super.disconnectedCallback();
this._static_options = [];
}
async getUpdateComplete() : Promise<boolean>
{
const result = await super.getUpdateComplete();
Expand Down
6 changes: 6 additions & 0 deletions api/js/etemplate/Et2Textbox/Et2Number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ export class Et2Number extends Et2Textbox
}
}

disconnectedCallback()
{
super.disconnectedCallback();
while(this.lastChild) this.lastChild.remove();
}

firstUpdated()
{
super.firstUpdated();
Expand Down
3 changes: 3 additions & 0 deletions api/js/etemplate/Et2Widget/Et2Widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,9 @@ const Et2WidgetMixin = <T extends Constructor>(superClass : T) =>
**/
destroy()
{
// Clear any deferred properties, functions may live in here
this._deferred_properties = {};

// Not really needed, use the disconnectedCallback() and let the browser handle it

// Call the destructor of all children so any legacy widgets get destroyed
Expand Down
1 change: 1 addition & 0 deletions api/js/etemplate/et2_widget_file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export class et2_file extends et2_inputWidget
{
super.destroy();
this.set_drop_target(null);
this.disabled_buttons = null;
this.node = null;
this.input = null;
this.span = null;
Expand Down
1 change: 1 addition & 0 deletions api/js/jsapi/egw_core.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
{
if (_cond(_arr[i]))
{
_arr[i].instance && _arr[i].instance.unregisterAllPlugins();
_arr.splice(i, 1);
}
}
Expand Down
7 changes: 7 additions & 0 deletions api/js/jsapi/egw_json.js
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,13 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
}
}
}
},
unregisterAllPlugins: function ()
{
for (const type of Object.getOwnPropertyNames(plugins))
{
delete plugins[type];
}
}
};

Expand Down
18 changes: 11 additions & 7 deletions api/js/jsapi/egw_message.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,18 @@ egw.extend('message', egw.MODULE_WND_LOCAL, function(_app, _wnd)
// keeps alive messages stored
var alive_messages = [];
// Register an 'error' plugin, displaying using the message system
this.registerJSONPlugin(function(type, res, req) {
if (typeof res.data == 'string')
window.setTimeout(() =>
{
egw(_wnd).registerJSONPlugin(function (type, res, req)
{
egw.message(res.data,'error');
return true;
}
throw 'Invalid parameters';
}, null, 'error');
if (typeof res.data == 'string')
{
egw.message(res.data, 'error');
return true;
}
throw 'Invalid parameters';
}, null, 'error');
}, 0);

/**
* Decode html entities so they can be added via .text(_str), eg. html_entity_decode('&amp;') === '&'
Expand Down

0 comments on commit 389a8ee

Please sign in to comment.