@yuneta/gobj-js 7.16.5 → 7.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4022,10 +4022,18 @@ var gobjJs = (function(exports) {
4022
4022
  - list of strings [s,...]
4023
4023
  - list of dicts [{},...]
4024
4024
  - dict of dicts {id:{},...}
4025
- return a **NEW** list of incref (clone) kw filtering the rows by `jn_filter` (where),
4026
- and matching the ids.
4027
- If match_fn is 0 then kw_match_simple is used.
4028
- NOTE Using JSON_INCREF/JSON_DECREF HACK
4025
+ return a NEW list holding the rows that match `ids` and the
4026
+ `jn_filter` (where). If match_fn is 0 then kw_match_simple is used.
4027
+
4028
+ WARNING the LIST is new; its elements are THE SAME objects, not
4029
+ copies. The C twin increfs each one and says "clone", which this
4030
+ comment repeated for years: javascript has no refcount, so a write
4031
+ through a collected row writes into `kw`. Copy what you mean to
4032
+ modify.
4033
+
4034
+ Returns null -- not an empty list -- for a `kw` that is neither a
4035
+ list nor a dict, so a caller that reads `.length` off the answer
4036
+ must check it first (kwid_find_one_record does).
4029
4037
  *************************************************************/
4030
4038
  function kwid_collect(gobj, kw, ids, jn_filter, match_fn) {
4031
4039
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
@@ -4054,12 +4062,17 @@ var gobjJs = (function(exports) {
4054
4062
  }
4055
4063
  /*************************************************************
4056
4064
  Utility for databases.
4057
- Return a new dict from a "dict of records" or "list of records"
4058
- WARNING the "id" of a dict's record is hardcorded to their key.
4065
+ Return a dict from a "dict of records" or "list of records".
4066
+ WARNING the "id" of a dict's record is hardcoded to its key.
4059
4067
  Convention:
4060
- - all arrays are list of records (dicts) with "id" field as primary key
4068
+ - all arrays are lists of records (dicts) with "id" as primary key
4061
4069
  - delimiter is '`' and '.'
4062
4070
  If path is empty then use kw
4071
+
4072
+ WARNING "new" is the C twin's word, where it means a new REFERENCE:
4073
+ handed a dict, both return THAT dict and not a copy of it. Only the
4074
+ list case builds something new, and even then the records inside it
4075
+ are the same objects.
4063
4076
  *************************************************************/
4064
4077
  function kwid_new_dict(gobj, kw, path) {
4065
4078
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
@@ -4068,20 +4081,59 @@ var gobjJs = (function(exports) {
4068
4081
  if (is_object(kw)) new_dict = kw;
4069
4082
  else if (is_array(kw)) for (let i = 0; i < kw.length; i++) {
4070
4083
  let kv = kw[i];
4071
- let id = kw_get_str(gobj, kv, "id", "", 0);
4084
+ let id = kw_get_str(gobj, kv, "id", "", kw_flag_t.KW_REQUIRED);
4072
4085
  if (!empty_string(id)) new_dict[id] = kv;
4073
4086
  }
4074
4087
  else log_error(`${gobj_short_name(gobj)} kwid_new_dict: data type unknown`);
4075
4088
  return new_dict;
4076
4089
  }
4077
4090
  /*************************************************************
4091
+ Utility for databases.
4092
+ Return a list from a "dict of records" or "list of records".
4093
+ The NORMALIZING function of this family: whatever shape the data
4094
+ arrives in, what comes back is the shape a table indexed and
4095
+ sorted by `id` wants.
4096
+ Convention:
4097
+ - all arrays are lists of records (dicts) with "id" as primary key
4098
+ - delimiter is '`' and '.'
4099
+ If path is empty then use kw
4100
+
4101
+ WARNING handed a DICT it writes each record's key into the record
4102
+ as its `id`, OVERWRITING one that differs -- in the source records,
4103
+ which it does not copy. That is the C twin's behaviour
4104
+ (`json_object_set_new(v, "id", ...)` in kwid.c) and it is the point:
4105
+ a dict keyed by id whose records disagree with their own key is
4106
+ exactly what this is for. Handed a LIST it returns that same list,
4107
+ untouched, as C returns a new reference to it.
4108
+ *************************************************************/
4109
+ function kwid_new_list(gobj, kw, path) {
4110
+ if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
4111
+ if (!empty_string(path)) kw = kw_find_path(gobj, kw, path);
4112
+ if (is_array(kw)) return kw;
4113
+ if (is_object(kw)) {
4114
+ let new_list = [];
4115
+ for (let id of Object.keys(kw)) {
4116
+ let record = kw[id];
4117
+ if (!is_object(record)) {
4118
+ log_error(`${gobj_short_name(gobj)} kwid_new_list: not a record: '${id}'`);
4119
+ continue;
4120
+ }
4121
+ record["id"] = id;
4122
+ new_list.push(record);
4123
+ }
4124
+ return new_list;
4125
+ }
4126
+ log_error(`${gobj_short_name(gobj)} kwid_new_list: wrong type for list`);
4127
+ return [];
4128
+ }
4129
+ /*************************************************************
4078
4130
  * Utility for databases. See kwid_collect parameters
4079
4131
  *************************************************************/
4080
4132
  function kwid_find_one_record(gobj, kw, ids, jn_filter, match_fn) {
4081
4133
  if (gobj && !is_gobj(gobj)) log_error(`GObj bad instanceof`);
4082
4134
  let list = kwid_collect(gobj, kw, ids, jn_filter, match_fn);
4083
- if (list.length > 0) return list[0];
4084
- else return null;
4135
+ if (!list || list.length === 0) return null;
4136
+ return list[0];
4085
4137
  }
4086
4138
  /*************************************************************
4087
4139
  Utility for databases.
@@ -4946,7 +4998,13 @@ var gobjJs = (function(exports) {
4946
4998
  return;
4947
4999
  }
4948
5000
  if (!element) element = document;
4949
- element.querySelectorAll("[data-i18n]").forEach(function(elem) {
5001
+ const matching = (selector) => {
5002
+ let out = [];
5003
+ if (typeof element.matches === "function" && element.matches(selector)) out.push(element);
5004
+ out.push(...element.querySelectorAll(selector));
5005
+ return out;
5006
+ };
5007
+ matching("[data-i18n]").forEach(function(elem) {
4950
5008
  let value = elem.getAttribute("data-i18n");
4951
5009
  for (let node of elem.childNodes) if (node.nodeType === Node.TEXT_NODE) {
4952
5010
  if (!value) value = node.nodeValue;
@@ -4954,15 +5012,15 @@ var gobjJs = (function(exports) {
4954
5012
  break;
4955
5013
  }
4956
5014
  });
4957
- element.querySelectorAll("[data-i18n-title]").forEach(function(elem) {
5015
+ matching("[data-i18n-title]").forEach(function(elem) {
4958
5016
  let value = elem.getAttribute("data-i18n-title");
4959
5017
  if (value) elem.setAttribute("title", t(value));
4960
5018
  });
4961
- element.querySelectorAll("[data-i18n-aria-label]").forEach(function(elem) {
5019
+ matching("[data-i18n-aria-label]").forEach(function(elem) {
4962
5020
  let value = elem.getAttribute("data-i18n-aria-label");
4963
5021
  if (value) elem.setAttribute("aria-label", t(value));
4964
5022
  });
4965
- element.querySelectorAll("[data-i18n-placeholder]").forEach(function(elem) {
5023
+ matching("[data-i18n-placeholder]").forEach(function(elem) {
4966
5024
  let value = elem.getAttribute("data-i18n-placeholder");
4967
5025
  if (value) elem.setAttribute("placeholder", t(value));
4968
5026
  });
@@ -7123,6 +7181,7 @@ var gobjJs = (function(exports) {
7123
7181
  exports.kwid_get_ids = kwid_get_ids;
7124
7182
  exports.kwid_match_id = kwid_match_id;
7125
7183
  exports.kwid_new_dict = kwid_new_dict;
7184
+ exports.kwid_new_list = kwid_new_list;
7126
7185
  exports.list2options = list2options;
7127
7186
  exports.load_json_file = load_json_file;
7128
7187
  exports.log_debug = log_debug;