@yuneta/gobj-ui 7.23.143 → 7.23.144
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/README.md +16 -2
- package/dist/gobj-ui.cjs.js +718 -158
- package/dist/gobj-ui.es.js +719 -159
- package/package.json +1 -1
- package/src/c_yui_json_pad.css +94 -0
- package/src/c_yui_json_pad.js +567 -114
- package/src/json_view_helpers.js +56 -1
- package/src/json_view_helpers.test.js +43 -0
- package/src/yui_icons.css +12 -0
package/dist/gobj-ui.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as gobj_js from "@yuneta/gobj-js";
|
|
2
|
-
import { SDATA, SDATA_END, clean_name, createElement2, createOneHtml, create_template_record, data_type_t, debounce, delete_from_list, duplicate_objects, empty_json, empty_string, escapeHtml, event_flag_t, gclass_create, gclass_find_by_name, gclass_flag_t, getPositionRelativeToBody, gobj_bottom_gobj, gobj_change_state, gobj_command, gobj_create, gobj_create_pure_child, gobj_create_service, gobj_current_state, gobj_destroy, gobj_find_child, gobj_find_service, gobj_full_name, gobj_gclass_name, gobj_is_destroying, gobj_is_playing, gobj_is_pure_child, gobj_is_running, gobj_is_service, gobj_is_volatil, gobj_match_children, gobj_name, gobj_parent, gobj_post_event, gobj_publish_event, gobj_read_attr, gobj_read_bool_attr, gobj_read_integer_attr, gobj_read_pointer_attr, gobj_read_str_attr, gobj_save_persistent_attrs, gobj_send_event, gobj_set_trace_machine_format, gobj_short_name, gobj_start, gobj_start_tree, gobj_stop, gobj_stop_children, gobj_subscribe_event, gobj_unsubscribe_event, gobj_write_attr, gobj_write_bool_attr, gobj_write_integer_attr, gobj_write_str_attr, gobj_yuno, gobj_yuno_name, is_array, is_boolean, is_date, is_gobj, is_null, is_number, is_object, is_string, json_deep_copy, json_object_size, json_object_update, json_object_update_missing, json_size, kw_clone_by_keys, kw_flag_t, kw_get_dict, kw_get_dict_value, kw_get_int, kw_get_local_storage_value, kw_get_str, kw_has_key, kw_set_dict_value, kw_set_local_storage_value, kwid_find_one_record, kwid_get_ids, kwid_new_dict, log_error, log_warning, msg_iev_get_stack, parseBoolean, parseSVG, refresh_language, safeSrc, sdata_flag_t, set_console_log_enabled, set_log_callback, sprintf, str_in_list, template_get_field_desc, trace_msg, treedb_decoder_fkey, treedb_encoder_fkey, treedb_get_field_desc, treedb_hook_data_size } from "@yuneta/gobj-js";
|
|
2
|
+
import { SDATA, SDATA_END, clean_name, createElement2, createOneHtml, create_template_record, data_type_t, debounce, delete_from_list, duplicate_objects, empty_json, empty_string, escapeHtml, event_flag_t, flat_diff, gclass_create, gclass_find_by_name, gclass_flag_t, getPositionRelativeToBody, gobj_bottom_gobj, gobj_change_state, gobj_command, gobj_create, gobj_create_pure_child, gobj_create_service, gobj_current_state, gobj_destroy, gobj_find_child, gobj_find_service, gobj_full_name, gobj_gclass_name, gobj_is_destroying, gobj_is_playing, gobj_is_pure_child, gobj_is_running, gobj_is_service, gobj_is_volatil, gobj_match_children, gobj_name, gobj_parent, gobj_post_event, gobj_publish_event, gobj_read_attr, gobj_read_bool_attr, gobj_read_integer_attr, gobj_read_pointer_attr, gobj_read_str_attr, gobj_save_persistent_attrs, gobj_send_event, gobj_set_trace_machine_format, gobj_short_name, gobj_start, gobj_start_tree, gobj_stop, gobj_stop_children, gobj_subscribe_event, gobj_unsubscribe_event, gobj_write_attr, gobj_write_bool_attr, gobj_write_integer_attr, gobj_write_str_attr, gobj_yuno, gobj_yuno_name, is_array, is_boolean, is_date, is_gobj, is_null, is_number, is_object, is_string, json2flat, json_deep_copy, json_object_size, json_object_update, json_object_update_missing, json_size, kw_clone_by_keys, kw_flag_t, kw_get_dict, kw_get_dict_value, kw_get_int, kw_get_local_storage_value, kw_get_str, kw_has_key, kw_set_dict_value, kw_set_local_storage_value, kwid_find_one_record, kwid_get_ids, kwid_new_dict, log_error, log_warning, msg_iev_get_stack, parseBoolean, parseSVG, refresh_language, safeSrc, sdata_flag_t, set_console_log_enabled, set_log_callback, sprintf, str_in_list, template_get_field_desc, trace_msg, treedb_decoder_fkey, treedb_encoder_fkey, treedb_get_field_desc, treedb_hook_data_size } from "@yuneta/gobj-js";
|
|
3
3
|
import i18next, { t } from "i18next";
|
|
4
4
|
import TomSelect from "tom-select";
|
|
5
5
|
import { createJSONEditor } from "vanilla-jsoneditor";
|
|
@@ -7048,6 +7048,60 @@ function count_branches(value) {
|
|
|
7048
7048
|
for (let v of entries) if (has_branch(v)) n++;
|
|
7049
7049
|
return n;
|
|
7050
7050
|
}
|
|
7051
|
+
/************************************************************
|
|
7052
|
+
* What differs between two documents: one row per id of
|
|
7053
|
+
* their flat form (json2flat), sorted by id in natural order,
|
|
7054
|
+
* so `[2]` comes before `[10]`:
|
|
7055
|
+
*
|
|
7056
|
+
* [{id, kind: "added"|"removed"|"changed", from?, to?}]
|
|
7057
|
+
*
|
|
7058
|
+
* `from` is the first document's value and `to` the second's:
|
|
7059
|
+
* an added row has no `from`, a removed row no `to`.
|
|
7060
|
+
*
|
|
7061
|
+
* Two roots that are not containers of the same kind have no
|
|
7062
|
+
* ids in common to compare by: they are one value each, and
|
|
7063
|
+
* the row that says they differ has the empty id.
|
|
7064
|
+
*
|
|
7065
|
+
* Throws what json2flat throws (a document too deep).
|
|
7066
|
+
************************************************************/
|
|
7067
|
+
function json_diff_rows(doc_a, doc_b) {
|
|
7068
|
+
const kind_of = (v) => {
|
|
7069
|
+
if (Array.isArray(v)) return "array";
|
|
7070
|
+
if (v !== null && typeof v === "object") return "object";
|
|
7071
|
+
return "scalar";
|
|
7072
|
+
};
|
|
7073
|
+
let kind_a = kind_of(doc_a);
|
|
7074
|
+
if (kind_a === "scalar" || kind_a !== kind_of(doc_b)) {
|
|
7075
|
+
if (JSON.stringify(doc_a) === JSON.stringify(doc_b)) return [];
|
|
7076
|
+
return [{
|
|
7077
|
+
id: "",
|
|
7078
|
+
kind: "changed",
|
|
7079
|
+
from: doc_a,
|
|
7080
|
+
to: doc_b
|
|
7081
|
+
}];
|
|
7082
|
+
}
|
|
7083
|
+
let diff = flat_diff(json2flat(doc_a), json2flat(doc_b));
|
|
7084
|
+
let rows = [];
|
|
7085
|
+
for (const id of Object.keys(diff.added)) rows.push({
|
|
7086
|
+
id,
|
|
7087
|
+
kind: "added",
|
|
7088
|
+
to: diff.added[id]
|
|
7089
|
+
});
|
|
7090
|
+
for (const id of Object.keys(diff.removed)) rows.push({
|
|
7091
|
+
id,
|
|
7092
|
+
kind: "removed",
|
|
7093
|
+
from: diff.removed[id]
|
|
7094
|
+
});
|
|
7095
|
+
for (const id of Object.keys(diff.changed)) rows.push({
|
|
7096
|
+
id,
|
|
7097
|
+
kind: "changed",
|
|
7098
|
+
from: diff.changed[id].from,
|
|
7099
|
+
to: diff.changed[id].to
|
|
7100
|
+
});
|
|
7101
|
+
const collator = new Intl.Collator("en", { numeric: true });
|
|
7102
|
+
rows.sort((x, y) => collator.compare(x.id, y.id));
|
|
7103
|
+
return rows;
|
|
7104
|
+
}
|
|
7051
7105
|
//#endregion
|
|
7052
7106
|
//#region src/c_yui_form.js
|
|
7053
7107
|
/***********************************************************************
|
|
@@ -14773,7 +14827,8 @@ function register_c_yui_json() {
|
|
|
14773
14827
|
* c_yui_json_pad.js
|
|
14774
14828
|
*
|
|
14775
14829
|
* C_YUI_JSON_PAD -- a pad to paste JSON from OUTSIDE and read it
|
|
14776
|
-
* with the library's own viewer
|
|
14830
|
+
* with the library's own viewer, and a second one to compare it
|
|
14831
|
+
* with.
|
|
14777
14832
|
*
|
|
14778
14833
|
* The viewer (C_YUI_JSON: the lazy tree, the raw text and the
|
|
14779
14834
|
* graph) only ever showed what an app fetched. A JSON that came
|
|
@@ -14782,30 +14837,63 @@ function register_c_yui_json() {
|
|
|
14782
14837
|
* at hand. This is the blank page for it: paste, and read it the
|
|
14783
14838
|
* way every other document of the app is read.
|
|
14784
14839
|
*
|
|
14840
|
+
* Two documents are the other half of the job: the config that
|
|
14841
|
+
* works and the one that does not, a record before and after. The
|
|
14842
|
+
* second pane is there on demand ("second json"), and "compare"
|
|
14843
|
+
* puts their differences in place of the two viewers -- one row
|
|
14844
|
+
* per id of the flat form (json2flat), the form a person reads
|
|
14845
|
+
* when two configurations disagree.
|
|
14846
|
+
*
|
|
14785
14847
|
* DOM (UPPER_SNAKE logical classes):
|
|
14786
14848
|
*
|
|
14787
|
-
* JSON_PAD
|
|
14788
|
-
*
|
|
14789
|
-
*
|
|
14790
|
-
*
|
|
14791
|
-
*
|
|
14792
|
-
*
|
|
14793
|
-
*
|
|
14794
|
-
*
|
|
14795
|
-
*
|
|
14796
|
-
*
|
|
14797
|
-
*
|
|
14798
|
-
*
|
|
14799
|
-
*
|
|
14800
|
-
*
|
|
14801
|
-
*
|
|
14802
|
-
*
|
|
14803
|
-
*
|
|
14804
|
-
*
|
|
14805
|
-
*
|
|
14806
|
-
*
|
|
14807
|
-
*
|
|
14808
|
-
*
|
|
14849
|
+
* JSON_PAD the root
|
|
14850
|
+
* JSON_PAD_TOOLBAR the notice and the two toggles
|
|
14851
|
+
* JSON_PAD_NOTICE "json not kept": the storage refused
|
|
14852
|
+
* JSON_PAD_SECOND show / hide the second pane
|
|
14853
|
+
* JSON_PAD_COMPARE show / hide the differences
|
|
14854
|
+
* JSON_PAD_PANES the panes, side by side (stacked when
|
|
14855
|
+
* the pad is narrow)
|
|
14856
|
+
* JSON_PAD_PANE JSON_PAD_PANE_A / JSON_PAD_PANE_B
|
|
14857
|
+
* JSON_PAD_BAR the text area and its two buttons
|
|
14858
|
+
* JSON_PAD_INPUT where the text goes
|
|
14859
|
+
* JSON_PAD_VIEW read what is in the text area
|
|
14860
|
+
* JSON_PAD_CLEAR empty the pane
|
|
14861
|
+
* JSON_PAD_ERROR "invalid JSON" and the parser's reason
|
|
14862
|
+
* JSON_PAD_BODY the pane's C_YUI_JSON child
|
|
14863
|
+
* JSON_PAD_DIFF the differences: JSON_PAD_DIFF_SUMMARY
|
|
14864
|
+
* and JSON_PAD_DIFF_TABLE, one
|
|
14865
|
+
* JSON_PAD_DIFF_ROW per id
|
|
14866
|
+
*
|
|
14867
|
+
* Every way in is an event, and a pane event names its pane
|
|
14868
|
+
* (`pane`: "a" or "b"):
|
|
14869
|
+
*
|
|
14870
|
+
* EV_PASTE {pane, text} a paste ANYWHERE in a pane replaces
|
|
14871
|
+
* its document and shows it at once --
|
|
14872
|
+
* a pane holds one document, not a
|
|
14873
|
+
* text to edit
|
|
14874
|
+
* EV_VIEW {pane} the text area as it is (typed, or
|
|
14875
|
+
* edited after a paste); also Ctrl+Enter
|
|
14876
|
+
* EV_CLEAR {pane} back to a blank pane
|
|
14877
|
+
* EV_TEXT_CHANGED {pane} the text area was edited: keep it
|
|
14878
|
+
* EV_TOGGLE_SECOND show / hide the second pane
|
|
14879
|
+
* EV_TOGGLE_DIFF show / hide the differences
|
|
14880
|
+
*
|
|
14881
|
+
* FSM: the states are the LAYOUT -- ST_SINGLE (one pane), ST_DUAL
|
|
14882
|
+
* (two), ST_DIFF (two, with their differences in place of the
|
|
14883
|
+
* viewers). Comparing needs two panes, so EV_TOGGLE_DIFF is not
|
|
14884
|
+
* defined in ST_SINGLE and its button is not on screen there.
|
|
14885
|
+
* EV_EXPAND_PATH, which a viewer publishes when a `__collapsed__`
|
|
14886
|
+
* sentinel is opened, is answered with EV_SUBTREE_ERROR to the
|
|
14887
|
+
* viewer that asked: a pasted document has no backend to fetch the
|
|
14888
|
+
* rest from -- the source truncated it, and the pad says so. It is
|
|
14889
|
+
* not defined in ST_DIFF, where no viewer is on screen.
|
|
14890
|
+
*
|
|
14891
|
+
* What is kept: both texts and the layout, in localStorage under
|
|
14892
|
+
* `storage_key` (empty: nothing is kept), written when a text is
|
|
14893
|
+
* pasted, viewed, cleared or edited and when the layout changes,
|
|
14894
|
+
* so the next pad opens as this one was left. localStorage is per
|
|
14895
|
+
* browser and per origin, and has a quota: a text too big for it
|
|
14896
|
+
* is not kept, the toolbar says so, and the log says why.
|
|
14809
14897
|
*
|
|
14810
14898
|
* Hosted by setup_json_pad() (yui_json_pad.js) in a C_YUI_WINDOW;
|
|
14811
14899
|
* any host can mount `$container` itself.
|
|
@@ -14817,19 +14905,52 @@ function register_c_yui_json() {
|
|
|
14817
14905
|
* Constants
|
|
14818
14906
|
***************************************************************/
|
|
14819
14907
|
var GCLASS_NAME$12 = "C_YUI_JSON_PAD";
|
|
14908
|
+
var PANES = ["a", "b"];
|
|
14909
|
+
var MODE_OF_STATE = {
|
|
14910
|
+
ST_SINGLE: "single",
|
|
14911
|
+
ST_DUAL: "dual",
|
|
14912
|
+
ST_DIFF: "diff"
|
|
14913
|
+
};
|
|
14914
|
+
var KIND_TAG = {
|
|
14915
|
+
added: () => [
|
|
14916
|
+
"span",
|
|
14917
|
+
{
|
|
14918
|
+
class: "tag is-success is-light",
|
|
14919
|
+
i18n: "added"
|
|
14920
|
+
},
|
|
14921
|
+
"added"
|
|
14922
|
+
],
|
|
14923
|
+
removed: () => [
|
|
14924
|
+
"span",
|
|
14925
|
+
{
|
|
14926
|
+
class: "tag is-danger is-light",
|
|
14927
|
+
i18n: "removed"
|
|
14928
|
+
},
|
|
14929
|
+
"removed"
|
|
14930
|
+
],
|
|
14931
|
+
changed: () => [
|
|
14932
|
+
"span",
|
|
14933
|
+
{
|
|
14934
|
+
class: "tag is-warning is-light",
|
|
14935
|
+
i18n: "changed"
|
|
14936
|
+
},
|
|
14937
|
+
"changed"
|
|
14938
|
+
]
|
|
14939
|
+
};
|
|
14820
14940
|
/***************************************************************
|
|
14821
14941
|
* Data
|
|
14822
14942
|
***************************************************************/
|
|
14823
14943
|
var attrs_table$12 = [
|
|
14824
14944
|
SDATA(data_type_t.DTP_POINTER, "subscriber", 0, null, "Subscriber of output events"),
|
|
14945
|
+
SDATA(data_type_t.DTP_STRING, "storage_key", 0, "yui_json_pad", "localStorage key the two texts and the layout are kept under. Empty: nothing is kept"),
|
|
14825
14946
|
SDATA(data_type_t.DTP_POINTER, "$container", 0, null, "HTMLElement root, mounted by the host"),
|
|
14826
14947
|
SDATA_END()
|
|
14827
14948
|
];
|
|
14828
14949
|
var PRIVATE_DATA$12 = {
|
|
14829
|
-
|
|
14830
|
-
$
|
|
14831
|
-
$
|
|
14832
|
-
|
|
14950
|
+
panes: null,
|
|
14951
|
+
$compare: null,
|
|
14952
|
+
$notice: null,
|
|
14953
|
+
$diff: null
|
|
14833
14954
|
};
|
|
14834
14955
|
var __gclass__$12 = null;
|
|
14835
14956
|
/******************************
|
|
@@ -14844,28 +14965,36 @@ function mt_create$12(gobj) {
|
|
|
14844
14965
|
if (!subscriber) subscriber = gobj_parent(gobj);
|
|
14845
14966
|
gobj_subscribe_event(gobj, null, {}, subscriber);
|
|
14846
14967
|
build_ui$11(gobj);
|
|
14847
|
-
|
|
14848
|
-
|
|
14849
|
-
|
|
14850
|
-
|
|
14851
|
-
|
|
14968
|
+
for (const id of PANES) {
|
|
14969
|
+
let pane = priv.panes[id];
|
|
14970
|
+
pane.gobj_json = gobj_create_pure_child(`json_pad_view_${id}`, "C_YUI_JSON", {}, gobj);
|
|
14971
|
+
let $view = pane.gobj_json ? gobj_read_attr(pane.gobj_json, "$container") : null;
|
|
14972
|
+
if (!$view) {
|
|
14973
|
+
log_error(`${gobj_short_name(gobj)}: C_YUI_JSON without $container`);
|
|
14974
|
+
continue;
|
|
14975
|
+
}
|
|
14976
|
+
pane.$body.appendChild($view);
|
|
14852
14977
|
}
|
|
14853
|
-
gobj_read_attr(gobj, "$container").querySelector(".JSON_PAD_BODY").appendChild($view);
|
|
14854
14978
|
}
|
|
14855
14979
|
/***************************************************************
|
|
14856
14980
|
* Framework Method: Start
|
|
14857
14981
|
***************************************************************/
|
|
14858
14982
|
function mt_start$12(gobj) {
|
|
14859
14983
|
let priv = gobj.priv;
|
|
14860
|
-
if (priv.gobj_json) gobj_start(priv.gobj_json);
|
|
14861
|
-
|
|
14984
|
+
for (const id of PANES) if (priv.panes[id].gobj_json) gobj_start(priv.panes[id].gobj_json);
|
|
14985
|
+
restore_state(gobj);
|
|
14986
|
+
priv.panes.a.$input.focus();
|
|
14862
14987
|
}
|
|
14863
14988
|
/***************************************************************
|
|
14864
14989
|
* Framework Method: Stop
|
|
14865
14990
|
***************************************************************/
|
|
14866
14991
|
function mt_stop$12(gobj) {
|
|
14867
14992
|
let priv = gobj.priv;
|
|
14868
|
-
|
|
14993
|
+
save_state(gobj);
|
|
14994
|
+
for (const id of PANES) {
|
|
14995
|
+
let gobj_json = priv.panes[id].gobj_json;
|
|
14996
|
+
if (gobj_json && gobj_is_running(gobj_json)) gobj_stop(gobj_json);
|
|
14997
|
+
}
|
|
14869
14998
|
}
|
|
14870
14999
|
/***************************************************************
|
|
14871
15000
|
* Framework Method: Destroy
|
|
@@ -14875,37 +15004,106 @@ function mt_destroy$12(gobj) {}
|
|
|
14875
15004
|
* Local Methods
|
|
14876
15005
|
***************************/
|
|
14877
15006
|
/***************************************************************
|
|
14878
|
-
*
|
|
14879
|
-
|
|
15007
|
+
* A button of the pad: an icon, its label, and an event.
|
|
15008
|
+
***************************************************************/
|
|
15009
|
+
function pad_button(gobj, cls, icon, key, event_name, kw) {
|
|
15010
|
+
return [
|
|
15011
|
+
"button",
|
|
15012
|
+
{
|
|
15013
|
+
class: `${cls} button`,
|
|
15014
|
+
type: "button",
|
|
15015
|
+
title: t(key),
|
|
15016
|
+
"data-i18n-title": key,
|
|
15017
|
+
"aria-label": t(key),
|
|
15018
|
+
"data-i18n-aria-label": key
|
|
15019
|
+
},
|
|
15020
|
+
[yui_toolbar_icon(icon), [
|
|
15021
|
+
"span",
|
|
15022
|
+
{
|
|
15023
|
+
style: "padding-left:5px;",
|
|
15024
|
+
i18n: key
|
|
15025
|
+
},
|
|
15026
|
+
key
|
|
15027
|
+
]],
|
|
15028
|
+
{ click: (evt) => {
|
|
15029
|
+
evt.stopPropagation();
|
|
15030
|
+
gobj_send_event(gobj, event_name, { ...kw }, gobj);
|
|
15031
|
+
} }
|
|
15032
|
+
];
|
|
15033
|
+
}
|
|
15034
|
+
/***************************************************************
|
|
15035
|
+
* The toolbar, the two panes, and the differences.
|
|
14880
15036
|
***************************************************************/
|
|
14881
15037
|
function build_ui$11(gobj) {
|
|
14882
15038
|
let priv = gobj.priv;
|
|
14883
|
-
|
|
14884
|
-
|
|
14885
|
-
|
|
15039
|
+
priv.$notice = createElement2([
|
|
15040
|
+
"div",
|
|
15041
|
+
{
|
|
15042
|
+
class: "JSON_PAD_NOTICE is-hidden has-text-danger is-size-7",
|
|
15043
|
+
role: "status"
|
|
15044
|
+
},
|
|
15045
|
+
[[
|
|
15046
|
+
"span",
|
|
14886
15047
|
{
|
|
14887
|
-
|
|
14888
|
-
|
|
14889
|
-
title: t(key),
|
|
14890
|
-
"data-i18n-title": key,
|
|
14891
|
-
"aria-label": t(key),
|
|
14892
|
-
"data-i18n-aria-label": key
|
|
15048
|
+
style: "font-weight:600;",
|
|
15049
|
+
i18n: "json not kept"
|
|
14893
15050
|
},
|
|
14894
|
-
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
|
|
14898
|
-
|
|
14899
|
-
|
|
14900
|
-
|
|
14901
|
-
]],
|
|
14902
|
-
{ click: (evt) => {
|
|
14903
|
-
evt.stopPropagation();
|
|
14904
|
-
gobj_send_event(gobj, event_name, {}, gobj);
|
|
14905
|
-
} }
|
|
14906
|
-
];
|
|
15051
|
+
"json not kept"
|
|
15052
|
+
]]
|
|
15053
|
+
]);
|
|
15054
|
+
priv.$compare = createElement2(pad_button(gobj, "JSON_PAD_COMPARE is-hidden", "yi-right-left", "compare", "EV_TOGGLE_DIFF", {}));
|
|
15055
|
+
priv.panes = {
|
|
15056
|
+
a: build_pane(gobj, "a", "first json"),
|
|
15057
|
+
b: build_pane(gobj, "b", "second json")
|
|
14907
15058
|
};
|
|
14908
|
-
priv.$
|
|
15059
|
+
priv.panes.b.$pane.classList.add("is-hidden");
|
|
15060
|
+
priv.$diff = createElement2([
|
|
15061
|
+
"div",
|
|
15062
|
+
{ class: "JSON_PAD_DIFF is-hidden" },
|
|
15063
|
+
[]
|
|
15064
|
+
]);
|
|
15065
|
+
let $container = createElement2([
|
|
15066
|
+
"div",
|
|
15067
|
+
{ class: "C_YUI_JSON_PAD JSON_PAD" },
|
|
15068
|
+
[
|
|
15069
|
+
[
|
|
15070
|
+
"div",
|
|
15071
|
+
{ class: "JSON_PAD_TOOLBAR" },
|
|
15072
|
+
[
|
|
15073
|
+
priv.$notice,
|
|
15074
|
+
pad_button(gobj, "JSON_PAD_SECOND", "yi-columns", "second json", "EV_TOGGLE_SECOND", {}),
|
|
15075
|
+
priv.$compare
|
|
15076
|
+
]
|
|
15077
|
+
],
|
|
15078
|
+
[
|
|
15079
|
+
"div",
|
|
15080
|
+
{ class: "JSON_PAD_PANES" },
|
|
15081
|
+
[priv.panes.a.$pane, priv.panes.b.$pane]
|
|
15082
|
+
],
|
|
15083
|
+
priv.$diff
|
|
15084
|
+
]
|
|
15085
|
+
]);
|
|
15086
|
+
gobj_write_attr(gobj, "$container", $container);
|
|
15087
|
+
press_toggle(gobj, ".JSON_PAD_SECOND", false);
|
|
15088
|
+
press_toggle(gobj, ".JSON_PAD_COMPARE", false);
|
|
15089
|
+
}
|
|
15090
|
+
/***************************************************************
|
|
15091
|
+
* One pane: the text area and its buttons, the error line, and
|
|
15092
|
+
* the body its viewer is mounted in. `name_key` names the pane
|
|
15093
|
+
* for a reader (its text area's title and aria-label).
|
|
15094
|
+
***************************************************************/
|
|
15095
|
+
function build_pane(gobj, id, name_key) {
|
|
15096
|
+
let pane = {
|
|
15097
|
+
$pane: null,
|
|
15098
|
+
$input: null,
|
|
15099
|
+
$error: null,
|
|
15100
|
+
$reason: null,
|
|
15101
|
+
$body: null,
|
|
15102
|
+
gobj_json: null,
|
|
15103
|
+
doc: null,
|
|
15104
|
+
has_doc: false
|
|
15105
|
+
};
|
|
15106
|
+
pane.$input = createElement2([
|
|
14909
15107
|
"textarea",
|
|
14910
15108
|
{
|
|
14911
15109
|
class: "JSON_PAD_INPUT textarea",
|
|
@@ -14913,21 +15111,26 @@ function build_ui$11(gobj) {
|
|
|
14913
15111
|
spellcheck: "false",
|
|
14914
15112
|
placeholder: t("paste json here"),
|
|
14915
15113
|
"data-i18n-placeholder": "paste json here",
|
|
14916
|
-
title: t(
|
|
14917
|
-
"data-i18n-title":
|
|
14918
|
-
"aria-label": t(
|
|
14919
|
-
"data-i18n-aria-label":
|
|
15114
|
+
title: t(name_key),
|
|
15115
|
+
"data-i18n-title": name_key,
|
|
15116
|
+
"aria-label": t(name_key),
|
|
15117
|
+
"data-i18n-aria-label": name_key,
|
|
14920
15118
|
style: "font-family:monospace; resize:vertical; min-height:4.5em;"
|
|
14921
15119
|
},
|
|
14922
15120
|
"",
|
|
14923
|
-
{
|
|
14924
|
-
|
|
14925
|
-
evt.
|
|
14926
|
-
|
|
15121
|
+
{
|
|
15122
|
+
keydown: (evt) => {
|
|
15123
|
+
if ((evt.ctrlKey || evt.metaKey) && evt.key === "Enter") {
|
|
15124
|
+
evt.preventDefault();
|
|
15125
|
+
gobj_send_event(gobj, "EV_VIEW", { pane: id }, gobj);
|
|
15126
|
+
}
|
|
15127
|
+
},
|
|
15128
|
+
change: () => {
|
|
15129
|
+
gobj_send_event(gobj, "EV_TEXT_CHANGED", { pane: id }, gobj);
|
|
14927
15130
|
}
|
|
14928
|
-
}
|
|
15131
|
+
}
|
|
14929
15132
|
]);
|
|
14930
|
-
|
|
15133
|
+
pane.$reason = createElement2([
|
|
14931
15134
|
"span",
|
|
14932
15135
|
{
|
|
14933
15136
|
class: "JSON_PAD_ERROR_REASON",
|
|
@@ -14935,7 +15138,7 @@ function build_ui$11(gobj) {
|
|
|
14935
15138
|
},
|
|
14936
15139
|
""
|
|
14937
15140
|
]);
|
|
14938
|
-
|
|
15141
|
+
pane.$error = createElement2([
|
|
14939
15142
|
"div",
|
|
14940
15143
|
{
|
|
14941
15144
|
class: "JSON_PAD_ERROR is-hidden has-text-danger is-size-7",
|
|
@@ -14949,14 +15152,19 @@ function build_ui$11(gobj) {
|
|
|
14949
15152
|
i18n: "invalid json"
|
|
14950
15153
|
},
|
|
14951
15154
|
"invalid json"
|
|
14952
|
-
],
|
|
15155
|
+
], pane.$reason]
|
|
14953
15156
|
]);
|
|
14954
|
-
|
|
15157
|
+
pane.$body = createElement2([
|
|
14955
15158
|
"div",
|
|
14956
15159
|
{
|
|
14957
|
-
class: "
|
|
14958
|
-
style: "height:
|
|
15160
|
+
class: "JSON_PAD_BODY",
|
|
15161
|
+
style: "flex:1 1 auto; min-height:0; display:flex; flex-direction:column;"
|
|
14959
15162
|
},
|
|
15163
|
+
[]
|
|
15164
|
+
]);
|
|
15165
|
+
pane.$pane = createElement2([
|
|
15166
|
+
"div",
|
|
15167
|
+
{ class: `JSON_PAD_PANE JSON_PAD_PANE_${id.toUpperCase()}` },
|
|
14960
15168
|
[
|
|
14961
15169
|
[
|
|
14962
15170
|
"div",
|
|
@@ -14967,40 +15175,59 @@ function build_ui$11(gobj) {
|
|
|
14967
15175
|
[[
|
|
14968
15176
|
"div",
|
|
14969
15177
|
{ style: "flex:1 1 auto; min-width:0;" },
|
|
14970
|
-
[
|
|
15178
|
+
[pane.$input]
|
|
14971
15179
|
], [
|
|
14972
15180
|
"div",
|
|
14973
15181
|
{ style: "flex:0 0 auto; display:flex; flex-direction:column; gap:.5rem;" },
|
|
14974
|
-
[
|
|
15182
|
+
[pad_button(gobj, "JSON_PAD_VIEW", "yi-eye", "view", "EV_VIEW", { pane: id }), pad_button(gobj, "JSON_PAD_CLEAR", "yi-broom", "clear", "EV_CLEAR", { pane: id })]
|
|
14975
15183
|
]]
|
|
14976
15184
|
],
|
|
14977
|
-
|
|
14978
|
-
|
|
14979
|
-
"div",
|
|
14980
|
-
{
|
|
14981
|
-
class: "JSON_PAD_BODY",
|
|
14982
|
-
style: "flex:1 1 auto; min-height:0; display:flex; flex-direction:column;"
|
|
14983
|
-
},
|
|
14984
|
-
[]
|
|
14985
|
-
]
|
|
15185
|
+
pane.$error,
|
|
15186
|
+
pane.$body
|
|
14986
15187
|
],
|
|
14987
15188
|
{ paste: (evt) => {
|
|
14988
15189
|
let text = evt.clipboardData ? evt.clipboardData.getData("text") : "";
|
|
14989
15190
|
if (!text) return;
|
|
14990
15191
|
evt.preventDefault();
|
|
14991
|
-
gobj_send_event(gobj, "EV_PASTE", {
|
|
15192
|
+
gobj_send_event(gobj, "EV_PASTE", {
|
|
15193
|
+
pane: id,
|
|
15194
|
+
text
|
|
15195
|
+
}, gobj);
|
|
14992
15196
|
} }
|
|
14993
15197
|
]);
|
|
14994
|
-
|
|
15198
|
+
return pane;
|
|
14995
15199
|
}
|
|
14996
15200
|
/***************************************************************
|
|
14997
|
-
*
|
|
15201
|
+
* The pane a pane event names.
|
|
14998
15202
|
***************************************************************/
|
|
14999
|
-
function
|
|
15203
|
+
function pane_of(gobj, kw) {
|
|
15000
15204
|
let priv = gobj.priv;
|
|
15205
|
+
let id = kw ? kw.pane : void 0;
|
|
15206
|
+
if (!PANES.includes(id)) {
|
|
15207
|
+
log_error(`${gobj_short_name(gobj)}: no pane '${id}'`);
|
|
15208
|
+
return null;
|
|
15209
|
+
}
|
|
15210
|
+
return priv.panes[id];
|
|
15211
|
+
}
|
|
15212
|
+
/***************************************************************
|
|
15213
|
+
* A toggle of the toolbar, pressed or not -- for the eye and
|
|
15214
|
+
* for a reader.
|
|
15215
|
+
***************************************************************/
|
|
15216
|
+
function press_toggle(gobj, selector, on) {
|
|
15217
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
15218
|
+
set_pressed_state($container, selector, on);
|
|
15219
|
+
$container.querySelectorAll(selector).forEach(($el) => {
|
|
15220
|
+
$el.setAttribute("aria-pressed", on ? "true" : "false");
|
|
15221
|
+
});
|
|
15222
|
+
}
|
|
15223
|
+
/***************************************************************
|
|
15224
|
+
* Read `text` as JSON and show it in `pane`, or say why it is
|
|
15225
|
+
* not. A text that is not JSON leaves the last document up.
|
|
15226
|
+
***************************************************************/
|
|
15227
|
+
function show_text(gobj, pane, text) {
|
|
15001
15228
|
let src = String(text || "").trim();
|
|
15002
15229
|
if (!src) {
|
|
15003
|
-
|
|
15230
|
+
clear_pane(gobj, pane, false);
|
|
15004
15231
|
return 0;
|
|
15005
15232
|
}
|
|
15006
15233
|
let doc;
|
|
@@ -15008,63 +15235,328 @@ function show_text(gobj, text) {
|
|
|
15008
15235
|
doc = JSON.parse(src);
|
|
15009
15236
|
} catch (e) {
|
|
15010
15237
|
log_warning(`${gobj_short_name(gobj)}: the pasted text is not JSON: ${e.message}`);
|
|
15011
|
-
|
|
15012
|
-
|
|
15238
|
+
pane.$reason.textContent = e.message;
|
|
15239
|
+
pane.$error.classList.remove("is-hidden");
|
|
15240
|
+
return -1;
|
|
15241
|
+
}
|
|
15242
|
+
pane.$error.classList.add("is-hidden");
|
|
15243
|
+
pane.$reason.textContent = "";
|
|
15244
|
+
pane.doc = doc;
|
|
15245
|
+
pane.has_doc = true;
|
|
15246
|
+
gobj_send_event(pane.gobj_json, "EV_SET_JSON", { json: doc }, gobj);
|
|
15247
|
+
return 0;
|
|
15248
|
+
}
|
|
15249
|
+
/***************************************************************
|
|
15250
|
+
* A blank pane again; `with_text` empties the text area too.
|
|
15251
|
+
***************************************************************/
|
|
15252
|
+
function clear_pane(gobj, pane, with_text) {
|
|
15253
|
+
if (with_text) pane.$input.value = "";
|
|
15254
|
+
pane.$error.classList.add("is-hidden");
|
|
15255
|
+
pane.$reason.textContent = "";
|
|
15256
|
+
pane.doc = null;
|
|
15257
|
+
pane.has_doc = false;
|
|
15258
|
+
gobj_send_event(pane.gobj_json, "EV_SET_JSON", { json: null }, gobj);
|
|
15259
|
+
}
|
|
15260
|
+
/***************************************************************
|
|
15261
|
+
* A pane changed its document: the differences follow it, and
|
|
15262
|
+
* the texts are kept.
|
|
15263
|
+
***************************************************************/
|
|
15264
|
+
function document_changed(gobj) {
|
|
15265
|
+
if (gobj_current_state(gobj) === "ST_DIFF") render_diff(gobj);
|
|
15266
|
+
save_state(gobj);
|
|
15267
|
+
}
|
|
15268
|
+
/***************************************************************
|
|
15269
|
+
* Enter one of the three layouts. The state IS the layout;
|
|
15270
|
+
* this is what the screen shows for it.
|
|
15271
|
+
***************************************************************/
|
|
15272
|
+
function enter_layout(gobj, state) {
|
|
15273
|
+
let priv = gobj.priv;
|
|
15274
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
15275
|
+
let second = state !== "ST_SINGLE";
|
|
15276
|
+
let diff = state === "ST_DIFF";
|
|
15277
|
+
gobj_change_state(gobj, state);
|
|
15278
|
+
priv.panes.b.$pane.classList.toggle("is-hidden", !second);
|
|
15279
|
+
priv.$compare.classList.toggle("is-hidden", !second);
|
|
15280
|
+
press_toggle(gobj, ".JSON_PAD_SECOND", second);
|
|
15281
|
+
press_toggle(gobj, ".JSON_PAD_COMPARE", diff);
|
|
15282
|
+
$container.classList.toggle("is-comparing", diff);
|
|
15283
|
+
for (const id of PANES) priv.panes[id].$body.classList.toggle("is-hidden", diff);
|
|
15284
|
+
priv.$diff.classList.toggle("is-hidden", !diff);
|
|
15285
|
+
if (diff) render_diff(gobj);
|
|
15286
|
+
else for (const id of PANES) {
|
|
15287
|
+
if (id === "b" && !second) continue;
|
|
15288
|
+
gobj_send_event(priv.panes[id].gobj_json, "EV_REFRESH", {}, gobj);
|
|
15289
|
+
}
|
|
15290
|
+
save_state(gobj);
|
|
15291
|
+
}
|
|
15292
|
+
/***************************************************************
|
|
15293
|
+
* The differences of the two documents, in place of the two
|
|
15294
|
+
* viewers. Only a pane that shows a document takes part: a
|
|
15295
|
+
* text that is not JSON leaves its last document, as on screen.
|
|
15296
|
+
***************************************************************/
|
|
15297
|
+
function render_diff(gobj) {
|
|
15298
|
+
let priv = gobj.priv;
|
|
15299
|
+
let a = priv.panes.a;
|
|
15300
|
+
let b = priv.panes.b;
|
|
15301
|
+
priv.$diff.replaceChildren();
|
|
15302
|
+
if (!a.has_doc || !b.has_doc) {
|
|
15303
|
+
priv.$diff.appendChild(createElement2([
|
|
15304
|
+
"p",
|
|
15305
|
+
{
|
|
15306
|
+
class: "JSON_PAD_DIFF_MESSAGE",
|
|
15307
|
+
i18n: "compare needs two json"
|
|
15308
|
+
},
|
|
15309
|
+
"compare needs two json"
|
|
15310
|
+
]));
|
|
15311
|
+
return 0;
|
|
15312
|
+
}
|
|
15313
|
+
let rows;
|
|
15314
|
+
try {
|
|
15315
|
+
rows = json_diff_rows(a.doc, b.doc);
|
|
15316
|
+
} catch (e) {
|
|
15317
|
+
log_warning(`${gobj_short_name(gobj)}: cannot compare: ${e.message}`);
|
|
15318
|
+
priv.$diff.appendChild(createElement2([
|
|
15319
|
+
"p",
|
|
15320
|
+
{ class: "JSON_PAD_DIFF_MESSAGE has-text-danger" },
|
|
15321
|
+
[[
|
|
15322
|
+
"span",
|
|
15323
|
+
{
|
|
15324
|
+
style: "font-weight:600;",
|
|
15325
|
+
i18n: "cannot compare"
|
|
15326
|
+
},
|
|
15327
|
+
"cannot compare"
|
|
15328
|
+
], [
|
|
15329
|
+
"span",
|
|
15330
|
+
{
|
|
15331
|
+
class: "JSON_PAD_DIFF_REASON",
|
|
15332
|
+
style: "margin-left:.5em; font-family:monospace;"
|
|
15333
|
+
},
|
|
15334
|
+
e.message
|
|
15335
|
+
]]
|
|
15336
|
+
]));
|
|
15013
15337
|
return -1;
|
|
15014
15338
|
}
|
|
15015
|
-
|
|
15016
|
-
|
|
15017
|
-
|
|
15018
|
-
|
|
15339
|
+
if (rows.length === 0) {
|
|
15340
|
+
priv.$diff.appendChild(createElement2([
|
|
15341
|
+
"p",
|
|
15342
|
+
{
|
|
15343
|
+
class: "JSON_PAD_DIFF_MESSAGE has-text-success",
|
|
15344
|
+
i18n: "no differences"
|
|
15345
|
+
},
|
|
15346
|
+
"no differences"
|
|
15347
|
+
]));
|
|
15348
|
+
return 0;
|
|
15349
|
+
}
|
|
15350
|
+
let count = {
|
|
15351
|
+
added: 0,
|
|
15352
|
+
removed: 0,
|
|
15353
|
+
changed: 0
|
|
15354
|
+
};
|
|
15355
|
+
for (const row of rows) count[row.kind]++;
|
|
15356
|
+
let value_cell = (cls, row, side) => {
|
|
15357
|
+
let has = Object.prototype.hasOwnProperty.call(row, side);
|
|
15358
|
+
return [
|
|
15359
|
+
"td",
|
|
15360
|
+
{ class: cls },
|
|
15361
|
+
has ? JSON.stringify(row[side]) : ""
|
|
15362
|
+
];
|
|
15363
|
+
};
|
|
15364
|
+
priv.$diff.appendChild(createElement2([
|
|
15365
|
+
"div",
|
|
15366
|
+
{ class: "JSON_PAD_DIFF_SUMMARY" },
|
|
15367
|
+
[
|
|
15368
|
+
"removed",
|
|
15369
|
+
"added",
|
|
15370
|
+
"changed"
|
|
15371
|
+
].map((kind) => {
|
|
15372
|
+
return [
|
|
15373
|
+
"span",
|
|
15374
|
+
{ class: "JSON_PAD_DIFF_COUNT" },
|
|
15375
|
+
[KIND_TAG[kind](), [
|
|
15376
|
+
"strong",
|
|
15377
|
+
{},
|
|
15378
|
+
String(count[kind])
|
|
15379
|
+
]]
|
|
15380
|
+
];
|
|
15381
|
+
})
|
|
15382
|
+
]));
|
|
15383
|
+
priv.$diff.appendChild(createElement2([
|
|
15384
|
+
"table",
|
|
15385
|
+
{ class: "JSON_PAD_DIFF_TABLE table is-fullwidth is-narrow is-hoverable" },
|
|
15386
|
+
[[
|
|
15387
|
+
"thead",
|
|
15388
|
+
{},
|
|
15389
|
+
[[
|
|
15390
|
+
"tr",
|
|
15391
|
+
{},
|
|
15392
|
+
[
|
|
15393
|
+
[
|
|
15394
|
+
"th",
|
|
15395
|
+
{},
|
|
15396
|
+
""
|
|
15397
|
+
],
|
|
15398
|
+
[
|
|
15399
|
+
"th",
|
|
15400
|
+
{ i18n: "path" },
|
|
15401
|
+
"path"
|
|
15402
|
+
],
|
|
15403
|
+
[
|
|
15404
|
+
"th",
|
|
15405
|
+
{ i18n: "first json" },
|
|
15406
|
+
"first json"
|
|
15407
|
+
],
|
|
15408
|
+
[
|
|
15409
|
+
"th",
|
|
15410
|
+
{ i18n: "second json" },
|
|
15411
|
+
"second json"
|
|
15412
|
+
]
|
|
15413
|
+
]
|
|
15414
|
+
]]
|
|
15415
|
+
], [
|
|
15416
|
+
"tbody",
|
|
15417
|
+
{},
|
|
15418
|
+
rows.map((row) => {
|
|
15419
|
+
return [
|
|
15420
|
+
"tr",
|
|
15421
|
+
{ class: `JSON_PAD_DIFF_ROW JSON_PAD_DIFF_${row.kind.toUpperCase()}` },
|
|
15422
|
+
[
|
|
15423
|
+
[
|
|
15424
|
+
"td",
|
|
15425
|
+
{},
|
|
15426
|
+
[KIND_TAG[row.kind]()]
|
|
15427
|
+
],
|
|
15428
|
+
[
|
|
15429
|
+
"td",
|
|
15430
|
+
{ class: "JSON_PAD_DIFF_PATH" },
|
|
15431
|
+
row.id
|
|
15432
|
+
],
|
|
15433
|
+
value_cell("JSON_PAD_DIFF_FROM", row, "from"),
|
|
15434
|
+
value_cell("JSON_PAD_DIFF_TO", row, "to")
|
|
15435
|
+
]
|
|
15436
|
+
];
|
|
15437
|
+
})
|
|
15438
|
+
]]
|
|
15439
|
+
]));
|
|
15019
15440
|
return 0;
|
|
15020
15441
|
}
|
|
15021
15442
|
/***************************************************************
|
|
15022
|
-
*
|
|
15443
|
+
* Keep both texts and the layout.
|
|
15023
15444
|
***************************************************************/
|
|
15024
|
-
function
|
|
15445
|
+
function save_state(gobj) {
|
|
15025
15446
|
let priv = gobj.priv;
|
|
15026
|
-
|
|
15027
|
-
|
|
15028
|
-
|
|
15029
|
-
|
|
15030
|
-
|
|
15447
|
+
let key = gobj_read_str_attr(gobj, "storage_key");
|
|
15448
|
+
if (!key) return 0;
|
|
15449
|
+
let ret = kw_set_local_storage_value(key, {
|
|
15450
|
+
a: priv.panes.a.$input.value,
|
|
15451
|
+
b: priv.panes.b.$input.value,
|
|
15452
|
+
mode: MODE_OF_STATE[gobj_current_state(gobj)] || "single"
|
|
15453
|
+
});
|
|
15454
|
+
priv.$notice.classList.toggle("is-hidden", ret === 0);
|
|
15455
|
+
return ret;
|
|
15456
|
+
}
|
|
15457
|
+
/***************************************************************
|
|
15458
|
+
* The pad as the last one was left: its texts, shown, and its
|
|
15459
|
+
* layout -- through the same events a reader would send.
|
|
15460
|
+
***************************************************************/
|
|
15461
|
+
function restore_state(gobj) {
|
|
15462
|
+
let priv = gobj.priv;
|
|
15463
|
+
let key = gobj_read_str_attr(gobj, "storage_key");
|
|
15464
|
+
if (!key) return 0;
|
|
15465
|
+
let kept = kw_get_local_storage_value(key, null, false);
|
|
15466
|
+
if (kept === null || kept === void 0) return 0;
|
|
15467
|
+
if (typeof kept !== "object" || Array.isArray(kept)) {
|
|
15468
|
+
log_warning(`${gobj_short_name(gobj)}: '${key}' in localStorage is not what the pad keeps`);
|
|
15469
|
+
return -1;
|
|
15470
|
+
}
|
|
15471
|
+
for (const id of PANES) if (typeof kept[id] === "string") priv.panes[id].$input.value = kept[id];
|
|
15472
|
+
for (const id of PANES) if (priv.panes[id].$input.value.trim()) gobj_send_event(gobj, "EV_VIEW", { pane: id }, gobj);
|
|
15473
|
+
if (kept.mode === "dual" || kept.mode === "diff") gobj_send_event(gobj, "EV_TOGGLE_SECOND", {}, gobj);
|
|
15474
|
+
if (kept.mode === "diff") gobj_send_event(gobj, "EV_TOGGLE_DIFF", {}, gobj);
|
|
15475
|
+
return 0;
|
|
15031
15476
|
}
|
|
15032
15477
|
/***************************
|
|
15033
15478
|
* Actions
|
|
15034
15479
|
***************************/
|
|
15035
15480
|
/***************************************************************
|
|
15036
|
-
* A paste: it becomes the text area and
|
|
15481
|
+
* A paste: it becomes the pane's text area and its document
|
|
15482
|
+
* at once.
|
|
15037
15483
|
***************************************************************/
|
|
15038
15484
|
function ac_paste(gobj, event, kw, src) {
|
|
15039
|
-
let
|
|
15040
|
-
|
|
15041
|
-
|
|
15042
|
-
|
|
15485
|
+
let pane = pane_of(gobj, kw);
|
|
15486
|
+
if (!pane) return -1;
|
|
15487
|
+
let text = typeof kw.text === "string" ? kw.text : "";
|
|
15488
|
+
pane.$input.value = text;
|
|
15489
|
+
let ret = show_text(gobj, pane, text);
|
|
15490
|
+
document_changed(gobj);
|
|
15491
|
+
return ret;
|
|
15043
15492
|
}
|
|
15044
15493
|
/***************************************************************
|
|
15045
|
-
* The text area as it is now.
|
|
15494
|
+
* The pane's text area as it is now.
|
|
15046
15495
|
***************************************************************/
|
|
15047
15496
|
function ac_view(gobj, event, kw, src) {
|
|
15048
|
-
let
|
|
15049
|
-
|
|
15497
|
+
let pane = pane_of(gobj, kw);
|
|
15498
|
+
if (!pane) return -1;
|
|
15499
|
+
let ret = show_text(gobj, pane, pane.$input.value);
|
|
15500
|
+
document_changed(gobj);
|
|
15501
|
+
return ret;
|
|
15050
15502
|
}
|
|
15051
15503
|
/***************************************************************
|
|
15052
|
-
*
|
|
15504
|
+
* A blank pane again.
|
|
15053
15505
|
***************************************************************/
|
|
15054
15506
|
function ac_clear(gobj, event, kw, src) {
|
|
15507
|
+
let pane = pane_of(gobj, kw);
|
|
15508
|
+
if (!pane) return -1;
|
|
15509
|
+
clear_pane(gobj, pane, true);
|
|
15510
|
+
pane.$input.focus();
|
|
15511
|
+
document_changed(gobj);
|
|
15512
|
+
return 0;
|
|
15513
|
+
}
|
|
15514
|
+
/***************************************************************
|
|
15515
|
+
* A text area was edited and left: keep what it holds. What
|
|
15516
|
+
* is SHOWN changes only with a view, as before.
|
|
15517
|
+
***************************************************************/
|
|
15518
|
+
function ac_text_changed(gobj, event, kw, src) {
|
|
15519
|
+
if (!pane_of(gobj, kw)) return -1;
|
|
15520
|
+
save_state(gobj);
|
|
15521
|
+
return 0;
|
|
15522
|
+
}
|
|
15523
|
+
/***************************************************************
|
|
15524
|
+
* The second pane, beside the first.
|
|
15525
|
+
***************************************************************/
|
|
15526
|
+
function ac_show_second(gobj, event, kw, src) {
|
|
15055
15527
|
let priv = gobj.priv;
|
|
15056
|
-
|
|
15057
|
-
priv.$input.focus();
|
|
15528
|
+
enter_layout(gobj, "ST_DUAL");
|
|
15529
|
+
priv.panes.b.$input.focus();
|
|
15530
|
+
return 0;
|
|
15531
|
+
}
|
|
15532
|
+
/***************************************************************
|
|
15533
|
+
* One pane again. Its text is kept: hiding is not clearing.
|
|
15534
|
+
***************************************************************/
|
|
15535
|
+
function ac_hide_second(gobj, event, kw, src) {
|
|
15536
|
+
enter_layout(gobj, "ST_SINGLE");
|
|
15058
15537
|
return 0;
|
|
15059
15538
|
}
|
|
15060
15539
|
/***************************************************************
|
|
15061
|
-
* The
|
|
15540
|
+
* The differences, in place of the viewers.
|
|
15541
|
+
***************************************************************/
|
|
15542
|
+
function ac_show_diff(gobj, event, kw, src) {
|
|
15543
|
+
enter_layout(gobj, "ST_DIFF");
|
|
15544
|
+
return 0;
|
|
15545
|
+
}
|
|
15546
|
+
/***************************************************************
|
|
15547
|
+
* The viewers again.
|
|
15548
|
+
***************************************************************/
|
|
15549
|
+
function ac_hide_diff(gobj, event, kw, src) {
|
|
15550
|
+
enter_layout(gobj, "ST_DUAL");
|
|
15551
|
+
return 0;
|
|
15552
|
+
}
|
|
15553
|
+
/***************************************************************
|
|
15554
|
+
* A viewer asks for a `__collapsed__` subtree. A pasted
|
|
15062
15555
|
* document has no backend to ask for it: the SOURCE truncated
|
|
15063
|
-
* it, and that is the answer.
|
|
15556
|
+
* it, and that is the answer, to the viewer that asked.
|
|
15064
15557
|
***************************************************************/
|
|
15065
15558
|
function ac_expand_path(gobj, event, kw, src) {
|
|
15066
|
-
|
|
15067
|
-
gobj_send_event(priv.gobj_json, "EV_SUBTREE_ERROR", {
|
|
15559
|
+
gobj_send_event(src, "EV_SUBTREE_ERROR", {
|
|
15068
15560
|
path: kw && kw.path || "",
|
|
15069
15561
|
error: t("collapsed in the source")
|
|
15070
15562
|
}, gobj);
|
|
@@ -15091,45 +15583,113 @@ function create_gclass$12(gclass_name) {
|
|
|
15091
15583
|
["EV_PASTE", 0],
|
|
15092
15584
|
["EV_VIEW", 0],
|
|
15093
15585
|
["EV_CLEAR", 0],
|
|
15586
|
+
["EV_TEXT_CHANGED", 0],
|
|
15587
|
+
["EV_TOGGLE_SECOND", 0],
|
|
15588
|
+
["EV_TOGGLE_DIFF", 0],
|
|
15094
15589
|
["EV_EXPAND_PATH", 0]
|
|
15095
|
-
], [
|
|
15096
|
-
[
|
|
15097
|
-
|
|
15098
|
-
|
|
15099
|
-
|
|
15100
|
-
|
|
15101
|
-
|
|
15102
|
-
|
|
15103
|
-
|
|
15104
|
-
|
|
15105
|
-
|
|
15106
|
-
|
|
15107
|
-
|
|
15108
|
-
|
|
15109
|
-
|
|
15110
|
-
|
|
15111
|
-
|
|
15112
|
-
|
|
15113
|
-
|
|
15114
|
-
|
|
15115
|
-
|
|
15116
|
-
|
|
15117
|
-
|
|
15118
|
-
|
|
15119
|
-
|
|
15120
|
-
|
|
15121
|
-
|
|
15122
|
-
|
|
15123
|
-
|
|
15124
|
-
|
|
15125
|
-
|
|
15126
|
-
|
|
15127
|
-
|
|
15128
|
-
|
|
15129
|
-
|
|
15130
|
-
|
|
15131
|
-
|
|
15132
|
-
|
|
15590
|
+
], [
|
|
15591
|
+
["ST_SINGLE", [
|
|
15592
|
+
[
|
|
15593
|
+
"EV_PASTE",
|
|
15594
|
+
ac_paste,
|
|
15595
|
+
null
|
|
15596
|
+
],
|
|
15597
|
+
[
|
|
15598
|
+
"EV_VIEW",
|
|
15599
|
+
ac_view,
|
|
15600
|
+
null
|
|
15601
|
+
],
|
|
15602
|
+
[
|
|
15603
|
+
"EV_CLEAR",
|
|
15604
|
+
ac_clear,
|
|
15605
|
+
null
|
|
15606
|
+
],
|
|
15607
|
+
[
|
|
15608
|
+
"EV_TEXT_CHANGED",
|
|
15609
|
+
ac_text_changed,
|
|
15610
|
+
null
|
|
15611
|
+
],
|
|
15612
|
+
[
|
|
15613
|
+
"EV_TOGGLE_SECOND",
|
|
15614
|
+
ac_show_second,
|
|
15615
|
+
null
|
|
15616
|
+
],
|
|
15617
|
+
[
|
|
15618
|
+
"EV_EXPAND_PATH",
|
|
15619
|
+
ac_expand_path,
|
|
15620
|
+
null
|
|
15621
|
+
]
|
|
15622
|
+
]],
|
|
15623
|
+
["ST_DUAL", [
|
|
15624
|
+
[
|
|
15625
|
+
"EV_PASTE",
|
|
15626
|
+
ac_paste,
|
|
15627
|
+
null
|
|
15628
|
+
],
|
|
15629
|
+
[
|
|
15630
|
+
"EV_VIEW",
|
|
15631
|
+
ac_view,
|
|
15632
|
+
null
|
|
15633
|
+
],
|
|
15634
|
+
[
|
|
15635
|
+
"EV_CLEAR",
|
|
15636
|
+
ac_clear,
|
|
15637
|
+
null
|
|
15638
|
+
],
|
|
15639
|
+
[
|
|
15640
|
+
"EV_TEXT_CHANGED",
|
|
15641
|
+
ac_text_changed,
|
|
15642
|
+
null
|
|
15643
|
+
],
|
|
15644
|
+
[
|
|
15645
|
+
"EV_TOGGLE_SECOND",
|
|
15646
|
+
ac_hide_second,
|
|
15647
|
+
null
|
|
15648
|
+
],
|
|
15649
|
+
[
|
|
15650
|
+
"EV_TOGGLE_DIFF",
|
|
15651
|
+
ac_show_diff,
|
|
15652
|
+
null
|
|
15653
|
+
],
|
|
15654
|
+
[
|
|
15655
|
+
"EV_EXPAND_PATH",
|
|
15656
|
+
ac_expand_path,
|
|
15657
|
+
null
|
|
15658
|
+
]
|
|
15659
|
+
]],
|
|
15660
|
+
["ST_DIFF", [
|
|
15661
|
+
[
|
|
15662
|
+
"EV_PASTE",
|
|
15663
|
+
ac_paste,
|
|
15664
|
+
null
|
|
15665
|
+
],
|
|
15666
|
+
[
|
|
15667
|
+
"EV_VIEW",
|
|
15668
|
+
ac_view,
|
|
15669
|
+
null
|
|
15670
|
+
],
|
|
15671
|
+
[
|
|
15672
|
+
"EV_CLEAR",
|
|
15673
|
+
ac_clear,
|
|
15674
|
+
null
|
|
15675
|
+
],
|
|
15676
|
+
[
|
|
15677
|
+
"EV_TEXT_CHANGED",
|
|
15678
|
+
ac_text_changed,
|
|
15679
|
+
null
|
|
15680
|
+
],
|
|
15681
|
+
[
|
|
15682
|
+
"EV_TOGGLE_SECOND",
|
|
15683
|
+
ac_hide_second,
|
|
15684
|
+
null
|
|
15685
|
+
],
|
|
15686
|
+
[
|
|
15687
|
+
"EV_TOGGLE_DIFF",
|
|
15688
|
+
ac_hide_diff,
|
|
15689
|
+
null
|
|
15690
|
+
]
|
|
15691
|
+
]]
|
|
15692
|
+
], gmt$12, 0, attrs_table$12, PRIVATE_DATA$12, 0, 0, 0, 0);
|
|
15133
15693
|
if (!__gclass__$12) return -1;
|
|
15134
15694
|
return 0;
|
|
15135
15695
|
}
|