Check-in [0ba3f6e997]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:improve twv demo
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0ba3f6e99740ccb2de3fe1b1a28a777aed6fc694
User & Date: chw 2019-06-15 06:09:38
Context
2019-06-16
06:22
add tcl upstream changes check-in: b0959def3b user: chw tags: trunk
2019-06-15
06:11
merge with trunk check-in: 9c76ebe46f user: chw tags: wtf-8-experiment
06:09
improve twv demo check-in: 0ba3f6e997 user: chw tags: trunk
06:09
minor fix in plotchart check-in: d34dee0c49 user: chw tags: trunk
Changes

Changes to undroid/tsb/tsb.tcl.

217
218
219
220
221
222
223

224
225
226
227
228
229
230
231
...
299
300
301
302
303
304
305

306
307
308
309
310
311
312
...
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
...
967
968
969
970
971
972
973

974
975
976
977

978
979
980
981
982
983
984
985
....
1020
1021
1022
1023
1024
1025
1026









1027
1028
1029
1030
1031
1032
1033
....
1037
1038
1039
1040
1041
1042
1043


1044
1045




1046
1047
1048
1049
1050
1051

1052

1053


1054
1055
1056
1057
1058
1059
1060
....
1061
1062
1063
1064
1065
1066
1067
1068

1069
1070
1071
1072
1073
1074
1075
    if {$name eq ""} {
	return
    }
    # This needs work.
    if {$mime ne ""} {
	set mime [::tsb::htmlquote $mime]
    } else {

	set mime image/[string tolower [file extension $name]]
    }
    if {![catch {open $name rb} f]} {
	set ret "<img style='margin: 1em;' src='data:$mime;base64,\n"
	append ret [binary encode base64 -maxlen 78 [read $f]]
	append ret "'>\n"
	close $f
	if {$selname || $import} {
................................................................................
	incr next
	set ::H($next) ""
	::tsb::call_from_js "$key $h($key)"
    }
    if {[info exists next]} {
	unset ::H($next)
    }

    after cancel ::tsb::reload0
    set inload 0
}

