8000 Fix #1429 - Use basic-devtools module (#1430) · pyscript/pyscript@82613d0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 82613d0

Browse files
Fix #1429 - Use basic-devtools module (#1430)
This MR brings in `$`, `$$`, and `$x` browsers devtools' utilities to our code so we can use these whenever we find it convenient.
1 parent 3a66be5 commit 82613d0

File tree

11 files changed

+47
-27
lines changed

11 files changed

+47
-27
lines changed

pyscriptjs/package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyscriptjs/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,8 @@
3838
"synclink": "0.2.4",
3939
"ts-jest": "29.0.3",
4040
"typescript": "5.0.4"
41+
},
42+
"dependencies": {
43+
"basic-devtools": "^0.1.6"
4144
}
4245
}

pyscriptjs/src/components/pyrepl.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { $, $$ } from 'basic-devtools';
2+
13
import { basicSetup, EditorView } from 'codemirror';
24
import { python } from '@codemirror/lang-python';
35
import { indentUnit } from '@codemirror/language';
@@ -78,7 +80,7 @@ export function make_PyRepl(interpreter: InterpreterClient, app: PyScriptApp) {
7880
if (!response.ok) {
7981
return;
8082
}
81-
const cmcontentElement = this.querySelector("div[class='cm-content']");
83+
const cmcontentElement = $('div[class="cm-content"]', this);
8284
const { lastElementChild } = cmcontentElement;
8385
cmcontentElement.replaceChildren(lastElementChild);
8486
lastElementChild.textContent = await response.text();
@@ -191,7 +193,7 @@ export function make_PyRepl(interpreter: InterpreterClient, app: PyScriptApp) {
191193
// should be the default.
192194
autogenerateMaybe(): void {
193195
if (this.hasAttribute('auto-generate')) {
194-
const allPyRepls = document.querySelectorAll(`py-repl[root='${this.getAttribute('root')}'][exec-id]`);
196+
const allPyRepls = $$(`py-repl[root='${this.getAttribute('root')}'][exec-id]`, document);
195197
const lastRepl = allPyRepls[allPyRepls.length - 1];
196198
const lastExecId = lastRepl.getAttribute('exec-id');
197199
const nextExecId = parseInt(lastExecId) + 1;

pyscriptjs/src/components/pyscript.ts

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { $$, $x } from 'basic-devtools';
2+
13
import { ltrim, htmlDecode, ensureUniqueId, createDeprecationWarning } from '../utils';
24
import { getLogger } from '../logger';
35
import { pyExec, displayPyException } from '../pyexec';
@@ -113,7 +115,7 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
113115
if ((node as PyScriptElement).matches(pyScriptCSS)) {
114116
bootstrap(node as PyScriptElement);
115117
}
116-
for (const child of (node as PyScriptElement).querySelectorAll(pyScriptCSS)) {
118+
for (const child of $$(pyScriptCSS, node as PyScriptElement)) {
117119
bootstrap(child as PyScriptElement);
118120
}
119121
}
@@ -139,7 +141,7 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
139141
});
140142

141143
// bootstrap all already live py <script> tags
142-
callback([{ addedNodes: document.querySelectorAll(pyScriptCSS) } as unknown] as MutationRecord[], null);
144+
callback([{ addedNodes: $$(pyScriptCSS, document) } as unknown] as MutationRecord[], null);
143145

144146
// once all tags have been initialized, observe new possible tags added later on
145147
// this is to save a few ticks within the callback as each <script> already adds a companion node
@@ -149,20 +151,6 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
149151
return PyScript;
150152
}
151153

152-
// Differently from CSS selectors, XPath can crawl attributes by name and select
153-
// directly attribute nodes. This allows us to look for literally any `py-*` attribute.
154-
// TODO: could we just depend on basic-devtools module?
155-
// @see https://github.com/WebReflection/basic-devtools
156-
const $x = (path: string, root: Document | HTMLElement = document): (Node | Attr)[] => {
157-
const expression = new XPathEvaluator().createExpression(path);
158-
const xpath = expression.evaluate(root, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
159-
const result = [];
160-
for (let i = 0, { snapshotLength } = xpath; i < snapshotLength; i++) {
161-
result.push(xpath.snapshotItem(i));
162-
}
163-
return result;
164-
};
165-
166154
/** A weak relation between an element and current interpreter */
167155
const elementInterpreter: WeakMap<Element, InterpreterClient> = new WeakMap();
168156

@@ -199,7 +187,7 @@ function createElementsWithEventListeners(interpreter: InterpreterClient, el: El
199187

200188
/** Mount all elements with attribute py-mount into the Python namespace */
201189
export async function mountElements(interpreter: InterpreterClient) {
202-
const matches: NodeListOf<HTMLElement> = document.querySelectorAll('[py-mount]');
190+
const matches = $$('[py-mount]', document);
203191
logger.info(`py-mount: found ${matches.length} elements`);
204192

205193
if (matches.length > 0) {

pyscriptjs/src/main.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { $$ } from 'basic-devtools';
2+
13
import './styles/pyscript_base.css';
24

35
import { loadConfigFromElement } from './pyconfig';
@@ -150,7 +152,7 @@ export class PyScriptApp {
150152
// XXX: we should actively complain if there are multiple <py-config>
151153
// and show a big error. PRs welcome :)
152154
logger.info('searching for <py-config>');
153-
const elements = document.getElementsByTagName('py-config');
155+
const elements = $$('py-config', document);
154156
let el: Element | null = null;
155157
if (elements.length > 0) el = elements[0];
156158
if (elements.length >= 2) {

pyscriptjs/src/plugins/importmap.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { $$ } from 'basic-devtools';
2+
13
import { showWarning } from '../utils';
24
import { Plugin } from '../plugin';
35
import { getLogger } from '../logger';
@@ -21,7 +23,7 @@ export class ImportmapPlugin extends Plugin {
2123
// await the module to be fully registered before executing the code
2224
// inside py-script. It's also unclear whether we want to wait or not
2325
// (or maybe only wait only if we do an actual 'import'?)
24-
for (const node of document.querySelectorAll("script[type='importmap']")) {
26+
for (const node of $$("script[type='importmap']", document)) {
2527
const importmap: ImportMapType = (() => {
2628
try {
2729
return JSON.parse(node.textContent) as ImportMapType;

pyscriptjs/src/plugins/pyterminal.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { $ } from 'basic-devtools';
2+
13
import type { PyScriptApp } from '../main';
24
import type { AppConfig } from '../pyconfig';
35
import { Plugin, validateConfigParameterFromArray } from '../plugin';
@@ -42,7 +44,7 @@ export class PyTerminalPlugin extends Plugin {
4244
const { terminal: t, docked: d } = config;
4345
const auto = t === true || t === 'auto';
4446
const docked = d === true || d === 'docked';
45-
if (auto && document.querySelector('py-terminal') === null) {
47+
if (auto && $('py-terminal', document) === null) {
4648
logger.info('No <py-terminal> found, adding one');
4749
const termElem = document.createElement('py-terminal');
4850
if (auto) termElem.setAttribute('auto', '');

pyscriptjs/src/plugins/splashscreen.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { $ } from 'basic-devtools';
2+
13
import type { AppConfig } from '../pyconfig';
24
import type { UserError } from '../exceptions';
35
import { showWarning } from '../utils';
@@ -92,8 +94,8 @@ export class PySplashscreen extends HTMLElement {
9294
</div>
9395
</div>`;
9496
this.mount_name = this.id.split('-').join('_');
95-
this.operation = document.getElementById('pyscript-operation');
96-
this.details = document.getElementById('pyscript-operation-details');
97+
this.operation = $('#pyscript-operation', document) as HTMLElement;
98+
this.details = $('#pyscript-operation-details', document) as HTMLElement;
9799
}
98100

99101
log(msg: string) {

pyscriptjs/src/plugins/stdiodirector.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { $ } from 'basic-devtools';
2+
13
import { Plugin } from '../plugin';
24
import { TargetedStdio, StdioMultiplexer } from '../stdio';
35
import type { InterpreterClient } from '../interpreter_client';
@@ -107,7 +109,7 @@ export class StdioDirector extends Plugin {
107109
if (outputId) {
108110
// 'output' attribute also used as location to send
109111
// result of REPL
110-
if (document.getElementById(outputId)) {
112+
if ($('#' + outputId, document)) {
111113
await pyDisplay(options.interpreter, options.result, { target: outputId });
112114
} else {
113115
//no matching element on page

pyscriptjs/src/stdio.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { $ } from 'basic-devtools';
2+
13
import { createSingularWarning, escape } from './utils';
24

35
export interface Stdio {
@@ -67,7 +69,7 @@ export class TargetedStdio implements Stdio {
6769
*/
6870
writeline_by_attribute(msg: string) {
6971
const target_id = this.source_element.getAttribute(this.source_attribute);
70-
const target = document.getElementById(target_id);
72+
const target = $('#' + target_id, document);
7173
if (target === null) {
7274
// No matching ID
7375
createSingularWarning(

0 commit comments

Comments
 (0)
0