浏览代码

add ancher feat support

wangweimin 5 年之前
父节点
当前提交
1dcd29b686
共有 2 个文件被更改,包括 76 次插入13 次删除
  1. 40 13
      pywebio/html/js/form.js
  2. 36 0
      pywebio/output.py

+ 40 - 13
pywebio/html/js/form.js

@@ -142,20 +142,47 @@
             else
                 console.warn('Unknown output type:%s', msg.spec.type);
         } else if (msg.command === 'output_ctl') {
-            if (msg.spec.title)
-                $('#title').text(msg.spec.title);  // 直接使用#title不规范 todo
-            if (msg.spec.output_fixed_height !== undefined)
-                if (msg.spec.output_fixed_height)
-                    $('.container').removeClass('no-fix-height');  // todo 不规范
-                else
-                    $('.container').addClass('no-fix-height');  // todo 不规范
-            if (msg.spec.auto_scroll_bottom !== undefined)
-                AutoScrollBottom = msg.spec.auto_scroll_bottom;
+            this.handle_output_ctl(msg);
         }
-        if (AutoScrollBottom)
+        // note:当接收到scroll_to指令时,忽略AutoScrollBottom
+        if (AutoScrollBottom && !(msg.command === 'output_ctl' && msg.spec.scroll_to !== undefined))
             this.scroll_bottom();
     };
 
+    OutputController.prototype.handle_output_ctl = function (msg) {
+        if (msg.spec.title)
+            $('#title').text(msg.spec.title);  // 直接使用#title不规范 todo
+        if (msg.spec.output_fixed_height !== undefined)
+            if (msg.spec.output_fixed_height)
+                $('.container').removeClass('no-fix-height');  // todo 不规范
+            else
+                $('.container').addClass('no-fix-height');  // todo 不规范
+        if (msg.spec.auto_scroll_bottom !== undefined)
+            AutoScrollBottom = msg.spec.auto_scroll_bottom;
+        if (msg.spec.set_anchor !== undefined) {
+            this.container_elem.find(`#${msg.spec.set_anchor}`).remove();
+            this.container_elem.append(`<div id="${msg.spec.set_anchor}"></div>`);
+        }
+        if (msg.spec.clear_before !== undefined)
+            this.container_elem.find(`#${msg.spec.clear_before}`).prevAll().remove();
+        if (msg.spec.clear_after !== undefined)
+            this.container_elem.find(`#${msg.spec.clear_after}~*`).remove();
+        if (msg.spec.scroll_to !== undefined)
+            $([document.documentElement, document.body]).animate({
+                scrollTop: $(`#${msg.spec.scroll_to}`).offset().top
+            }, 400);
+        if (msg.spec.clear_range !== undefined) {
+            if (this.container_elem.find(`#${msg.spec.clear_range[0]}`).length &&
+                this.container_elem.find(`#${msg.spec.clear_range[1]}`).length) {
+                this.container_elem.find(`#${msg.spec.clear_range[0]}~*`).each(function () {
+                    if (this.id === msg.spec.clear_range[1])
+                        return false;
+                    $(this).remove();
+                });
+            }
+        }
+    };
+
     OutputController.prototype.handle_file = function (msg) {
         const html = `<div class="form-group"><button type="button" class="btn btn-link">${msg.spec.name}</button></div>`;
         var element = $(html);
@@ -206,7 +233,7 @@
             if (ctrl === old_ctrl || old_ctrl === undefined) {
                 console.log('开:%s', ctrl.spec.label);
                 return ctrl.element.show(ShowDuration, function () {
-                    if(AutoScrollBottom)
+                    if (AutoScrollBottom)
                         $('[auto_focus]').focus();
                 });
             }
@@ -217,7 +244,7 @@
                 // 需要在回调中重新获取当前前置表单元素,因为100ms内可能有变化
                 var t = that.form_ctrls.get_top();
                 if (t) t[t.length - 1].element.show(ShowDuration, function () {
-                    if(AutoScrollBottom)
+                    if (AutoScrollBottom)
                         $('[auto_focus]').focus();
                 });
             });
@@ -281,7 +308,7 @@
                         deleted.element.remove();
                         var t = that.form_ctrls.get_top();
                         if (t) t[t.length - 1].element.show(ShowDuration, function () {
-                            if(AutoScrollBottom)
+                            if (AutoScrollBottom)
                                 $('[auto_focus]').focus();
                         });
                     });

+ 36 - 0
pywebio/output.py

@@ -21,6 +21,42 @@ def set_auto_scroll_bottom(enabled=True):
     send_msg('output_ctl', dict(auto_scroll_bottom=enabled))
 
 
+def set_anchor(name):
+    """
+    在当前输出处标记锚点。 若已经存在name锚点,则先将旧锚点删除
+    """
+    inner_ancher_name = 'pywebio-anchor-%s' % name
+    send_msg('output_ctl', dict(set_anchor=inner_ancher_name))
+
+
+def clear_before(anchor):
+    """清除anchor锚点之前输出的内容"""
+    inner_ancher_name = 'pywebio-anchor-%s' % anchor
+    send_msg('output_ctl', dict(clear_before=inner_ancher_name))
+
+
+def clear_after(anchor):
+    """清除anchor锚点之后输出的内容"""
+    inner_ancher_name = 'pywebio-anchor-%s' % anchor
+    send_msg('output_ctl', dict(clear_after=inner_ancher_name))
+
+
+def clear_range(start_anchor, end_ancher):
+    """
+    清除start_anchor-end_ancher锚点之间输出的内容.
+    若 start_anchor 或 end_ancher 不存在,则不进行任何操作
+    """
+    inner_start_anchor_name = 'pywebio-anchor-%s' % start_anchor
+    inner_end_ancher_name = 'pywebio-anchor-%s' % end_ancher
+    send_msg('output_ctl', dict(clear_range=[inner_start_anchor_name, inner_end_ancher_name]))
+
+
+def scroll_to(anchor):
+    """将页面滚动到anchor锚点处"""
+    inner_ancher_name = 'pywebio-anchor-%s' % anchor
+    send_msg('output_ctl', dict(scroll_to=inner_ancher_name))
+
+
 def text_print(text, *, ws=None):
     if text is None:
         text = ''