acd: rewrite Python wrapper without jQuery

* python/spot/__init__.py (acd): Rewrite javascript so that it does
not use jQuery, to make it easier to use in jupyterlab, or with
nbconvert.
* tests/python/zlktree.ipynb: Adjust.
* NEWS: Mention this.
This commit is contained in:
Alexandre Duret-Lutz 2022-12-09 12:04:15 +01:00
parent 427f667f9f
commit d0b1508831
3 changed files with 564 additions and 181 deletions

4
NEWS
View file

@ -9,6 +9,10 @@ New in spot 2.11.3.dev (not yet released)
- b:b[*i..j] = b[*max(i,1)..j] - b:b[*i..j] = b[*max(i,1)..j]
- b[*i..j]:b[*k..l] = b[*max(i,1)+max(k,1)-1, j+l-1] - b[*i..j]:b[*k..l] = b[*max(i,1)+max(k,1)-1, j+l-1]
Python:
- spot.acd() no longer depends on jQuery for interactivity.
New in spot 2.11.3 (2022-12-09) New in spot 2.11.3 (2022-12-09)
Bug fixes: Bug fixes:

View file

@ -502,51 +502,57 @@ class acd:
.acdacc polygon{fill:green;} .acdacc polygon{fill:green;}
''' '''
js = ''' js = '''
function acd{num}_clear(){{ function acdremclasses(sel, classes) {{
$("#acd{num} .node,#acdaut{num} .node,#acdaut{num} .edge") document.querySelectorAll(sel).forEach(n=>{{n.classList.remove(...classes)}});}}
.removeClass("acdhigh acdbold acdacc acdrej"); function acdaddclasses(sel, classes) {{
document.querySelectorAll(sel).forEach(n=>{{n.classList.add(...classes)}});}}
function acdonclick(sel, fn) {{
document.querySelectorAll(sel).forEach(n=>
{{n.addEventListener("click", fn)}});
}}
function acd{num}_clear() {{
acdremclasses("#acd{num} .node,#acdaut{num} .node,#acdaut{num} .edge",
["acdhigh", "acdbold", "acdacc", "acdrej"]);
}}; }};
function acd{num}_state(state){{ function acd{num}_state(state){{
acd{num}_clear(); acd{num}_clear();
$("#acd{num} .acdS" + state).addClass("acdhigh acdbold"); acdaddclasses("#acd{num} .acdS" + state, ["acdhigh", "acdbold"]);
$("#acdaut{num} #S" + state).addClass("acdbold"); acdaddclasses("#acdaut{num} #S" + state, ["acdbold"]);
}}; }};
function acd{num}_edge(edge){{ function acd{num}_edge(edge){{
acd{num}_clear(); acd{num}_clear();
var theedge = $('#acdaut{num} #E' + edge) var theedge = document.querySelector('#acdaut{num} #E' + edge);
var classList = theedge.attr('class').split(/\s+/); theedge.classList.forEach(function(item, index) {{
$.each(classList, function(index, item) {{ if (item.startsWith('acdN')) {{
if (item.startsWith('acdN')) {{ acdaddclasses("#acd{num} #" + item.substring(3), ["acdhigh", "acdbold"]);
$("#acd{num} #" + item.substring(3)).addClass("acdhigh acdbold"); }}
}} }});
}}); theedge.classList.add("acdbold");
theedge.addClass("acdbold");
}}; }};
function acd{num}_node(node, acc){{ function acd{num}_node(node, acc){{
acd{num}_clear(); acd{num}_clear();
$("#acdaut{num} .acdN" + node).addClass(acc acdaddclasses("#acdaut{num} .acdN" + node,
? "acdacc acdbold" [acc ? "acdacc" : "acdrej", "acdbold"]);
: "acdrej acdbold"); acdaddclasses("#acd{num} #N" + node, ["acdbold", "acdhigh"]);
$("#acd{num} #N" + node).addClass("acdbold acdhigh");
}};'''.format(num=num) }};'''.format(num=num)
me = 0 me = 0
for n in range(self.node_count()): for n in range(self.node_count()):
for e in self.edges_of_node(n): for e in self.edges_of_node(n):
me = max(e, me) me = max(e, me)
js += '$("#acdaut{num} #E{e}").addClass("acdN{n}");'\ js += 'acdaddclasses("#acdaut{num} #E{e}", ["acdN{n}"]);\n'\
.format(num=num, e=e, n=n) .format(num=num, e=e, n=n)
for e in range(1, me + 1): for e in range(1, me + 1):
js += '$("#acdaut{num} #E{e}")'\ js += 'acdonclick("#acdaut{num} #E{e}",'\
'.click(function(){{acd{num}_edge({e});}});'\ 'function(){{acd{num}_edge({e});}});\n'\
.format(num=num, e=e) .format(num=num, e=e)
for s in range(self.get_aut().num_states()): for s in range(self.get_aut().num_states()):
js += '$("#acdaut{num} #S{s}")'\ js += 'acdonclick("#acdaut{num} #S{s}",'\
'.click(function(){{acd{num}_state({s});}});'\ 'function(){{acd{num}_state({s});}});\n'\
.format(num=num, s=s) .format(num=num, s=s)
for n in range(self.node_count()): for n in range(self.node_count()):
v = int(self.node_acceptance(n)) v = int(self.node_acceptance(n))
js += '$("#acd{num} #N{n}")'\ js += 'acdonclick("#acd{num} #N{n}",'\
'.click(function(){{acd{num}_node({n}, {v});}});'\ 'function(){{acd{num}_node({n}, {v});}});\n'\
.format(num=num, n=n, v=v) .format(num=num, n=n, v=v)
html = '<style>{}</style><div>{}</div><div>{}</div><script>{}</script>'\ html = '<style>{}</style><div>{}</div><div>{}</div><script>{}</script>'\
.format(style, .format(style,

File diff suppressed because one or more lines are too long