proc ::tsb::save {{name {}}} {
    variable inload
    if {$inload} {
................................................................................
    set count 10
    while {$count > 0} {
	incr count -1
	$::W loop 0
	if {$dump ne ""} {
	    break
	}
	after 10 [set ::tsb::dump $::tsb::dump]
	vwait [namespace current]::dump

    }
    return $dump
}

# Write HTML to file.

proc ::tsb::wrhtml {{name {}}} {
................................................................................
	    needsClear[id] = true;
	    RunTcl("" + id + " " + input.value);
	};

	var Field = function(id) {
	    var div = document.createElement('div');
	    div.className = 'field';

	    var html = '\n <div class="infield" id="in' + id + '">';
	    html += '\n  <label for="code' + id + '">in(' + id + ')</label>';
	    html += '\n  <textarea class="tin" id="code' + id + '" rows="1"';
	    html += '></textarea>\n </div>\n <div';

	    html += ' id="out' + id + '-pre">';
	    html += '<pre></pre></div>';
	    html += '\n <div id="out' + id + '-raw"></div>\n';
	    div.innerHTML = html;
	    document.body.appendChild(div);
	    /* For better readability only. */
	    document.body.appendChild(document.createTextNode('\n'));
	    needsClear[id] = null;
................................................................................
	var InitField = function(id, str) {
	    var input = Field(id);
	    input.value = str;
	    var lines = str.split(/\r?\n|\r/);
	    var nlines = (lines.length < 43) ? lines.length : 43;
	    input.rows = nlines;
	};










	var ClearFields = function() {
	    while (1) {
		var fields = document.getElementsByClassName('field');
		if (fields.length > 0) {
		    fields[0].parentNode.removeChild(fields[0]);
		    continue;
................................................................................
	};

	var Dump = function() {
	    var i;
	    var values = new Array();
	    var fields = document.getElementsByClassName('tin');
	    for (i = 0; i < fields.length; i++) {


		values[i] = fields[i].value;
		fields[i].innerHTML = values[i];




		fields[i].disabled = true;
	    }
	    window.external.invoke(document.body.innerHTML);
	    fields = document.getElementsByClassName('tin');
	    for (i = 0; i < fields.length; i++) {
		fields[i].disabled = false;

		fields[i].innerHTML = "";

		fields[i].value = values[i];


	    }
	};

	/* Is this really needed? */
	window.addEventListener('unload', function(event) {
	    window.clearInterval(Gtimer);
	    Gtimer = null;
................................................................................
	});

	</script>
    }

    # Assemble pieces with empty BODY.
    set D $D_head
    append D $D_style $D_script {</head><body></body></html>}


    # The URL to be displayed.
    # Windows:   data:text/html,<html><head><script>window.external.invoke("0 ::tsb::reload");</script></head></html>
    # MacOS:     data:text/html,<html><head><script>window.external.invoke("0 ::tsb::reload");</script></head></html>
    # WebkitGtk: data:text/html,<html><head><script>window.webkit.messageHandlers.extern.postMessage("0 ::tsb::reload");</script></head></html>

    variable U







>
|







 







>







 







|
|
>







 







>
|


|
>
|







 







>
>
>
>
>
>
>
>
>







 







>
>
|
|
>
>
>
>






>
|
>
|
>
>







 







|
>







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
...
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
...
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
....
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
....
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
....
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
    if {$name eq ""} {
	return
    }
    # This needs work.
    if {$mime ne ""} {
	set mime [::tsb::htmlquote $mime]
    } else {
	set ext [string tolower [string trimleft [file extension $name] "."]]
	set mime image/$ext
    }
    if {![catch {open $name rb} f]} {
	set ret "<img style='margin: 1em;' src='data:$mime;base64,\n"
	append ret [binary encode base64 -maxlen 78 [read $f]]
	append ret "'>\n"
	close $f
	if {$selname || $import} {
................................................................................
	incr next
	set ::H($next) ""
	::tsb::call_from_js "$key $h($key)"
    }
    if {[info exists next]} {
	unset ::H($next)
    }
    $::W call GotoTop
    after cancel ::tsb::reload0
    set inload 0
}

proc ::tsb::save {{name {}}} {
    variable inload
    if {$inload} {
................................................................................
    set count 10
    while {$count > 0} {
	incr count -1
	$::W loop 0
	if {$dump ne ""} {
	    break
	}
	set var [namespace current]::dump
	after 10 [subst -nocommands {set $var [set $var]}]
	vwait $var
    }
    return $dump
}

# Write HTML to file.

proc ::tsb::wrhtml {{name {}}} {
................................................................................
	    needsClear[id] = true;
	    RunTcl("" + id + " " + input.value);
	};

	var Field = function(id) {
	    var div = document.createElement('div');
	    div.className = 'field';
	    var html = '\n <a href="#in' + id + '"></a>';
	    html += '\n <div class="infield" id="in' + id + '">';
	    html += '\n  <label for="code' + id + '">in(' + id + ')</label>';
	    html += '\n  <textarea class="tin" id="code' + id + '" rows="1"';
	    html += '></textarea>\n </div>';
	    html += '\n <a href="#out' + id + '"></a>';
	    html += '\n <div id="out' + id + '-pre">';
	    html += '<pre></pre></div>';
	    html += '\n <div id="out' + id + '-raw"></div>\n';
	    div.innerHTML = html;
	    document.body.appendChild(div);
	    /* For better readability only. */
	    document.body.appendChild(document.createTextNode('\n'));
	    needsClear[id] = null;
................................................................................
	var InitField = function(id, str) {
	    var input = Field(id);
	    input.value = str;
	    var lines = str.split(/\r?\n|\r/);
	    var nlines = (lines.length < 43) ? lines.length : 43;
	    input.rows = nlines;
	};

	var GotoTop = function() {
	    window.location.href = "#top";
	};

	var GotoField = function(id, isout) {
	    var href = (isout ? "#out" : "#in") + id;
	    window.location.href = href;
	};

	var ClearFields = function() {
	    while (1) {
		var fields = document.getElementsByClassName('field');
		if (fields.length > 0) {
		    fields[0].parentNode.removeChild(fields[0]);
		    continue;
................................................................................
	};

	var Dump = function() {
	    var i;
	    var values = new Array();
	    var fields = document.getElementsByClassName('tin');
	    for (i = 0; i < fields.length; i++) {
		if (fields[i].parentNode.style.display !== 'none') {
 		    if (msLike) {
			values[i] = fields[i].value;
			fields[i].innerHTML = values[i];
		    } else {
			fields[i].innerHTML = fields[i].value;
		    }
		}
		fields[i].disabled = true;
	    }
	    window.external.invoke(document.body.innerHTML);
	    fields = document.getElementsByClassName('tin');
	    for (i = 0; i < fields.length; i++) {
		fields[i].disabled = false;
		if (fields[i].parentNode.style.display !== 'none') {
		    fields[i].innerHTML = "";
		    if (msLike) {
			fields[i].value = values[i];
		    }
		}
	    }
	};

	/* Is this really needed? */
	window.addEventListener('unload', function(event) {
	    window.clearInterval(Gtimer);
	    Gtimer = null;
................................................................................
	});

	</script>
    }

    # Assemble pieces with empty BODY.
    set D $D_head
    append D $D_style $D_script \
	{</head><body><a href="#top"></a></body></html>}

    # The URL to be displayed.
    # Windows:   data:text/html,<html><head><script>window.external.invoke("0 ::tsb::reload");</script></head></html>
    # MacOS:     data:text/html,<html><head><script>window.external.invoke("0 ::tsb::reload");</script></head></html>
    # WebkitGtk: data:text/html,<html><head><script>window.webkit.messageHandlers.extern.postMessage("0 ::tsb::reload");</script></head></html>

    variable U

Changes to undroid/twv/twv.c.

66
67
68
69
70
71
72
73
74
75
76


77
78
79
80
81
82
83
..
89
90
91
92
93
94
95
96
97
98
99


100
101
102
103
104
105
106
...
370
371
372
373
374
375
376

377
378


379
380
381
382
383
384
385
386

387
388
389

390
391
392
393
394
395
396
    ret = Tcl_EvalEx(interp, Tcl_DStringValue(&dsc),
		     Tcl_DStringLength(&dsc), TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&dsc);
    if (ret != TCL_OK) {
        Tcl_AddErrorInfo(interp, "\n    (twv callback handler)");
        Tcl_BackgroundException(interp, ret);
    }
    Tcl_Release((ClientData) interp);
    while (Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT)) {
	/* empty loop body */
    }


}

static void
TwvDispatchCB(struct webview *w, void *arg)
{
    char *script = (char *) arg;
    Tcl_Interp *interp = (Tcl_Interp *) w->userdata;
................................................................................
    Tcl_Preserve((ClientData) interp);
    ret = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
    Tcl_Free(script);
    if (ret != TCL_OK) {
        Tcl_AddErrorInfo(interp, "\n    (twv dispatch handler)");
        Tcl_BackgroundException(interp, ret);
    }
    Tcl_Release((ClientData) interp);
    while (Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT)) {
	/* empty loop body */
    }


}

static int
TwvInstObjCmd(ClientData clientData, Tcl_Interp *interp,
	      int objc, Tcl_Obj * const objv[])
{
    struct twebview *tw = (struct twebview *) clientData;
................................................................................
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "bool");
            return TCL_ERROR;
        }
	if (Tcl_GetBooleanFromObj(interp, objv[2], &flag) != TCL_OK) {
	    return TCL_ERROR;
	}

	flag = (webview_loop(&tw->w, flag) != 0);
	Tcl_SetBooleanObj(Tcl_GetObjResult(interp), flag);


	break;
    }

    case CMD_run: {
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
            return TCL_ERROR;
        }

	while (webview_loop(&tw->w, 1) == 0) {
	    /* Empty loop body. */
	}

	break;
    }

    case CMD_terminate: {
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
            return TCL_ERROR;







<



>
>







 







<



>
>







 







>

<
>
>








>



>







66
67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
..
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
...
372
373
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
    ret = Tcl_EvalEx(interp, Tcl_DStringValue(&dsc),
		     Tcl_DStringLength(&dsc), TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&dsc);
    if (ret != TCL_OK) {
        Tcl_AddErrorInfo(interp, "\n    (twv callback handler)");
        Tcl_BackgroundException(interp, ret);
    }

    while (Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT)) {
	/* empty loop body */
    }
    Tcl_ResetResult(interp);
    Tcl_Release((ClientData) interp);
}

