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 09e147ee4b
commit cab3ea7faf
3 changed files with 563 additions and 182 deletions

4
NEWS
View file

@ -1,6 +1,8 @@
New in spot 2.11.3.dev (not yet released)
Nothing yet.
Python:
- spot.acd() no longer depends on jQuery for interactivity.
New in spot 2.11.3 (2022-12-09)

View file

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

File diff suppressed because one or more lines are too long