Forráskód Böngészése

lock scope height after clear scope in `use_scope(clear=True)``

wangweimin 2 éve
szülő
commit
8a58af0407
3 módosított fájl, 21 hozzáadás és 6 törlés
  1. 2 0
      docs/spec.rst
  2. 4 3
      pywebio/output.py
  3. 15 3
      webiojs/src/handlers/output.ts

+ 2 - 0
docs/spec.rst

@@ -367,7 +367,9 @@ The ``spec`` fields of ``output_ctl`` commands:
         - null: Do nothing
         - null: Do nothing
         - `'remove'`: Remove the old scope first and then create a new one
         - `'remove'`: Remove the old scope first and then create a new one
         - `'clear'`: Just clear the contents of the old scope, but don’t create a new scope
         - `'clear'`: Just clear the contents of the old scope, but don’t create a new scope
+        - `'blank'`: Clear the contents of the old scope and keep the height, don’t create a new scope
 
 
+* loose: css selector of the scope, set the scope not to keep the height (i.e., revoke the effect of ``set_scope(if_exist='blank')``)
 * clear: css selector of the scope need to clear
 * clear: css selector of the scope need to clear
 * clear_before
 * clear_before
 * clear_after
 * clear_after

+ 4 - 3
pywebio/output.py

@@ -1765,8 +1765,8 @@ def use_scope(name=None, clear=False, **kwargs):
 
 
     def before_enter():
     def before_enter():
         if create_scope:
         if create_scope:
-            if_exist = 'clear' if clear else None
-            set_scope(name, if_exist=if_exist, **scope_params)
+            if_exist = 'blank' if clear else None
+            set_scope(name, if_exist=if_exist, **scope_params)  # lock the height of the scope and clear its content
 
 
     return use_scope_(name=name, before_enter=before_enter)
     return use_scope_(name=name, before_enter=before_enter)
 
 
@@ -1787,7 +1787,8 @@ class use_scope_:
         If this method returns True, it means that the context manager can handle the exception,
         If this method returns True, it means that the context manager can handle the exception,
         so that the with statement terminates the propagation of the exception
         so that the with statement terminates the propagation of the exception
         """
         """
-        get_current_session().pop_scope()
+        scope = get_current_session().pop_scope()
+        send_msg('output_ctl', dict(loose=scope2dom(scope)))  # revoke lock the height of the scope
         return False  # Propagate Exception
         return False  # Propagate Exception
 
 
     def __call__(self, func):
     def __call__(self, func):

+ 15 - 3
webiojs/src/handlers/output.ts

@@ -10,7 +10,7 @@ const DISPLAY_NONE_TAGS = ['script', 'style'];
 let after_show_callbacks: (() => void) [] = [];
 let after_show_callbacks: (() => void) [] = [];
 
 
 // register a callback to execute after the current output widget showing
 // register a callback to execute after the current output widget showing
-export function AfterCurrentOutputWidgetShow(callback: () => void){
+export function AfterCurrentOutputWidgetShow(callback: () => void) {
     after_show_callbacks.push(callback);
     after_show_callbacks.push(callback);
 }
 }
 
 
@@ -86,7 +86,7 @@ export class OutputHandler implements CommandHandler {
 
 
             // to avoid widget width exceeding page width
             // to avoid widget width exceeding page width
             // show horizon scroll bar when content too wide
             // show horizon scroll bar when content too wide
-            if(elem.width() > this.container_elem.width())
+            if (elem.width() > this.container_elem.width())
                 elem.wrap($(document.createElement('div')).css('overflow', 'auto'));
                 elem.wrap($(document.createElement('div')).css('overflow', 'auto'));
 
 
             if (this.is_elem_visible(elem) && container_elem.length == 1) {  // 输出内容为可见标签且输出目的scope唯一
             if (this.is_elem_visible(elem) && container_elem.length == 1) {  // 输出内容为可见标签且输出目的scope唯一
@@ -127,11 +127,20 @@ export class OutputHandler implements CommandHandler {
                 else if (spec.if_exist == 'clear') {
                 else if (spec.if_exist == 'clear') {
                     old.empty();
                     old.empty();
                     return;
                     return;
+                } else if (spec.if_exist == 'blank') { // Clear the contents of the old scope and keep the height
+                    let scope_css: any = {'min-height': old.height()};
+                    let prev = old.prev(), next = old.next();
+                    if (prev.length)
+                        scope_css['margin-top'] = old[0].getBoundingClientRect().top - prev[0].getBoundingClientRect().bottom;
+                    if (next.length)
+                        scope_css['margin-bottom'] = next[0].getBoundingClientRect().top - old[0].getBoundingClientRect().bottom;
+                    old.css(scope_css);
+                    old.empty();
+                    return;
                 } else {
                 } else {
                     return;
                     return;
                 }
                 }
             }
             }
-
             let html = `<div id="${spec.set_scope}"></div>`;
             let html = `<div id="${spec.set_scope}"></div>`;
             if (spec.position === 0)
             if (spec.position === 0)
                 container_elem.prepend(html);
                 container_elem.prepend(html);
@@ -144,6 +153,9 @@ export class OutputHandler implements CommandHandler {
                     $(`${spec.container} > *`).eq(spec.position).insertAfter(html);
                     $(`${spec.container} > *`).eq(spec.position).insertAfter(html);
             }
             }
         }
         }
+        if (msg.spec.loose !== undefined) { // revoke the effect of ``set_scope(if_exist='blank')``
+            $(msg.spec.loose).css({'min-height': '', 'margin-top': '', 'margin-bottom': ''});
+        }
         if (msg.spec.clear !== undefined) {
         if (msg.spec.clear !== undefined) {
             $(msg.spec.clear).empty();
             $(msg.spec.clear).empty();
         }
         }