mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-21 19:25:35 -05:00
Restore output attribute of py-script tags, add py-script exec lifecycle hooks (#1063)
* Add beforePyScriptExec, afterPyScriptExec lifecycle hooks * Add stdiodirector plugin for `output`, `stderr` attributes of py-script tag * Add docs on `output` and `stderr` attributes of py-script tag * Tests * Removed output deprecation warning for `output` attribute * Add createSingularWarning(), with createDeprecationWarning as alias
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { createSingularWarning, escape } from "./utils";
|
||||
|
||||
export interface Stdio {
|
||||
stdout_writeline: (msg: string) => void;
|
||||
stderr_writeline: (msg: string) => void;
|
||||
@@ -36,6 +38,63 @@ export class CaptureStdio implements Stdio {
|
||||
}
|
||||
}
|
||||
|
||||
/** Stdio provider for sending output to DOM element
|
||||
* specified by ID. Used with "output" keyword.
|
||||
*
|
||||
*/
|
||||
export class TargetedStdio implements Stdio{
|
||||
|
||||
source_element: HTMLElement;
|
||||
source_attribute: string;
|
||||
capture_stdout: boolean;
|
||||
capture_stderr: boolean;
|
||||
|
||||
constructor(source_element: HTMLElement, source_attribute: string, capture_stdout = true, capture_stderr = true) {
|
||||
this.source_element = source_element;
|
||||
this.source_attribute = source_attribute;
|
||||
this.capture_stdout = capture_stdout;
|
||||
this.capture_stderr = capture_stderr;
|
||||
}
|
||||
|
||||
/** Writes the given msg to an element with a given ID. The ID is the value an attribute
|
||||
* of the source_element specified by source_attribute.
|
||||
* Both the element to be targeted and the ID of the element to write to
|
||||
* are determined at write-time, not when the TargetdStdio object is
|
||||
* created. This way, if either the 'output' attribute of the HTML tag
|
||||
* or the ID of the target element changes during execution of the Python
|
||||
* code, the output is still routed (or not) as expected
|
||||
*
|
||||
* @param msg The output to be written
|
||||
*/
|
||||
writeline_by_attribute(msg:string){
|
||||
const target_id = this.source_element.getAttribute(this.source_attribute)
|
||||
const target = document.getElementById(target_id)
|
||||
if (target === null) { // No matching ID
|
||||
createSingularWarning(`${this.source_attribute} = "${target_id}" does not match the id of any element on the page.`)
|
||||
}
|
||||
else {
|
||||
msg = escape(msg).replace("\n", "<br>")
|
||||
if (!msg.endsWith("<br/>") && !msg.endsWith("<br>")){
|
||||
msg = msg + "<br>"
|
||||
}
|
||||
target.innerHTML += msg
|
||||
}
|
||||
}
|
||||
|
||||
stdout_writeline (msg: string) {
|
||||
if (this.capture_stdout){
|
||||
this.writeline_by_attribute(msg)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
stderr_writeline (msg: string) {
|
||||
if (this.capture_stderr){
|
||||
this.writeline_by_attribute(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Redirect stdio streams to multiple listeners
|
||||
*/
|
||||
export class StdioMultiplexer implements Stdio {
|
||||
@@ -49,6 +108,13 @@ export class StdioMultiplexer implements Stdio {
|
||||
this._listeners.push(obj);
|
||||
}
|
||||
|
||||
removeListener(obj: Stdio) {
|
||||
const index = this._listeners.indexOf(obj)
|
||||
if (index > -1){
|
||||
this._listeners.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
stdout_writeline(msg: string) {
|
||||
for (const obj of this._listeners) obj.stdout_writeline(msg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user