HDB的实现,_hyperscript调试器

2021-03-18 04:46:48

0.0.6的_hyperscript超文本UI脚本语言引入了HDB,交互式调试环境。在本文中,我讨论了如何轻松地实现Hyper-FlexiCred Runtime如何实现HDB的第一个版本。但首先,我会向您介绍HDB的样子:

在缺记runtime(这是树行走解释器)中,每个命令具有execute()方法,该方法返回要执行的下一个命令,或其承诺。 BreakPoint命令的执行方法会创建HDB环境,并将其分配给全局范围(通常是窗口):

HDB对象随着我们逐步持有当前命令和上下文。 (上下文是持有屏幕上的局部变量的对象,以及运行时跟踪的其他一些事情)。我们称之为break()方法:

。原型 。 break =函数(ctx){var self = this;安慰 。日志("%c === hdb /// _ hyperscript / debugger ===",头饰);自己 。 UI();返回新(函数(解析,拒绝){self .bus。addeventlistener("继续"函数(){if(self .ctx!== ctx){//上下文切换(var attr在ctx中){删除CTX [attr];}对象。分配(ctx,self .ctx);删除窗口.hdb;解析(self .runtime。findnext(self .cmd,self .ctx));},{一次:true });})}

这里有一些东西可以打开包装。我们调用self.ui()启动UI,我们将稍后开始。请记住,命令如何返回下一个方法作为承诺执行?断裂方法在内部事件总线接收A&#34之后解决;继续"事件,是否按用户按“继续”或只是到达调试代码的末尾。

“上下文切换”是它的最肮脏的部分。因为我们可以耗尽函数,所以我们可能会完成与之前的不同上下文的调试会话。在这种情况下,我们只需擦除旧上下文并复制当前上下文变量。老实说,我以为我必须做更多的事情。

首先,如果self.cmd为null,那么上一个命令是最后一个命令,所以我们只需停止调试过程:

如果没有,那么我们做了一点舞蹈来执行当前命令并获得下一个命令:

我们表现​​了一个无用的检查,我忘了拿出来(self.cmd&&)。然后,我们特殊情况 - 断点命令本身并且不执行它(嵌套调试会话不会结束......),而是在鼠标核心核心中使用runtime.findnext()找到后续命令。否则,我们可以执行当前命令。

if(结果.type ===" Implicitreturn")回归自我。 Stepout(); if(结果&结果.then instanceof){返回结果。然后(函数(下一个){self .cmd = next; self .bus。Dispatchevent("步骤")); self。logcommand();})}否则如果(结果.halt_flag){这个。公共汽车 。 DispatchEvent(新("继续&#34)); } else {self .cmd =结果;自我.bus。 DispatchEvent(新(" Step"));这 。 logcommand(); }

如果我们从函数返回,我们搬出它(下面讨论)。否则,如果命令返回承诺,我们等待下一个命令,将cmd设置为它,通知事件总线并使用一些花式样式登录。如果结果是同步的,并且是[停止] [];我们停止调试(正如我写下这个问题,我意识到我应该在这里调用[continueexec()] [继续执行])。最后,我们提交了那种代码复制纯净的屏幕旨在帮助您避免,处理同步结果。

要走出来,我们首先让我们的手在我们被召唤的背景下:

。原型 。 stepout = function(){var self = this;如果(!self .ctx .meta .caller)返回自我。 continueexec(); var callingcmd = self .ctx .meta .callingcommand; var oldme = self .ctx .me; self .ctx = self .ctx .meta .caller;

拒绝_hyperscript函数调用已经保留了呼叫者上下文(但是me由me添加)。在改变上下文之后,我们做一些奇怪的事情:

我们无法执行命令以设置名称,直到我们有名称,因此当调用getName()时,当前命令仍然设置为转换。我们调用FindNext一次找到集合,然后再次找到日志。

我用什么来制作uI用于yprecript调试器? killscript,当然!

从HDB.Bus中侦听加载或步骤有很多元素,因此我将在从.hdb的更新中巩固它们。 #keperscript-hdb-ui-wrapper-是一个元素,它的阴影dom这个ui生活在 - 使用shadow dom来隔离面板的造型在后面的情况下,我会看到。

def extullightdebudcode set start to hdb.cmd.starttoken.start设置结尾到hdb.cmd.endtoken.end set src到hdb.cmd.programsource将beForecmd设置为eScapthtml(src.substring(0,start))将cmd设置为eScapthtml(src .substring(开始,结束))将resucmd设置为eScapthtml(src.substring(end))返回beforecmd +" " + cmd +" " +渣打结束

现在,我没有意识到我们在这一点上有一个在kidscript中的模板文字,所以这是下一个版本。 eveschthtml帮助者可能会失望一些:

def vectaphtml(不安全)js(不安全)返回不安全.replace(/& / g,"").replace(/ g,"").replace(/ \ \ x22 / g,"").replace(/ \\ x27 / g,"'")结束返回它结束

我们拥有HDB最严重的部分,PrettyPrint功能。如果您知道如何更好,请随时发送PR。

为什么我使用奇怪的选择器,如<输入/>当这些元素有良好的IDS时,在我?因为#eval-expr在鼠标中使用document.querySelector,它不会到达阴影DOM。

那循环绝对可以清洁。您可以看到隐藏的功能,您可以在其中单击变量名称以将其记录到控制台(如果您不想依赖我的超级仓鼠漂亮的打印机)。

一些CSS后来,我们已经完成了UI!为避免从主页的干扰,我们创建一个包装器并将我们的UI放在其暗影DOM中:

。原型 。 UI =函数(){var node =文档。牧场(' div'); var shadow =节点。 attachshadow({mode:'打开'});节点.style ='全部:初始' ;节点.id =' knerscript-hdb-ui-wrapper - ' ;影子.innerhtml = UI;文件。Body。 AppendChild(节点);窗口.hdbui =阴影。 QuerySelector(' .hdb'); _hyperscript。 ProcessNode(HDBUI); }

只需360行,我们有一个基本的调试器。这会说出viderscript运行时灵活性的卷,我希望HDB用作Hyperscript Extension API的可能性。就像其余的猕猴一样,它在发展的早期阶段 - 反馈和贡献者总是欢迎!