Deal with some IDE warnings

better documentation of things tried
This commit is contained in:
nathan 2022-01-05 13:14:28 -07:00
parent 7ab60918f4
commit 4ed888476c
3 changed files with 216 additions and 119 deletions

View File

@ -45,6 +45,18 @@ export class Et2SelectReadonly extends Et2Widget(LitElement) implements et2_IDet
transformAttributes(_attrs)
{
/*
TODO: Check with more / different nextmatch data to see if this becomes faster.
Currently it's faster for the nextmatch to re-do transformAttributes() and find_select_options()
on every row than it is to use widget.clone()
// If there's no parent, there's a good chance we're in a nextmatch row so skip the transform
if(!this.getParent())
{
return;
}
*/
super.transformAttributes(_attrs);
let sel_options = find_select_options(this, _attrs['select_options'], _attrs);

View File

@ -41,11 +41,13 @@ const Et2WidgetMixin = (superClass) =>
class Et2WidgetClass extends superClass implements et2_IDOMNode
{
/** et2_widget compatability **/
protected _mgrs : et2_arrayMgr[] = [];
protected _parent : Et2WidgetClass | et2_widget | null = null;
private _inst : etemplate2 | null = null;
private supportedWidgetClasses = [];
/** et2_widget compatability **/
// @ts-ignore Some legacy widgets check their parent to see whats allowed
public supportedWidgetClasses = [];
/**
* If we put the widget somewhere other than as a child of its parent, we need to record that so
@ -297,7 +299,6 @@ const Et2WidgetMixin = (superClass) =>
*/
set id(value)
{
let oldValue = this._widget_id;
this._widget_id = value;
let dom_id = "";
if(this._widget_id)
@ -358,7 +359,7 @@ const Et2WidgetMixin = (superClass) =>
if(typeof this.onclick == 'function')
{
// Make sure function gets a reference to the widget, splice it in as 2. argument if not
var args = Array.prototype.slice.call(arguments);
let args = Array.prototype.slice.call(arguments);
if(args.indexOf(this) == -1)
{
args.splice(1, 0, this);
@ -390,10 +391,10 @@ const Et2WidgetMixin = (superClass) =>
loadFromXML(_node)
{
// Load the child nodes.
for(var i = 0; i < _node.childNodes.length; i++)
for(let i = 0; i < _node.childNodes.length; i++)
{
var node = _node.childNodes[i];
var widgetType = node.nodeName.toLowerCase();
let node = _node.childNodes[i];
let widgetType = node.nodeName.toLowerCase();
if(widgetType == "#comment")
{
@ -430,7 +431,7 @@ const Et2WidgetMixin = (superClass) =>
*/
createElementFromNode(_node, _name?)
{
var attributes = {};
let attributes = {};
// Parse the "readonly" and "type" flag for this element here, as they
// determine which constructor is used
@ -442,7 +443,7 @@ const Et2WidgetMixin = (superClass) =>
typeof this.readonly !== "undefined" ? this.readonly : false) : false;
// Check to see if modifications change type
var modifications = this.getArrayMgr("modifications");
let modifications = this.getArrayMgr("modifications");
if(modifications && _node.getAttribute("id"))
{
let entry : any = modifications.getEntry(_node.getAttribute("id"));
@ -475,12 +476,12 @@ const Et2WidgetMixin = (superClass) =>
_nodeName = attributes["type"] = this.getArrayMgr('content').expandName(_nodeName);
}
let widget = null;
let widget;
if(undefined == window.customElements.get(_nodeName))
{
// Get the constructor - if the widget is readonly, use the special "_ro"
// constructor if it is available
var constructor = et2_registry[typeof et2_registry[_nodeName] == "undefined" ? 'placeholder' : _nodeName];
let constructor = et2_registry[typeof et2_registry[_nodeName] == "undefined" ? 'placeholder' : _nodeName];
if(readonly === true && typeof et2_registry[_nodeName + "_ro"] != "undefined")
{
constructor = et2_registry[_nodeName + "_ro"];
@ -522,6 +523,9 @@ const Et2WidgetMixin = (superClass) =>
* and adds the given attributes to the _target associative array. This
* function also parses the legacyOptions.
*
* N.B. This is only used for legacy widgets. WebComponents use transformAttributes() and
* do their own handling of attributes.
*
* @param _attrsObj is the XML DOM attributes object
* @param {object} _target is the object to which the attributes should be written.
* @param {et2_widget} _proto prototype with attributes and legacyOptions attribute
@ -535,22 +539,21 @@ const Et2WidgetMixin = (superClass) =>
}
// Iterate over the given attributes and parse them
var mgr = this.getArrayMgr("content");
for(var i = 0; i < _attrsObj.length; i++)
let mgr = this.getArrayMgr("content");
for(let i = 0; i < _attrsObj.length; i++)
{
var attrName = _attrsObj[i].name;
var attrValue = _attrsObj[i].value;
let attrName = _attrsObj[i].name;
let attrValue = _attrsObj[i].value;
// Special handling for the legacy options
if(attrName == "options" && _proto.constructor.legacyOptions && _proto.constructor.legacyOptions.length > 0)
{
let legacy = _proto.constructor.legacyOptions || [];
let attrs = et2_attribute_registry[Object.getPrototypeOf(_proto).constructor.name] || {};
// Check for modifications on legacy options here. Normal modifications
// are handled in widget constructor, but it's too late for legacy options then
if(_target.id && this.getArrayMgr("modifications").getEntry(_target.id))
{
var mod : any = this.getArrayMgr("modifications").getEntry(_target.id);
let mod : any = this.getArrayMgr("modifications").getEntry(_target.id);
if(typeof mod.options != "undefined")
{
attrValue = _attrsObj[i].value = mod.options;
@ -563,9 +566,9 @@ const Et2WidgetMixin = (superClass) =>
}
// Parse the legacy options (as a string, other types not allowed)
var splitted = et2_csvSplit(attrValue + "");
let splitted = et2_csvSplit(attrValue + "");
for(var j = 0; j < splitted.length && j < legacy.length; j++)
for(let j = 0; j < splitted.length && j < legacy.length; j++)
{
// Blank = not set, unless there's more legacy options provided after
if(splitted[j].trim().length === 0 && legacy.length >= splitted.length)
@ -587,7 +590,7 @@ const Et2WidgetMixin = (superClass) =>
attrValue = splitted.slice(j);
}
var attr = et2_attribute_registry[_proto.constructor.name][legacy[j]] || {};
let attr = et2_attribute_registry[_proto.constructor.name][legacy[j]] || {};
// If the attribute is marked as boolean, parse the
// expression as bool expression.
@ -612,7 +615,7 @@ const Et2WidgetMixin = (superClass) =>
let attrs = et2_attribute_registry[_proto.constructor.name] || {};
if(mgr != null && typeof attrs[attrName] != "undefined")
{
var attr = attrs[attrName];
let attr = attrs[attrName];
// If the attribute is marked as boolean, parse the
// expression as bool expression.
@ -673,9 +676,11 @@ const Et2WidgetMixin = (superClass) =>
* rest themselves with their normal lifecycle (especially connectedCallback(), which is kind
* of the equivalent of doLoadingFinished()
*/
// @ts-ignore this is not an et2_widget, so getDOMNode(this) is bad
if(!this._parent_node && this.getParent() instanceof et2_widget && (<et2_DOMWidget>this.getParent()).getDOMNode(this) != this.parentNode)
{
this.getParent().getDOMNode(this).append(this);
// @ts-ignore this is not an et2_widget, and Et2Widget is not a Node
(<et2_DOMWidget>this.getParent()).getDOMNode(this).append(this);
}
// An empty text node causes problems with legacy widget children
@ -708,9 +713,9 @@ const Et2WidgetMixin = (superClass) =>
let check_children = children =>
{
for(var i = 0; i < children.length; i++)
for(let i = 0; i < children.length; i++)
{
var elem = children[i].getWidgetById(_id);
let elem = children[i].getWidgetById(_id);
if(elem != null)
{
@ -719,9 +724,9 @@ const Et2WidgetMixin = (superClass) =>
}
if(this.id && _id.indexOf('[') > -1 && children.length)
{
var ids = (new et2_arrayMgr()).explodeKey(_id);
var widget : Et2WidgetClass = this;
for(var i = 0; i < ids.length && widget !== null; i++)
let ids = (new et2_arrayMgr()).explodeKey(_id);
let widget : Et2WidgetClass = this;
for(let i = 0; i < ids.length && widget !== null; i++)
{
widget = widget.getWidgetById(ids[i]);
}
@ -746,7 +751,7 @@ const Et2WidgetMixin = (superClass) =>
}
if(parent)
{
parent.append(this);
parent.append(<Node><unknown>this);
this._parent_node = parent;
}
}
@ -763,14 +768,12 @@ const Et2WidgetMixin = (superClass) =>
this.checkCreateNamespace();
}
}
// @ts-ignore
this._parent.addChild(this);
}
getParent() : Et2WidgetClass | et2_widget
{
let parentNode = this.parentNode;
// If parent is an old et2_widget, use it
if(this._parent)
{
return this._parent;
@ -787,6 +790,9 @@ const Et2WidgetMixin = (superClass) =>
}
if(child instanceof et2_widget)
{
// Type of et2_widget._parent is et2_widget, not Et2Widget. This might cause problems, but they
// should be fixed by getting rid of the legacy widget with problems
// @ts-ignore
child._parent = this;
// During legacy widget creation, the child's DOM node won't be available yet.
@ -794,6 +800,7 @@ const Et2WidgetMixin = (superClass) =>
let child_node = null;
try
{
//@ts-ignore Technically getDOMNode() is from et2_DOMWidget
child_node = typeof child.getDOMNode !== "undefined" ? child.getDOMNode(child) : null;
}
catch(e)
@ -846,7 +853,7 @@ const Et2WidgetMixin = (superClass) =>
}
// Create the copy
var copy = <Et2WidgetClass>this.cloneNode();
let copy = <Et2WidgetClass>this.cloneNode();
copy.id = this._widget_id;
if(_parent)
@ -870,7 +877,7 @@ const Et2WidgetMixin = (superClass) =>
}
// Create a clone of all child widgets of the given object
for(var i = 0; i < this.getChildren().length; i++)
for(let i = 0; i < this.getChildren().length; i++)
{
this.getChildren()[i].clone(copy);
}
@ -934,7 +941,7 @@ const Et2WidgetMixin = (superClass) =>
// Add all managers of this object to the result, if they have not already
// been set in the result
for(var key in this._mgrs)
for(let key in this._mgrs)
{
if(typeof _mgrs[key] == "undefined")
{
@ -961,11 +968,11 @@ const Et2WidgetMixin = (superClass) =>
checkCreateNamespace()
{
// Get the content manager
var mgrs = this.getArrayMgrs();
let mgrs = this.getArrayMgrs();
for(var key in mgrs)
for(let key in mgrs)
{
var mgr = mgrs[key];
let mgr = mgrs[key];
// Get the original content manager if we have already created a
// perspective for this node
@ -975,7 +982,7 @@ const Et2WidgetMixin = (superClass) =>
}
// Check whether the manager has a namespace for the id of this object
var entry = mgr.getEntry(this.id);
let entry = mgr.getEntry(this.id);
if(typeof entry === 'object' && entry !== null || this.id)
{
// The content manager has an own node for this object, so
@ -1042,7 +1049,7 @@ const Et2WidgetMixin = (superClass) =>
*/
getPath()
{
var path = this.getArrayMgr("content")?.getPath() ?? [];
let path = this.getArrayMgr("content")?.getPath() ?? [];
// Prevent namespaced widgets with value from going an extra layer deep
if(this.id && this._createNamespace() && path[path.length - 1] == this.id)
@ -1066,11 +1073,11 @@ const Et2WidgetMixin = (superClass) =>
}
// Get the window this object belongs to
var wnd = null;
let wnd = null;
// @ts-ignore Technically this doesn't have implements(), but it's mixed in
if(this.implements(et2_IDOMNode))
{
var node = (<et2_IDOMNode><unknown>this).getDOMNode();
let node = (<et2_IDOMNode><unknown>this).getDOMNode();
if(node && node.ownerDocument)
{
wnd = node.ownerDocument.parentNode || node.ownerDocument.defaultView;
@ -1080,7 +1087,7 @@ const Et2WidgetMixin = (superClass) =>
// If we're the root object, return the phpgwapi API instance
return typeof egw === "function" ? egw('phpgwapi', wnd) : null;
}
};
}
// Add some more stuff in
applyMixins(Et2WidgetClass, [ClassWithInterfaces]);
@ -1093,7 +1100,9 @@ export const Et2Widget = dedupeMixin(Et2WidgetMixin);
* Load a Web Component
* @param _nodeName
* @param _template_node
* @param parent Parent widget
*/
// @ts-ignore Et2Widget is I guess not the right type
export function loadWebComponent(_nodeName : string, _template_node, parent : Et2Widget | et2_widget) : HTMLElement
{
// @ts-ignore
@ -1106,7 +1115,6 @@ export function loadWebComponent(_nodeName : string, _template_node, parent : Et
throw Error("Unknown or unregistered WebComponent '" + _nodeName + "', could not find class");
}
widget.setParent(parent);
var mgr = widget.getArrayMgr("content");
// Set read-only. Doesn't really matter if it's a ro widget, but otherwise it needs set
widget.readOnly = parent.getArrayMgr("readonlys") ?
@ -1222,7 +1230,8 @@ function transformAttributes(widget, mgr : et2_arrayMgr, attributes)
* }
* `];
* }
* @param image_name
* @param image_name Name of the image
* @param app_name Optional, image is from an app instead of api
* @returns {CSSResult}
*/
export function cssImage(image_name : string, app_name? : string)

View File

@ -26,17 +26,17 @@ import {et2_compilePHPExpression} from "./et2_core_phpExpressionCompiler";
*/
export class et2_arrayMgr
{
splitIds: boolean = true;
public data: object;
splitIds : boolean = true;
public data : object;
// Holds information about the current perspective
public perspectiveData: { owner: et2_widget; row: number; key: string } = {
public perspectiveData : { owner : et2_widget; row : number; key : string } = {
"owner": null,
"key": null,
"row": null
};
protected static compiledExpressions: object = {};
private readonly _parentMgr: et2_arrayMgr;
protected readOnly: boolean = false;
protected static compiledExpressions : object = {};
private readonly _parentMgr : et2_arrayMgr;
protected readOnly : boolean = false;
/**
* Constructor
@ -45,8 +45,10 @@ export class et2_arrayMgr
* @param _data
* @param _parentMgr
*/
constructor(_data: object = {}, _parentMgr?: et2_arrayMgr) {
if (typeof _parentMgr == "undefined") {
constructor(_data : object = {}, _parentMgr? : et2_arrayMgr)
{
if(typeof _parentMgr == "undefined")
{
_parentMgr = null;
}
@ -55,7 +57,8 @@ export class et2_arrayMgr
this._parentMgr = _parentMgr;
// Hold a reference to the data
if (typeof _data == "undefined" || !_data) {
if(typeof _data == "undefined" || !_data)
{
egw.debug("log", "No data passed to content array manager. Probably a mismatch between template namespaces and data.");
_data = {};
}
@ -63,19 +66,24 @@ export class et2_arrayMgr
// Expand sub-arrays that have been shmushed together, so further perspectives work
// Shmushed keys look like: ${row}[info_cat]
// Expanded: ${row}: Object{info_cat: ..value}
if (this.splitIds) {
if(this.splitIds)
{
// For each index, we need a key: {..} sub array
for (let key in _data) {
for(let key in _data)
{
// Split up indexes
const indexes = key.replace(/&#x5B;/g, "[").split('[');
// Put data in the proper place
if (indexes.length > 1) {
if(indexes.length > 1)
{
const value = _data[key];
let target = _data;
for (let i = 0; i < indexes.length; i++) {
for(let i = 0; i < indexes.length; i++)
{
indexes[i] = indexes[i].replace(/&#x5D;/g, '').replace(']', '');
if (typeof target[indexes[i]] == "undefined" || target[indexes[i]] === null) {
if(typeof target[indexes[i]] == "undefined" || target[indexes[i]] === null)
{
target[indexes[i]] = i == indexes.length - 1 ? value : {};
}
target = target[indexes[i]];
@ -91,27 +99,33 @@ export class et2_arrayMgr
/**
* Returns the root content array manager object
*/
getRoot(): et2_arrayMgr {
if (this._parentMgr != null) {
getRoot() : et2_arrayMgr
{
if(this._parentMgr != null)
{
return this._parentMgr.getRoot();
}
return this;
}
getParentMgr(): et2_arrayMgr {
getParentMgr() : et2_arrayMgr
{
return this._parentMgr;
}
getPerspectiveData(): { owner: et2_widget; row: number; key: string } {
getPerspectiveData() : { owner : et2_widget; row : number; key : string }
{
return this.perspectiveData;
}
setPerspectiveData(new_perspective: { owner: et2_widget; row: number; key: string }) {
setPerspectiveData(new_perspective : { owner : et2_widget; row : number; key : string })
{
this.perspectiveData = new_perspective;
}
setRow(new_row: number) {
setRow(new_row : number)
{
this.perspectiveData.row = new_row;
}
@ -127,21 +141,28 @@ export class et2_arrayMgr
*
* @return {string[]}
*/
explodeKey(_key: string): string[] {
if(!_key || typeof _key == 'string' && _key.trim() === "") return [];
explodeKey(_key : string) : string[]
{
if(!_key || typeof _key == 'string' && _key.trim() === "")
{
return [];
}
// Parse the given key by removing the "]"-chars and splitting at "["
let indexes = [_key];
if (typeof _key === "string") {
if(typeof _key === "string")
{
_key = _key.replace(/&#x5B;/g, "[").replace(/&#x5D;/g, "]");
indexes = _key.split('[');
}
if (indexes.length > 1) {
if(indexes.length > 1)
{
indexes = [indexes.shift(), indexes.join('[')];
indexes[1] = indexes[1].substring(0, indexes[1].length - 1);
const children = indexes[1].split('][');
if (children.length) {
if(children.length)
{
indexes = jQuery.merge([indexes[0]], children);
}
}
@ -154,17 +175,21 @@ export class et2_arrayMgr
*
* @param _path is used internally, do not supply it manually.
*/
getPath(_path?: string[]): string[] {
if (typeof _path == "undefined") {
getPath(_path? : string[]) : string[]
{
if(typeof _path == "undefined")
{
_path = [];
}
if (this.perspectiveData.key != null) {
if(this.perspectiveData.key != null)
{
// prepend components of this.perspectiveData.key to path, can be more then one eg. "nm[rows]"
_path = this.perspectiveData.key.replace(/]/g, '').split('[').concat(_path);
}
if (this._parentMgr != null) {
if(this._parentMgr != null)
{
_path = this._parentMgr.getPath(_path);
}
@ -182,31 +207,40 @@ export class et2_arrayMgr
* @param _skipEmpty returns null if _key is not present in this content array.
* Defaults to false.
*/
getEntry(_key: string, _referenceInto?: boolean, _skipEmpty?: boolean): any {
if (typeof _referenceInto == "undefined") {
getEntry(_key : string, _referenceInto? : boolean, _skipEmpty? : boolean) : any
{
if(typeof _referenceInto == "undefined")
{
_referenceInto = false;
}
if (typeof _skipEmpty == "undefined") {
if(typeof _skipEmpty == "undefined")
{
_skipEmpty = false;
}
// Parse the given key by removing the "]"-chars and splitting at "["
const indexes = this.explodeKey(_key);
if(indexes.length == 0 && _skipEmpty) return null;
if(indexes.length == 0 && _skipEmpty)
{
return null;
}
let entry = this.data;
for (let i = 0; i < indexes.length; i++) {
for(let i = 0; i < indexes.length; i++)
{
// Abort if the current entry is not an object (associative array) and
// we should descend further into it.
const isObject = typeof entry === 'object';
if (!isObject && !_referenceInto || entry == null || jQuery.isEmptyObject(entry)) {
if(!isObject && !_referenceInto || entry == null || jQuery.isEmptyObject(entry))
{
return null;
}
// Check whether the entry actually exists
const idx = indexes[i];
if (_skipEmpty && (!isObject || typeof entry[idx] == "undefined")) {
if(_skipEmpty && (!isObject || typeof entry[idx] == "undefined"))
{
return null;
}
@ -225,16 +259,18 @@ export class et2_arrayMgr
* @param {string} _ident Key used to reference into managed array
* @return {*}
*/
expandName(_ident: string): string | object {
expandName(_ident : string) : string | object
{
// Check whether the identifier refers to an index in the content array
const is_index_in_content = _ident.charAt(0) == '@';
// Check whether "$" occurs in the given identifier
const pos_var = _ident.indexOf('$');
if (pos_var >= 0 && (this.perspectiveData.row != null || !_ident.match(/\$\{?row\}?/))
if(pos_var >= 0 && (this.perspectiveData.row != null || !_ident.match(/\$\{?row\}?/))
// Avoid messing with regex in validators
&& pos_var !== _ident.indexOf("$/")
) {
)
{
// Get the content array for the current row
const row = typeof this.perspectiveData.row == 'number' ? this.perspectiveData.row : '';
const row_cont = this.data[row] || {};
@ -245,19 +281,26 @@ export class et2_arrayMgr
// Check whether the expression has already been compiled - if not,
// try to compile it first. If an error occurs, the identifier
// function is set to null
if (typeof et2_arrayMgr.compiledExpressions[_ident] == "undefined") {
try {
if (this.perspectiveData.row == null) {
if(typeof et2_arrayMgr.compiledExpressions[_ident] == "undefined")
{
try
{
if(this.perspectiveData.row == null)
{
// No row, compile for only top level content
// @ts-ignore
et2_arrayMgr.compiledExpressions[_ident] = et2_compilePHPExpression(
_ident, ["cont", "_cont"]);
} else {
}
else
{
// @ts-ignore
et2_arrayMgr.compiledExpressions[_ident] = et2_compilePHPExpression(
_ident, ["row", "cont", "row_cont", "_cont"]);
}
} catch (e) {
}
catch(e)
{
et2_arrayMgr.compiledExpressions[_ident] = null;
egw.debug("error", "Error while compiling PHP->JS ", e);
}
@ -266,15 +309,22 @@ export class et2_arrayMgr
// Execute the previously compiled expression, if it is not "null"
// because compilation failed. The parameters have to be in the same
// order as defined during compilation.
if (et2_arrayMgr.compiledExpressions[_ident]) {
try {
if (this.perspectiveData.row == null) {
if(et2_arrayMgr.compiledExpressions[_ident])
{
try
{
if(this.perspectiveData.row == null)
{
// No row, exec with only top level content
_ident = et2_arrayMgr.compiledExpressions[_ident](cont, _cont);
} else {
}
else
{
_ident = et2_arrayMgr.compiledExpressions[_ident](row, cont, row_cont, _cont);
}
} catch (e) {
}
catch(e)
{
// only log error, as they are no real errors but missing data
egw.debug("log", typeof e == 'object' ? e.message : e);
_ident = null;
@ -282,12 +332,16 @@ export class et2_arrayMgr
}
}
if (is_index_in_content && _ident) {
if(is_index_in_content && _ident)
{
// If an additional "@" is specified, this means that we have to return
// the entry from the root element
if (_ident.charAt(1) == '@') {
if(_ident.charAt(1) == '@')
{
return this.getRoot().getEntry(_ident.substr(2));
} else {
}
else
{
return this.getEntry(_ident.substr(1));
}
}
@ -295,10 +349,12 @@ export class et2_arrayMgr
return _ident;
}
parseBoolExpression(_expression: string) {
parseBoolExpression(_expression : string)
{
// If the first char of the expression is a '!' this means, that the value
// is to be negated.
if (_expression.charAt(0) == '!') {
if(_expression.charAt(0) == '!')
{
return !this.parseBoolExpression(_expression.substr(1));
}
@ -310,13 +366,15 @@ export class et2_arrayMgr
val = (typeof val == "undefined" || val === null) ? '' : '' + val;
// If a second expression existed, test that one
if (typeof parts[1] != "undefined") {
if(typeof parts[1] != "undefined")
{
// Expand the second value
const checkVal = '' + this.expandName(parts[1]);
// Values starting with / are treated as regular expression. It is
// checked whether the first value matches the regular expression
if (checkVal.charAt(0) == '/') {
if(checkVal.charAt(0) == '/')
{
return (new RegExp(checkVal.substr(1, checkVal.length - 2)))
.test(val);
}
@ -335,11 +393,15 @@ export class et2_arrayMgr
* @param {(string|null|object)} _root string with key, null for whole data or object with data
* @param {number?} _row key for into the _root for the desired row
*/
openPerspective(_owner: et2_widget, _root: (string | null | object), _row: number | null): et2_arrayMgr {
openPerspective(_owner : et2_widget, _root : (string | null | object), _row? : number | null) : et2_arrayMgr
{
// Get the root node
let root = typeof _root == "string" ? this.data[_root] :
(_root == null ? this.data : _root);
if (typeof root == "undefined" && typeof _root == "string") root = this.getEntry(_root);
if(typeof root == "undefined" && typeof _root == "string")
{
root = this.getEntry(_root);
}
// Create a new content array manager with the given root
const constructor = this.readOnly ? et2_readonlysArrayMgr : et2_arrayMgr;
@ -349,12 +411,14 @@ export class et2_arrayMgr
mgr.perspectiveData.owner = _owner;
// Set the root key
if (typeof _root == "string") {
if(typeof _root == "string")
{
mgr.perspectiveData.key = _root;
}
// Set _row parameter
if (typeof _row != "undefined") {
if(typeof _row != "undefined")
{
mgr.perspectiveData.row = _row;
}
@ -366,7 +430,8 @@ export class et2_arrayMgr
/**
* @augments et2_arrayMgr
*/
export class et2_readonlysArrayMgr extends et2_arrayMgr {
export class et2_readonlysArrayMgr extends et2_arrayMgr
{
readOnly : boolean = true;
@ -379,36 +444,43 @@ export class et2_readonlysArrayMgr extends et2_arrayMgr {
* @param _parent
* @returns
*/
isReadOnly(_id: string, _attr: string, _parent?: et2_arrayMgr): boolean | string {
isReadOnly(_id : string, _attr : string, _parent? : et2_arrayMgr) : boolean | string
{
let entry = null;
if (_id != null) {
if (_id.indexOf('$') >= 0 || _id.indexOf('@') >= 0) {
if(_id != null)
{
if(_id.indexOf('$') >= 0 || _id.indexOf('@') >= 0)
{
_id = this.expandName(_id);
}
// readonlys was not namespaced in old eTemplate, therefore if we dont find data
// under current namespace, we look into parent
// (if there is anything namespaced, we will NOT look for parent!)
let mgr: et2_arrayMgr = this;
while (mgr.getParentMgr() && jQuery.isEmptyObject(mgr.data)) {
let mgr : et2_arrayMgr = this;
while(mgr.getParentMgr() && jQuery.isEmptyObject(mgr.data))
{
mgr = mgr.getParentMgr();
}
entry = mgr.getEntry(_id);
}
// Let the array entry override the read only attribute entry
if (typeof entry != "undefined" && !(typeof entry === 'object')) {
if(typeof entry != "undefined" && !(typeof entry === 'object'))
{
return entry;
}
// If the attribute is set, return that
if (typeof _attr != "undefined" && _attr !== null) {
if(typeof _attr != "undefined" && _attr !== null)
{
// Accept 'editable', but otherwise boolean
return this.expandName(_attr) === 'editable' ? 'editable' : et2_evalBool(_attr);
}
// Otherwise take into accounf whether the parent is readonly
if (typeof _parent != "undefined" && _parent) {
if(typeof _parent != "undefined" && _parent)
{
return true;
}
@ -426,7 +498,8 @@ export class et2_readonlysArrayMgr extends et2_arrayMgr {
* @param {string} ident Key for searching into the array.
* @returns {*}
*/
expandName(ident: string): any {
expandName(ident : string) : any
{
return this.perspectiveData.owner.getArrayMgr('content').expandName(ident);
}
}
@ -442,15 +515,18 @@ export class et2_readonlysArrayMgr extends et2_arrayMgr {
* existing array managers.
* @param _row is the row for which the array managers will be opened.
*/
export function et2_arrayMgrs_expand(_owner: et2_widget, _mgrs: object, _data: object, _row: number) {
export function et2_arrayMgrs_expand(_owner : et2_widget, _mgrs : object, _data : object, _row : number)
{
// Create a copy of the given _mgrs associative array
let result = {};
// Merge the given data associative array into the existing array managers
for (let key in _mgrs) {
for(let key in _mgrs)
{
result[key] = _mgrs[key];
if (typeof _data[key] != "undefined") {
if(typeof _data[key] != "undefined")
{
// Open a perspective for the given data row
let rowData = {};
rowData[_row] = _data[key];