zen-coding:使用 ^ 提升 DOM 树的能力

发布于 2024-10-29 23:13:12 字数 350 浏览 3 评论 0原文

我分叉了优秀的 zen-coding 项目,想法是使用 ^ - 实现 DOM 提升,这样你就可以这样做:

html>head>title^body>h1 而不是 html>(head>title)+body>h1

最初我使用相当粗劣的正则表达式方法来实现。我现在已经使用@Jordan 的出色答案实现了。我的 fork 在这里

我仍然想知道

我的函数是否有返回错误值的情况?

I forked the excellent zen-coding project, with an idea to implement DOM ascension using a ^ - so you can do:

html>head>title^body>h1 rather than html>(head>title)+body>h1

Initially I implemented with rather shoddy regex methods. I have now implemented using @Jordan's excellent answer. My fork is here

What I still want to know

Are there any scenarios where my function returns the wrong value?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一个人练习一个人 2024-11-05 23:13:12

免责声明:我从未使用过 zen-coding,这只是我第二次听说它,所以我不知道可能的陷阱是什么。也就是说,这似乎是一种可行的解决方案,或者至少非常接近于一种可行的解决方案。

我正在使用 Zen 编码对于 textarea v0.7.1 为此。如果您使用不同版本的代码库,您将需要相应地调整这些说明。

一些评论者认为这不是正则表达式的工作,我同意。幸运的是,zen-coding 有自己的解析器实现,并且非常容易构建!您需要在两个地方添加代码才能实现此功能:

  1. ^ 字符添加到 isAllowedChar 中的 special_chars 变量中函数(大约从第 1694 行开始):

    function isAllowedChar(ch) {
        ...
        Special_chars = '#.>+*:$-_!@[]()|^'; // 添加升序运算符“^”
    
  2. parse 函数的 switch 语句中处理 new 运算符(大约从第 1541 行开始):

    解析:函数(缩写){
        ...
        而(i < il){
            ch = abbr.charAt(i);
            上一个频道 = 我? abbr.charAt(i - 1) : '';
            开关(通道){
                ...
                // 下面是您的代码
                case '^': // 升序运算符
                    if (!text_lvl && !attr_lvl) {
                        转储令牌();
                        上下文 = context.parent.parent.addChild();
                    } 别的 {
                        令牌+= ch;
                    }
                    休息;
    

    以下是新代码功能的逐行细分:

    case '^': // 当前字符是升序运算符。
        if (!text_lvl && !attr_lvl) { // 不适用于文本/属性。
            转储令牌(); // 运算符表示当前标记的结束。
    
                                      // 将上下文向上移动两级。
            上下文 = context.parent.parent.addChild();
    
        } 别的 {
            令牌+= ch; // 将字符添加到文本/属性中的标记。
        }
        休息;
    

上面的实现按预期工作,例如:

html>head>title^body
html:5>div#first>div.inner^div#second>div.inner
html:5>div>(div>div>div^div)^div*2
html:5>div>div>div^^div

您无疑会想尝试一些更高级的、真实的测试用例。 这是我修改过的源代码如果你想快速启动;将您的 zen_textarea.min.js 替换为这个,以进行一些快速而肮脏的测试。

请注意,这仅将 DOM 提升两级,并且不会将前面的元素视为一个组,因此例如 div>div^*3 不会像 (div>div)*3 那样工作。如果这是您想要的,那么请查看右括号字符的逻辑,它使用前瞻来检查乘法。 (就我个人而言,我建议不要这样做,因为即使对于缩写语法来说,它也非常难以阅读。)

Disclaimer: I have never used zen-coding and this is only my second time hearing about it, so I have no idea what the likely gotchas are. That said, this seems to be a working solution, or at least very close to one.

I am using Zen Coding for textarea v0.7.1 for this. If you are using a different version of the codebase you will need to adapt these instructions accordingly.

A couple of commenters have suggested that this is not a job for regular expressions, and I agree. Fortunately, zen-coding has its own parser implementation, and it's really easy to build on! There are two places where you need to add code to make this work:

  1. Add the ^ character to the special_chars variable in the isAllowedChar function (starts circa line 1694):

    function isAllowedChar(ch) {
        ...
        special_chars = '#.>+*:$-_!@[]()|^'; // Added ascension operator "^"
    
  2. Handle the new operator in the switch statement of the parse function (starts circa line 1541):

    parse: function(abbr) {
        ...
        while (i < il) {
            ch = abbr.charAt(i);
            prev_ch = i ? abbr.charAt(i - 1) : '';
            switch (ch) {
                ...
                // YOUR CODE BELOW
                case '^': // Ascension operator
                    if (!text_lvl && !attr_lvl) {
                        dumpToken();
                        context = context.parent.parent.addChild();
                    } else {
                        token += ch;
                    }
                    break;
    

    Here's a line-by-line breakdown of what the new code does:

    case '^':                         // Current character is ascension operator.
        if (!text_lvl && !attr_lvl) { // Don't apply in text/attributes.
            dumpToken();              // Operator signifies end of current token.
    
                                      // Shift context up two levels.
            context = context.parent.parent.addChild();
    
        } else {
            token += ch;              // Add char to token in text/attribute.
        }
        break;
    

The implementation above works as expected for e.g.:

html>head>title^body
html:5>div#first>div.inner^div#second>div.inner
html:5>div>(div>div>div^div)^div*2
html:5>div>div>div^^div

You will doubtless want to try some more advanced, real-world test cases. Here's my modified source if you want a kick-start; replace your zen_textarea.min.js with this for some quick-and-dirty testing.

Note that this merely ascends the DOM by two levels and does not treat the preceding elements as a group, so e.g. div>div^*3 will not work like (div>div)*3. If this is something you want then look at the logic for the closing parenthesis character, which uses a lookahead to check for multiplication. (Personally, I suggest not doing this, since even for an abbreviated syntax it is horribly unreadable.)

脸赞 2024-11-05 23:13:12

您应该在您使用的语言中寻找 Perl 的 Text::Balanced 替代方案。

You should look for Perl's Text::Balanced alternative in the language that you're using.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文