static void
TwvDispatchCB(struct webview *w, void *arg)
{
    char *script = (char *) arg;
    Tcl_Interp *interp = (Tcl_Interp *) w->userdata;
................................................................................
    Tcl_Preserve((ClientData) interp);
    ret = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
    Tcl_Free(script);
    if (ret != TCL_OK) {
        Tcl_AddErrorInfo(interp, "\n    (twv dispatch handler)");
        Tcl_BackgroundException(interp, ret);
    }

    while (Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT)) {
	/* empty loop body */
    }
    Tcl_ResetResult(interp);
    Tcl_Release((ClientData) interp);
}

static int
TwvInstObjCmd(ClientData clientData, Tcl_Interp *interp,
	      int objc, Tcl_Obj * const objv[])
{
    struct twebview *tw = (struct twebview *) clientData;
................................................................................
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "bool");
            return TCL_ERROR;
        }
	if (Tcl_GetBooleanFromObj(interp, objv[2], &flag) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_Preserve((ClientData) interp);
	flag = (webview_loop(&tw->w, flag) != 0);

	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(flag));
	Tcl_Release((ClientData) interp);
	break;
    }

    case CMD_run: {
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
            return TCL_ERROR;
        }
	Tcl_Preserve((ClientData) interp);
	while (webview_loop(&tw->w, 1) == 0) {
	    /* Empty loop body. */
	}
	Tcl_Release((ClientData) interp);
	break;
    }

    case CMD_terminate: {
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
            return TCL_ERROR;