sdc_client 0.158.9 → 0.160.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.
- package/CHANGELOG.md +58 -0
- package/LICENSE +21 -0
- package/dist/index.js +23 -13
- package/dist/ugly.index.js +2 -1
- package/dist/ugly.index.js.LICENSE.txt +1 -8
- package/gulp/gulp.jsx +11 -36
- package/package.json +23 -12
- package/src/index.js +31 -7
- package/src/simpleDomControl/AbstractSDC.js +15 -11
- package/src/simpleDomControl/sdc_controller.js +3 -3
- package/src/simpleDomControl/sdc_dom_events.js +5 -10
- package/src/simpleDomControl/sdc_events.js +3 -3
- package/src/simpleDomControl/sdc_main.js +34 -13
- package/src/simpleDomControl/sdc_model.js +225 -92
- package/src/simpleDomControl/sdc_params.js +0 -3
- package/src/simpleDomControl/sdc_server_call.js +21 -4
- package/src/simpleDomControl/sdc_test_utils.js +0 -1
- package/src/simpleDomControl/sdc_utils.js +59 -7
- package/src/simpleDomControl/sdc_view.js +16 -1
- package/.github/workflows/node.js.yml +0 -38
- package/.idea/inspectionProfiles/Project_Default.xml +0 -17
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -403
- package/.readthedocs.yaml +0 -13
- package/.tool-versions +0 -1
- package/SimpleDomControlClient.iml +0 -12
- package/docs/api-reference.rst +0 -225
- package/docs/conf.py +0 -11
- package/docs/controllers.rst +0 -228
- package/docs/events-and-dom.rst +0 -120
- package/docs/getting-started.rst +0 -143
- package/docs/index.rst +0 -22
- package/docs/models.rst +0 -351
- package/docs/overview.rst +0 -66
- package/docs/requirements.txt +0 -1
- package/eslint.config.js +0 -43
- package/gulpfile.cjs +0 -30
- package/jest.config.mjs +0 -197
- package/test/controller.test.js +0 -93
- package/test/dist.test.js +0 -127
- package/test/model.test.js +0 -330
- package/test/models/Author.js +0 -145
- package/test/models/Book.js +0 -112
- package/test/models/BookContent.js +0 -114
- package/test/models/SdcUser.js +0 -75
- package/test/models/src.js +0 -8
- package/test/sdc_model_dates.ai.test.js +0 -57
- package/test/sdc_server_call.ai.test.js +0 -267
- package/test/utils.js +0 -88
- package/test/view.test.js +0 -159
- package/test-setup.js +0 -4
- package/webpack.config/webpack.default.config.cjs +0 -14
- package/webpack.config/webpack.development.config.cjs +0 -14
- package/webpack.config/webpack.production.config.cjs +0 -11
|
@@ -6,7 +6,22 @@ let IS_CONNECTING = false;
|
|
|
6
6
|
let SDC_SOCKET = null;
|
|
7
7
|
let OPEN_REQUESTS = {};
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Server methods receive the arguments as keyword arguments, so they must be an
|
|
11
|
+
* object. Other values are passed as ``arg0``.
|
|
12
|
+
*/
|
|
13
|
+
function normalizeArgs(args) {
|
|
14
|
+
if (args === undefined || args === null) {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
if (typeof args !== "object" || Array.isArray(args)) {
|
|
18
|
+
return { arg0: args };
|
|
19
|
+
}
|
|
20
|
+
return args;
|
|
21
|
+
}
|
|
22
|
+
|
|
9
23
|
export function callServer(app, controller, parsedContentUrl, funcName, args) {
|
|
24
|
+
args = normalizeArgs(args);
|
|
10
25
|
if (window.SERVER_CALL_VIA_WEB_SOCKET) {
|
|
11
26
|
return socketCallServer(app, controller, funcName, args);
|
|
12
27
|
} else {
|
|
@@ -29,9 +44,6 @@ export function close() {
|
|
|
29
44
|
}
|
|
30
45
|
|
|
31
46
|
function postCallServer(parsedContentUrl, funcName, args) {
|
|
32
|
-
if (typeof args !== "object" && Array.isArray(args) && args === null) {
|
|
33
|
-
args = { arg0: args };
|
|
34
|
-
}
|
|
35
47
|
args = {
|
|
36
48
|
data: JSON.stringify(args),
|
|
37
49
|
_sdc_func_name: funcName,
|
|
@@ -145,12 +157,17 @@ function _handle_response(data) {
|
|
|
145
157
|
}
|
|
146
158
|
|
|
147
159
|
if (data.type && data.type === "sdc_recall") {
|
|
160
|
+
// Like over HTTP: msg/header in the return value of the server method show a message.
|
|
161
|
+
const { data: returnData } = data;
|
|
162
|
+
if (returnData && typeof returnData === "object" && (returnData.msg || returnData.header)) {
|
|
163
|
+
trigger("pushMsg", returnData.header || "", returnData.msg || "");
|
|
164
|
+
}
|
|
148
165
|
if (data.id && OPEN_REQUESTS[data.id]) {
|
|
149
166
|
OPEN_REQUESTS[data.id][0](data.data);
|
|
150
167
|
delete OPEN_REQUESTS[data.id];
|
|
151
168
|
}
|
|
152
169
|
} else if (data.type && data.type === "sdc_event") {
|
|
153
|
-
let event = data
|
|
170
|
+
let { event } = data;
|
|
154
171
|
if (event) {
|
|
155
172
|
trigger(event, data.payload);
|
|
156
173
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {SdcModel, SdcQuerySet} from "../index.js";
|
|
1
|
+
import { SdcModel, SdcQuerySet } from "../index.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Reference to the HTML body.
|
|
@@ -193,7 +193,7 @@ function progressHandlingFunction(e) {
|
|
|
193
193
|
|
|
194
194
|
$progressContainer
|
|
195
195
|
.find(".progress-bar")
|
|
196
|
-
.css({width: percentVal})
|
|
196
|
+
.css({ width: percentVal })
|
|
197
197
|
.text(percentVal);
|
|
198
198
|
}
|
|
199
199
|
}
|
|
@@ -331,7 +331,7 @@ function parseHiddenInputs(value) {
|
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
export function getValueFromField(formItem) {
|
|
334
|
-
let {type, name} = formItem;
|
|
334
|
+
let { type, name } = formItem;
|
|
335
335
|
if (name && name !== "") {
|
|
336
336
|
if (type === "hidden") {
|
|
337
337
|
return parseHiddenInputs($(formItem).val());
|
|
@@ -350,12 +350,64 @@ export function getValueFromField(formItem) {
|
|
|
350
350
|
return null;
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
+
const pad2 = (n) => String(n).padStart(2, "0");
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Convert a Date, a date string or a timestamp into a valid Date.
|
|
357
|
+
* A date-only string ("YYYY-MM-DD") is read as local midnight, not UTC,
|
|
358
|
+
* so the day does not shift in time zones west of UTC.
|
|
359
|
+
*
|
|
360
|
+
* @param {*} value
|
|
361
|
+
* @returns {?Date} null if the value is empty or not a valid date
|
|
362
|
+
*/
|
|
363
|
+
export function toDate(value) {
|
|
364
|
+
if (value === null || value === undefined || value === "") {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
let date;
|
|
368
|
+
if (value instanceof Date) {
|
|
369
|
+
date = value;
|
|
370
|
+
} else if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
371
|
+
const [y, m, d] = value.split("-").map(Number);
|
|
372
|
+
date = new Date(y, m - 1, d);
|
|
373
|
+
} else {
|
|
374
|
+
date = new Date(value);
|
|
375
|
+
}
|
|
376
|
+
return isNaN(date.getTime()) ? null : date;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* @param {*} value
|
|
381
|
+
* @returns {string} "YYYY-MM-DD" in local time, or "" if not a valid date
|
|
382
|
+
*/
|
|
383
|
+
export function formatDate(value) {
|
|
384
|
+
const date = toDate(value);
|
|
385
|
+
if (!date) {
|
|
386
|
+
return "";
|
|
387
|
+
}
|
|
388
|
+
return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* @param {*} value
|
|
393
|
+
* @returns {string} "YYYY-MM-DDTHH:MM" in local time, or "" if not a valid date
|
|
394
|
+
*/
|
|
395
|
+
export function formatDateTimeLocal(value) {
|
|
396
|
+
const date = toDate(value);
|
|
397
|
+
if (!date) {
|
|
398
|
+
return "";
|
|
399
|
+
}
|
|
400
|
+
return `${formatDate(date)}T${pad2(date.getHours())}:${pad2(date.getMinutes())}`;
|
|
401
|
+
}
|
|
353
402
|
|
|
354
403
|
export function setValueInField(formItem, value) {
|
|
355
|
-
let {type, name} = formItem;
|
|
404
|
+
let { type, name } = formItem;
|
|
356
405
|
if (name && name !== "") {
|
|
357
|
-
|
|
358
|
-
|
|
406
|
+
if (type === "datetime-local") {
|
|
407
|
+
formItem.value = formatDateTimeLocal(value);
|
|
408
|
+
} else if (type === "date") {
|
|
409
|
+
formItem.value = formatDate(value);
|
|
410
|
+
} else if (type === "checkbox") {
|
|
359
411
|
formItem.checked = !!value;
|
|
360
412
|
} else if (type === "file") {
|
|
361
413
|
if (value instanceof File) {
|
|
@@ -368,7 +420,7 @@ export function setValueInField(formItem, value) {
|
|
|
368
420
|
} else if (value instanceof SdcModel) {
|
|
369
421
|
$(formItem).val(value.id);
|
|
370
422
|
} else if (value instanceof SdcQuerySet) {
|
|
371
|
-
$(formItem).val(`[${value.getIds().join(
|
|
423
|
+
$(formItem).val(`[${value.getIds().join(",")}]`);
|
|
372
424
|
} else {
|
|
373
425
|
if (value === null) {
|
|
374
426
|
value = "";
|
|
@@ -72,7 +72,7 @@ function findSdcTgs($container, tagNameList, parentController) {
|
|
|
72
72
|
*/
|
|
73
73
|
function replacePlaceholderController(controller, url, urlValues) {
|
|
74
74
|
for (let key_idx in controller._urlParams) {
|
|
75
|
-
if (controller._urlParams
|
|
75
|
+
if (Object.hasOwn(controller._urlParams, key_idx)) {
|
|
76
76
|
let key = controller._urlParams[key_idx];
|
|
77
77
|
let re = RegExp("%\\(" + key + "\\)\\w", "gm");
|
|
78
78
|
const val = urlValues[key];
|
|
@@ -516,7 +516,22 @@ export function reconcile($virtualNode, $realNode) {
|
|
|
516
516
|
toRemove.forEach(($element) => $element.safeRemove());
|
|
517
517
|
}
|
|
518
518
|
|
|
519
|
+
/**
|
|
520
|
+
* Replace the event listeners added by sdcDom (JSX on* props) on a kept node
|
|
521
|
+
* with the listeners of its new virtual counterpart.
|
|
522
|
+
*/
|
|
523
|
+
function syncListeners(real, virtual) {
|
|
524
|
+
if (!real || !virtual || (!real._sdcListeners && !virtual._sdcListeners)) {
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
(real._sdcListeners ?? []).forEach(([type, fn]) => real.removeEventListener(type, fn));
|
|
528
|
+
const listeners = virtual._sdcListeners ?? [];
|
|
529
|
+
listeners.forEach(([type, fn]) => real.addEventListener(type, fn));
|
|
530
|
+
real._sdcListeners = listeners;
|
|
531
|
+
}
|
|
532
|
+
|
|
519
533
|
function syncAttributes($real, $virtual) {
|
|
534
|
+
syncListeners($real[0], $virtual[0]);
|
|
520
535
|
const realAttrs = $real[0].attributes ?? [];
|
|
521
536
|
const virtualAttrs = $virtual[0].attributes ?? [];
|
|
522
537
|
// Remove missing attrs
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
|
2
|
-
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
|
|
3
|
-
|
|
4
|
-
name: Node.js CI
|
|
5
|
-
|
|
6
|
-
on:
|
|
7
|
-
push:
|
|
8
|
-
branches: [ "main" ]
|
|
9
|
-
pull_request:
|
|
10
|
-
branches: [ "main" ]
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
build:
|
|
14
|
-
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
|
|
17
|
-
strategy:
|
|
18
|
-
matrix:
|
|
19
|
-
node-version: [20.x, 22.x]
|
|
20
|
-
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
21
|
-
|
|
22
|
-
steps:
|
|
23
|
-
- uses: actions/checkout@v4
|
|
24
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
|
25
|
-
uses: actions/setup-node@v4
|
|
26
|
-
with:
|
|
27
|
-
node-version: ${{ matrix.node-version }}
|
|
28
|
-
cache: 'npm'
|
|
29
|
-
|
|
30
|
-
- name: Install dependencies (npm)
|
|
31
|
-
run: |
|
|
32
|
-
npm i -g yarn
|
|
33
|
-
yarn install
|
|
34
|
-
|
|
35
|
-
- name: Run Tests
|
|
36
|
-
run: |
|
|
37
|
-
yarn test
|
|
38
|
-
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<component name="InspectionProjectProfileManager">
|
|
2
|
-
<profile version="1.0">
|
|
3
|
-
<option name="myName" value="Project Default" />
|
|
4
|
-
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
5
|
-
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
|
6
|
-
<option name="myValues">
|
|
7
|
-
<value>
|
|
8
|
-
<list size="1">
|
|
9
|
-
<item index="0" class="java.lang.String" itemvalue="keydown" />
|
|
10
|
-
</list>
|
|
11
|
-
</value>
|
|
12
|
-
</option>
|
|
13
|
-
<option name="myCustomValuesEnabled" value="true" />
|
|
14
|
-
</inspection_tool>
|
|
15
|
-
<inspection_tool class="JSHint" enabled="true" level="ERROR" enabled_by_default="true" />
|
|
16
|
-
</profile>
|
|
17
|
-
</component>
|
package/.idea/misc.xml
DELETED
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/SimpleDomControlClient.iml" filepath="$PROJECT_DIR$/SimpleDomControlClient.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|