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