pgwidgets-js 0.3.3__tar.gz → 0.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/PKG-INFO +2 -2
  2. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/README.md +1 -1
  3. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/WhatsNew.rst +74 -0
  4. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/package.json +1 -1
  5. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/defs.py +24 -2
  6. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/Widgets.js +2 -1
  7. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/TextSource.css +18 -0
  8. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Box.js +6 -2
  9. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Button.js +57 -0
  10. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Dialog.js +36 -0
  11. pgwidgets_js-0.3.4/pgwidgets_js/static/modules/Separator.js +55 -0
  12. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/TextSource.js +184 -2
  13. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js.egg-info/PKG-INFO +2 -2
  14. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js.egg-info/SOURCES.txt +1 -0
  15. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js.egg-info/scm_file_list.json +1 -0
  16. pgwidgets_js-0.3.4/pgwidgets_js.egg-info/scm_version.json +8 -0
  17. pgwidgets_js-0.3.3/pgwidgets_js.egg-info/scm_version.json +0 -8
  18. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/.flake8 +0 -0
  19. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/.github/workflows/tests.yml +0 -0
  20. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/.gitignore +0 -0
  21. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/.readthedocs.yaml +0 -0
  22. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/LICENSE.md +0 -0
  23. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/MANIFEST.in +0 -0
  24. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/Widgets.css +0 -0
  25. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/Widgets.js +0 -0
  26. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/Makefile +0 -0
  27. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/callbacks.rst +0 -0
  28. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/conf.py +0 -0
  29. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/electron.rst +0 -0
  30. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/external-widgets.rst +0 -0
  31. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/for-developers.rst +0 -0
  32. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/frameworks.rst +0 -0
  33. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/getting-started.rst +0 -0
  34. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/index.rst +0 -0
  35. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/pyodide.rst +0 -0
  36. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/remote.rst +0 -0
  37. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/styling.rst +0 -0
  38. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/widgets/controls.rst +0 -0
  39. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/widgets/dialogs.rst +0 -0
  40. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/widgets/display.rst +0 -0
  41. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/widgets/index.rst +0 -0
  42. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/widgets/layout.rst +0 -0
  43. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/widgets/menus.rst +0 -0
  44. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/widgets/nonvisual.rst +0 -0
  45. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/docs/widgets/text.rst +0 -0
  46. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/all_widgets.html +0 -0
  47. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/all_widgets_pyodide.html +0 -0
  48. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/all_widgets_pyodide.py +0 -0
  49. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/all_widgets_pyscript.html +0 -0
  50. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/all_widgets_pyscript.py +0 -0
  51. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/box.html +0 -0
  52. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/button.html +0 -0
  53. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/canvas.html +0 -0
  54. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/checkbox.html +0 -0
  55. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/colordialog.html +0 -0
  56. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/combobox.html +0 -0
  57. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/debug_spinbox.html +0 -0
  58. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/dial.html +0 -0
  59. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/dialog.html +0 -0
  60. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/electron/.gitignore +0 -0
  61. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/electron/.npmrc +0 -0
  62. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/electron/index.html +0 -0
  63. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/electron/main.js +0 -0
  64. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/electron/package.json +0 -0
  65. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/expander.html +0 -0
  66. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/external_widgets.html +0 -0
  67. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/fixedlayout.html +0 -0
  68. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/frame.html +0 -0
  69. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/gridbox.html +0 -0
  70. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/htmlview.html +0 -0
  71. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/image.html +0 -0
  72. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/label.html +0 -0
  73. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/mdi_widget.html +0 -0
  74. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/menu.html +0 -0
  75. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/progressbar.html +0 -0
  76. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/pyodide_demo.html +0 -0
  77. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/pyscript.toml +0 -0
  78. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/radiobutton.html +0 -0
  79. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/remote.html +0 -0
  80. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/remote_demo.py +0 -0
  81. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/remote_demo_async.py +0 -0
  82. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/scroll_area.html +0 -0
  83. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/scrollable.html +0 -0
  84. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/scrollbar.html +0 -0
  85. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/slider.html +0 -0
  86. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/spinbox.html +0 -0
  87. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/splitter.html +0 -0
  88. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/tab_widget.html +0 -0
  89. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/tableview.html +0 -0
  90. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/text_entry.html +0 -0
  91. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/textarea.html +0 -0
  92. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/textentryset.html +0 -0
  93. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/textsource.html +0 -0
  94. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/togglebutton.html +0 -0
  95. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/toolbar.html +0 -0
  96. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/treeview.html +0 -0
  97. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/examples/videowidget.html +0 -0
  98. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/__init__.py +0 -0
  99. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/pyodide/__init__.py +0 -0
  100. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/pyodide/log.py +0 -0
  101. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/pyodide/widget.py +0 -0
  102. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/Widgets.css +0 -0
  103. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/AbstractScrollArea.css +0 -0
  104. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Box.css +0 -0
  105. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Button.css +0 -0
  106. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/CheckBox.css +0 -0
  107. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/ColorDialog.css +0 -0
  108. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/ComboBox.css +0 -0
  109. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Dial.css +0 -0
  110. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Dialog.css +0 -0
  111. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Expander.css +0 -0
  112. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/ExternalWidget.css +0 -0
  113. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/FixedLayout.css +0 -0
  114. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Frame.css +0 -0
  115. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/GridBox.css +0 -0
  116. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/HtmlView.css +0 -0
  117. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Image.css +0 -0
  118. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Label.css +0 -0
  119. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/MDIWidget.css +0 -0
  120. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Menu.css +0 -0
  121. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/ProgressBar.css +0 -0
  122. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/RadioButton.css +0 -0
  123. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/ScrollArea.css +0 -0
  124. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/ScrollBar.css +0 -0
  125. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Slider.css +0 -0
  126. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/SpinBox.css +0 -0
  127. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Splitter.css +0 -0
  128. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/StatusBar.css +0 -0
  129. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/TabWidget.css +0 -0
  130. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Text.css +0 -0
  131. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/TextArea.css +0 -0
  132. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/TextEntrySet.css +0 -0
  133. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/ToggleButton.css +0 -0
  134. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/ToolBar.css +0 -0
  135. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/TopLevel.css +0 -0
  136. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/TreeView.css +0 -0
  137. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/VideoWidget.css +0 -0
  138. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/Widget.css +0 -0
  139. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/css/WindowMenu.css +0 -0
  140. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/icons/file.svg +0 -0
  141. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/icons/folder.svg +0 -0
  142. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/icons/hdots.svg +0 -0
  143. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/icons/pgicon.svg +0 -0
  144. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/icons/pgwidgets-logo.png +0 -0
  145. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/icons/pgwidgets-logo.svg +0 -0
  146. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/icons/vdots.svg +0 -0
  147. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/AbstractScrollArea.js +0 -0
  148. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Callback.js +0 -0
  149. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Canvas.js +0 -0
  150. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/CheckBox.js +0 -0
  151. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ColorDialog.js +0 -0
  152. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ColorWidget.js +0 -0
  153. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ComboBox.js +0 -0
  154. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ComboBoxNative.js +0 -0
  155. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Dial.js +0 -0
  156. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Expander.js +0 -0
  157. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ExternalWidget.js +0 -0
  158. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/FileDialog.js +0 -0
  159. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/FixedLayout.js +0 -0
  160. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Frame.js +0 -0
  161. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/GridBox.js +0 -0
  162. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/HtmlView.js +0 -0
  163. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Image.js +0 -0
  164. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Label.js +0 -0
  165. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/MDIWidget.js +0 -0
  166. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Menu.js +0 -0
  167. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/MenuAction.js +0 -0
  168. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/MenuBar.js +0 -0
  169. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Page.js +0 -0
  170. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ProgressBar.js +0 -0
  171. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/RadioButton.js +0 -0
  172. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/RemoteInterface.js +0 -0
  173. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ScrollArea.js +0 -0
  174. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ScrollBar.js +0 -0
  175. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Slider.js +0 -0
  176. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/SpinBox.js +0 -0
  177. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Splitter.js +0 -0
  178. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/StatusBar.js +0 -0
  179. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/TabWidget.js +0 -0
  180. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/TableView.js +0 -0
  181. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/TextArea.js +0 -0
  182. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/TextEntry.js +0 -0
  183. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/TextEntrySet.js +0 -0
  184. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/TextWidget.js +0 -0
  185. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Timer.js +0 -0
  186. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ToggleButton.js +0 -0
  187. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ToolBar.js +0 -0
  188. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/ToolBarAction.js +0 -0
  189. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/TopLevel.js +0 -0
  190. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/TreeView.js +0 -0
  191. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/VideoWidget.js +0 -0
  192. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/Widget.js +0 -0
  193. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/modules/WindowMenu.js +0 -0
  194. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js/static/remote.html +0 -0
  195. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js.egg-info/dependency_links.txt +0 -0
  196. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js.egg-info/requires.txt +0 -0
  197. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pgwidgets_js.egg-info/top_level.txt +0 -0
  198. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/pyproject.toml +0 -0
  199. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/setup.cfg +0 -0
  200. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/setup.py +0 -0
  201. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/tests/__init__.py +0 -0
  202. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/tests/test_consistency.py +0 -0
  203. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/tests/test_defs.py +0 -0
  204. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/tests/test_recent_additions.py +0 -0
  205. {pgwidgets_js-0.3.3 → pgwidgets_js-0.3.4}/tests/test_static_assets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pgwidgets-js
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: pgwidgets JavaScript widget library — static assets for use with Python servers
5
5
  Author: PGWidgets Developers
6
6
  License: BSD-3-Clause
@@ -26,7 +26,7 @@ Requires-Dist: pytest; extra == "test"
26
26
  Dynamic: license-file
27
27
 
28
28
  <p align="center">
29
- <img src="pgwidgets_js/static/icons/pgwidgets-logo.png" alt="pgwidgets logo" width="300">
29
+ <img src="pgwidgets_js/static/icons/pgwidgets-logo.png" alt="pgwidgets logo" width="500">
30
30
  </p>
31
31
 
32
32
  <p align="center">
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="pgwidgets_js/static/icons/pgwidgets-logo.png" alt="pgwidgets logo" width="300">
2
+ <img src="pgwidgets_js/static/icons/pgwidgets-logo.png" alt="pgwidgets logo" width="500">
3
3
  </p>
4
4
 
5
5
  <p align="center">
@@ -1,6 +1,80 @@
1
1
  What's New
2
2
  ==========
3
3
 
4
+ Recent changes — since ``v0.3.3``
5
+ ---------------------------------
6
+
7
+ TextSource: text no longer clipped when scrolling long files
8
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9
+
10
+ A ``TextSource`` holding more than a screenful of text showed only the
11
+ first screen -- the scrollbar reported the full length, but scrolling
12
+ past the first page revealed blank space. The edit area is now laid out
13
+ so it grows to the full content height, and the widget scrolls through
14
+ all of it.
15
+
16
+ TextSource: fonts, hover tooltips, and scroll helpers
17
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18
+
19
+ ``set_font(family, size)`` sets the editor font. Hover tooltips can be
20
+ enabled with ``set_tooltips_enabled(True)``: while enabled the widget
21
+ fires a ``tooltip`` callback carrying the line, column and text under the
22
+ pointer, leaving the host to decide what (if anything) to display. New
23
+ scroll helpers address the buffer by offset (used by ``scroll_to_ref``
24
+ and the remote-driver scroll methods), and ``set_wrap`` now also accepts
25
+ a boolean.
26
+
27
+ TextSource: selection and tag-region queries
28
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29
+
30
+ Four query methods now match Ginga's qt/gtk ``TextSource``:
31
+ ``has_selection()``; ``get_selection_bounds()`` returning the selected
32
+ ``[start, end]`` refs (or ``None``); ``get_tag_region(name)`` returning a
33
+ tag's overall span; and ``get_tag_regions(name)`` returning one
34
+ ``[start, end]`` pair per contiguous run of the tag. They are declared in
35
+ the widget spec, so the Python proxy -- and thus Ginga's pgw
36
+ ``TextSource`` -- can call them.
37
+
38
+ New widget: Separator
39
+ ~~~~~~~~~~~~~~~~~~~~~
40
+
41
+ ``Separator`` is a thin horizontal or vertical rule for visually
42
+ dividing a layout.
43
+
44
+ Button: per-button hover highlight (``set_hover``)
45
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46
+
47
+ ``set_hover(bg, fg)`` mirrors the qt/gtk backends' per-button hover:
48
+ while the pointer is over the button its colors switch to the supplied
49
+ values and revert on mouse-out. Passing ``(None, None)`` clears it. It
50
+ is a setter, so it round-trips and replays on browser reconnect (like
51
+ ``set_color``).
52
+
53
+ ButtonBox: ``min_button_width`` option
54
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55
+
56
+ A ``ButtonBox`` already sizes its buttons to the widest member; the new
57
+ ``min_button_width`` constructor option sets a floor so buttons never
58
+ render narrower than the given width.
59
+
60
+ Dialog: ``set_title``, and correct content-area handling
61
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62
+
63
+ ``set_title`` is now callable on a ``Dialog`` across all wrappers;
64
+ previously the method was undeclared on the ``Dialog`` spec and raised
65
+ ``AttributeError``. Also, ``remove_all`` / ``remove_widget`` /
66
+ ``get_children`` / ``num_children`` now target the dialog's content area,
67
+ matching ``add_widget``. Previously ``remove_all`` tore out the whole
68
+ content-plus-buttons layout, so a rebuilt dialog (e.g. a ``MessageDialog``
69
+ re-showing its message) could leave its content orphaned and blank.
70
+
71
+ TableView: ``set_row_spacing`` / ``set_column_spacing``
72
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
73
+
74
+ The Python proxy for ``TableView`` now exposes ``set_row_spacing`` and
75
+ ``set_column_spacing`` (already implemented by its ``TreeView`` base), so
76
+ cell spacing can be set on a ``TableView``.
77
+
4
78
  Recent changes — since ``v0.3.2``
5
79
  ---------------------------------
6
80
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgwidgets",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "A native JavaScript widget library with Qt/GTK-style layout and controls",
5
5
  "type": "module",
6
6
  "main": "Widgets.js",
@@ -109,7 +109,7 @@ WIDGETS = {
109
109
  "ButtonBox": {
110
110
  "base": "container",
111
111
  "args": [],
112
- "options": ["orientation", "halign"],
112
+ "options": ["orientation", "halign", "min_button_width"],
113
113
  "methods": {
114
114
  "add_widget": ["child", "stretch"],
115
115
  "insert_widget": ["index", "child", "stretch"],
@@ -179,6 +179,17 @@ WIDGETS = {
179
179
  "callbacks": [],
180
180
  },
181
181
 
182
+ "Separator": {
183
+ # A thin horizontal or vertical rule (like an HTML <hr>).
184
+ "base": "widget",
185
+ "args": ["orientation"],
186
+ "options": [],
187
+ "methods": {
188
+ "set_orientation": ["orientation"],
189
+ },
190
+ "callbacks": [],
191
+ },
192
+
182
193
  "Expander": {
183
194
  # JS Expander extends ContainerWidget (single child via set_widget),
184
195
  # so it needs the container method set (get_children, num_children,
@@ -366,6 +377,8 @@ WIDGETS = {
366
377
  "set_position": ["x", "y"],
367
378
  "popup": ["x", "y"],
368
379
  "set_modal": ["tf"],
380
+ # inherited from TopLevel on the JS side (Dialog extends TopLevel)
381
+ "set_title": ["title"],
369
382
  },
370
383
  "callbacks": [*CONTAINER_CALLBACKS, "activated", "move", "close"],
371
384
  },
@@ -409,6 +422,7 @@ WIDGETS = {
409
422
  "set_icon": ["url", "size"],
410
423
  "get_icon": [],
411
424
  "set_color": ["bg", "fg"],
425
+ "set_hover": ["bg", "fg"],
412
426
  },
413
427
  "callbacks": ["activated"],
414
428
  },
@@ -547,10 +561,14 @@ WIDGETS = {
547
561
  "set_wrap": ["mode"],
548
562
  "set_line_numbers": ["tf"],
549
563
  "set_icon_gutter": ["tf"],
564
+ "set_font": ["family", "size"],
565
+ "set_tooltips_enabled": ["tf"],
550
566
  "set_icon": ["ref", "icon_url"],
551
567
  "get_cursor": [],
552
568
  "set_cursor": ["ref"],
553
569
  "get_selection_range": [],
570
+ "has_selection": [],
571
+ "get_selection_bounds": [],
554
572
  "set_selection_range": ["start_ref", "end_ref"],
555
573
  # Tags
556
574
  "create_tag": ["name", "attrs"],
@@ -560,6 +578,8 @@ WIDGETS = {
560
578
  "remove_tag": ["name", "start_ref", "end_ref"],
561
579
  "get_tags_at": ["ref"],
562
580
  "get_tags_range": ["start_ref", "end_ref"],
581
+ "get_tag_region": ["name"],
582
+ "get_tag_regions": ["name"],
563
583
  # Live refs
564
584
  "create_ref": ["offset", "gravity"],
565
585
  "remove_ref": ["ref"],
@@ -594,7 +614,7 @@ WIDGETS = {
594
614
  "get_scroll_position": [],
595
615
  },
596
616
  "callbacks": ["changed", "cursor_moved", "line_clicked",
597
- "icon_clicked", "scrolled"],
617
+ "icon_clicked", "scrolled", "tooltip"],
598
618
  },
599
619
 
600
620
  # A live position handle into a TextSource buffer. Extends the
@@ -830,6 +850,8 @@ WIDGETS = {
830
850
  "select_all": ["state"],
831
851
  "set_column_width": ["col_index", "width"],
832
852
  "set_optimal_column_widths": [],
853
+ "set_row_spacing": ["px"],
854
+ "set_column_spacing": ["px"],
833
855
  "sort_by_column": ["col_index", "ascending"],
834
856
  "scroll_to_path": ["path"],
835
857
  "scroll_to_end": [],
@@ -33,6 +33,7 @@ import {ToggleButton} from "./modules/ToggleButton.js";
33
33
  import {RadioButton} from "./modules/RadioButton.js";
34
34
  import {ProgressBar} from "./modules/ProgressBar.js";
35
35
  import {Frame} from "./modules/Frame.js";
36
+ import {Separator} from "./modules/Separator.js";
36
37
  import {FixedLayout} from "./modules/FixedLayout.js";
37
38
  import {GridBox} from "./modules/GridBox.js";
38
39
  import {Image} from "./modules/Image.js";
@@ -61,7 +62,7 @@ const Widgets = {Callback, Widget, ContainerWidget, Box, VBox, HBox, ButtonBox,
61
62
  TopLevel, AbstractScrollArea, ScrollArea, MDIWidget, Splitter, TabWidget,
62
63
  StackWidget, Expander, Page, Text, Label, StatusBar, TextArea, TextSource,
63
64
  TextBufferRef,
64
- Frame, FixedLayout, GridBox, Button, ToggleButton, CheckBox,
65
+ Frame, Separator, FixedLayout, GridBox, Button, ToggleButton, CheckBox,
65
66
  RadioButton, ComboBox, ComboBoxNative, TextEntry,
66
67
  Slider, Canvas, SpinBox, ProgressBar, Image, Dial,
67
68
  MenuBar, Menu, MenuAction, ToolBar, ToolBarAction,
@@ -29,6 +29,14 @@
29
29
  grid-column: 1;
30
30
  display: flex;
31
31
  flex-direction: row;
32
+ /* Top-align children so the edit wrap grows to its full content
33
+ height instead of being stretched (and clipped) to the visible
34
+ height. With the default `stretch`, `.textsource-edit-wrap`
35
+ (overflow: hidden) gets capped at the viewport height and clips
36
+ the text to one screenful, while the number gutter (overflow
37
+ visible) still reports the full height -- so the scrollbar looks
38
+ right but scrolling reveals blank space. */
39
+ align-items: flex-start;
32
40
  overflow-y: auto;
33
41
  overflow-x: hidden;
34
42
  min-height: 0;
@@ -47,6 +55,8 @@
47
55
  background: #f4f4f4;
48
56
  border-right: 1px solid #e0e0e0;
49
57
  user-select: none;
58
+ /* fill the viewport height for short documents (see .textsource-main) */
59
+ min-height: 100%;
50
60
  }
51
61
 
52
62
  .textsource-icon-cell {
@@ -75,6 +85,8 @@
75
85
  font-size: 12px;
76
86
  text-align: right;
77
87
  user-select: none;
88
+ /* fill the viewport height for short documents (see .textsource-main) */
89
+ min-height: 100%;
78
90
  }
79
91
 
80
92
  .textsource-line-number {
@@ -88,6 +100,12 @@
88
100
  flex: 1 1 auto;
89
101
  position: relative;
90
102
  overflow: hidden;
103
+ /* Fill the viewport height for short documents (children are
104
+ top-aligned in .textsource-main, so without this the box would
105
+ shrink to its content height). For tall documents the box grows
106
+ past this to its full content height, letting .textsource-main
107
+ be the single vertical scroller. */
108
+ min-height: 100%;
91
109
  min-width: 0;
92
110
  /* hide native horizontal scrollbar; we use ScrollBar widget */
93
111
  scrollbar-width: none;
@@ -214,6 +214,9 @@ class ButtonBox extends Box {
214
214
  constructor(options = { orientation: 'horizontal' }) {
215
215
  super(options);
216
216
  this._halign = this.get_option(options, 'halign', 'center');
217
+ // optional lower bound: buttons are never narrower than this, even
218
+ // if the widest button's natural size is smaller
219
+ this._minButtonWidth = this.get_option(options, 'min_button_width', null);
217
220
  this._applyAlign();
218
221
 
219
222
  }
@@ -281,8 +284,9 @@ class ButtonBox extends Box {
281
284
  let w = elt.getBoundingClientRect().width;
282
285
  if (w > maxW) maxW = w;
283
286
  }
284
- if (maxW > 0) {
285
- let px = Math.ceil(maxW) + 'px';
287
+ let target = Math.max(Math.ceil(maxW), this._minButtonWidth || 0);
288
+ if (target > 0) {
289
+ let px = target + 'px';
286
290
  for (let child of this.children) {
287
291
  let elt = child.get_element();
288
292
  elt.style.minWidth = px;
@@ -35,6 +35,11 @@ class Button extends Widget {
35
35
 
36
36
  this.element.onclick = () => this._cb_redirect('clicked');
37
37
  this.enable_callback('activated');
38
+
39
+ // hover highlight colors (see set_hover); null = no hover override
40
+ this._hoverBg = null;
41
+ this._hoverFg = null;
42
+ this._hoverInstalled = false;
38
43
  }
39
44
 
40
45
  /**
@@ -114,6 +119,58 @@ class Button extends Widget {
114
119
  }
115
120
  }
116
121
 
122
+ /**
123
+ * Give this button a hover highlight: while the pointer is over the
124
+ * button its background/foreground switch to the supplied colors,
125
+ * reverting on mouse-out. Mirrors the qt/gtk backends' per-button
126
+ * hover. Pass ``(null, null)`` or empty strings to clear it.
127
+ *
128
+ * Implemented with mouseenter/mouseleave that swap (and restore) the
129
+ * inline style, because an inline base background set via set_color
130
+ * would otherwise win over a CSS ``:hover`` rule.
131
+ *
132
+ * @param {string|null} [bg=null] - Hover background CSS color.
133
+ * @param {string|null} [fg=null] - Hover foreground (text) CSS color.
134
+ */
135
+ set_hover(bg=null, fg=null) {
136
+ this._hoverBg = (bg === '') ? null : bg;
137
+ this._hoverFg = (fg === '') ? null : fg;
138
+ if (!this._hoverInstalled) {
139
+ this._hoverInstalled = true;
140
+ this.element.addEventListener('mouseenter',
141
+ () => this._applyHover());
142
+ this.element.addEventListener('mouseleave',
143
+ () => this._restoreHover());
144
+ }
145
+ }
146
+
147
+ _applyHover() {
148
+ if (this._hoverBg === null && this._hoverFg === null) {
149
+ return;
150
+ }
151
+ // remember whatever inline colors are in effect (e.g. a base color
152
+ // from set_color, or '' for the default look) so we can restore them
153
+ this._savedBg = this.element.style.background;
154
+ this._savedFg = this.element.style.color;
155
+ if (this._hoverBg !== null) {
156
+ this.element.style.background = this._hoverBg;
157
+ }
158
+ if (this._hoverFg !== null) {
159
+ this.element.style.color = this._hoverFg;
160
+ }
161
+ }
162
+
163
+ _restoreHover() {
164
+ if (this._savedBg !== undefined) {
165
+ this.element.style.background = this._savedBg;
166
+ this._savedBg = undefined;
167
+ }
168
+ if (this._savedFg !== undefined) {
169
+ this.element.style.color = this._savedFg;
170
+ this._savedFg = undefined;
171
+ }
172
+ }
173
+
117
174
  _cb_redirect(action) {
118
175
  if (action === 'clicked') {
119
176
  this.make_callback('activated');
@@ -149,6 +149,42 @@ class Dialog extends TopLevel {
149
149
  this._contentArea.set_spacing(gap);
150
150
  }
151
151
 
152
+ /**
153
+ * Removes a widget from the dialog's content area.
154
+ * @param {Widget} child - The widget to remove.
155
+ * @param {boolean} [destroy=false] - If true, also destroy the child.
156
+ */
157
+ remove_widget(child, destroy = false) {
158
+ this._contentArea.remove_widget(child, destroy);
159
+ }
160
+
161
+ /**
162
+ * Removes all widgets from the dialog's content area, leaving the
163
+ * button bar intact. (The base implementation would clear the
164
+ * dialog's own children -- the content area + button bar -- which
165
+ * detaches the layout; delegate here to match add_widget().)
166
+ * @param {boolean} [destroy=false] - If true, also destroy each child.
167
+ */
168
+ remove_all(destroy = false) {
169
+ this._contentArea.remove_all(destroy);
170
+ }
171
+
172
+ /**
173
+ * Returns the content area's child widgets.
174
+ * @returns {Widget[]} The children array.
175
+ */
176
+ get_children() {
177
+ return this._contentArea.get_children();
178
+ }
179
+
180
+ /**
181
+ * Returns the number of widgets in the dialog's content area.
182
+ * @returns {number} The child count.
183
+ */
184
+ num_children() {
185
+ return this._contentArea.num_children();
186
+ }
187
+
152
188
  /**
153
189
  * Adds a button widget to the dialog's button bar.
154
190
  * Clicking the button fires the dialog's 'activated' callback
@@ -0,0 +1,55 @@
1
+ "use_strict";
2
+
3
+ import {Widget} from "./Widget.js";
4
+
5
+ /**
6
+ * A thin separator rule (like an HTML <hr>). Rendered as a 1px border on
7
+ * one edge of a zero-thickness div so it takes essentially no space along
8
+ * its thin axis while stretching along the other.
9
+ * @extends Widget
10
+ */
11
+ class Separator extends Widget {
12
+
13
+ /**
14
+ * @param {string} [orientation='horizontal'] - 'horizontal' or 'vertical'.
15
+ * @param {Object} [options]
16
+ */
17
+ constructor(orientation='horizontal', options={}) {
18
+ super();
19
+ // orientation may arrive positionally or in the options dict
20
+ if (orientation != null && typeof orientation === 'object') {
21
+ options = orientation;
22
+ orientation = null;
23
+ }
24
+ this._orientation = orientation
25
+ || this.get_option(options, 'orientation', 'horizontal');
26
+
27
+ this.element = document.createElement('div');
28
+ this.element.className = 'separator-widget';
29
+ this._applyOrientation();
30
+
31
+ super.init_style();
32
+ }
33
+
34
+ _applyOrientation() {
35
+ let s = this.element.style;
36
+ s.borderTop = s.borderLeft = '';
37
+ s.width = s.height = '';
38
+ if (this._orientation === 'vertical') {
39
+ s.width = '0px';
40
+ s.height = '100%';
41
+ s.borderLeft = '1px solid #888';
42
+ } else {
43
+ s.height = '0px';
44
+ s.width = '100%';
45
+ s.borderTop = '1px solid #888';
46
+ }
47
+ }
48
+
49
+ set_orientation(orientation) {
50
+ this._orientation = orientation || 'horizontal';
51
+ this._applyOrientation();
52
+ }
53
+ }
54
+
55
+ export { Separator };
@@ -454,6 +454,14 @@ class TextSource extends Widget {
454
454
  this._captureSelection();
455
455
  }
456
456
  });
457
+
458
+ // -- hover tooltips (fire 'tooltip'; the page decides what to show) --
459
+ this._tooltipsEnabled = false;
460
+ this._tooltipTimer = null;
461
+ this._tooltipEl = null;
462
+ this._edit.addEventListener('mousemove', (e) => this._onHoverMove(e));
463
+ this._edit.addEventListener('mouseleave', () => this._hideTooltip());
464
+
457
465
  requestAnimationFrame(() => { this._scrollReady = true; });
458
466
  }
459
467
 
@@ -816,6 +824,25 @@ class TextSource extends Widget {
816
824
  this.create_ref(e, 'right')];
817
825
  }
818
826
 
827
+ /**
828
+ * Whether there is a non-empty selection.
829
+ * @returns {boolean}
830
+ */
831
+ has_selection() {
832
+ return this._selStart !== this._selEnd;
833
+ }
834
+
835
+ /**
836
+ * Canonical accessor used by page-level code. Returns
837
+ * ``[startRef, endRef]`` for the current selection, or ``null``
838
+ * when there is no selection (guard with ``has_selection()``).
839
+ * Alias of ``get_selection_range``; does not throw.
840
+ * @returns {?[TextBufferRef, TextBufferRef]}
841
+ */
842
+ get_selection_bounds() {
843
+ return this.get_selection_range();
844
+ }
845
+
819
846
  /**
820
847
  * Set the selection to span ``[startRef, endRef]``. The cursor
821
848
  * lands at *endRef*'s position.
@@ -841,6 +868,9 @@ class TextSource extends Widget {
841
868
  }
842
869
 
843
870
  set_wrap(mode) {
871
+ // Tolerate a boolean (some callers pass true/false): map to a mode.
872
+ if (mode === true) mode = 'word';
873
+ else if (mode === false) mode = 'none';
844
874
  if (!['none', 'hard', 'word'].includes(mode)) {
845
875
  throw new Error(`Invalid wrap mode: ${mode}`);
846
876
  }
@@ -861,6 +891,106 @@ class TextSource extends Widget {
861
891
  this._render();
862
892
  }
863
893
 
894
+ /**
895
+ * Set the editor font. ``family`` and/or ``size`` (px) may be null to
896
+ * leave that dimension unchanged. The line-number gutter is kept in the
897
+ * same font so its rows stay aligned with the text.
898
+ * @param {?string} family
899
+ * @param {?number} size
900
+ */
901
+ set_font(family, size) {
902
+ if (family != null) this._fontFamily = family;
903
+ if (size != null) this._fontSize = size;
904
+ for (let el of [this._edit, this._numberGutter]) {
905
+ if (el) {
906
+ el.style.fontFamily = this._fontFamily;
907
+ el.style.fontSize = this._fontSize + 'px';
908
+ }
909
+ }
910
+ this._render();
911
+ }
912
+
913
+ /** Enable/disable hover tooltips (which fire the 'tooltip' callback). */
914
+ set_tooltips_enabled(tf) {
915
+ this._tooltipsEnabled = !!tf;
916
+ if (!this._tooltipsEnabled) this._hideTooltip();
917
+ }
918
+
919
+ _onHoverMove(e) {
920
+ if (!this._tooltipsEnabled) return;
921
+ // Hide any showing tooltip while the pointer moves, and (re)arm a
922
+ // timer so we only query once the pointer settles -- like a native
923
+ // tooltip.
924
+ this._hideTooltip();
925
+ let x = e.clientX, y = e.clientY;
926
+ this._tooltipTimer = setTimeout(() => {
927
+ this._tooltipTimer = null;
928
+ let hit = this._lineColFromPoint(x, y);
929
+ if (hit === null) return;
930
+ // The page appends a string to the callback's result list (on the
931
+ // Python side) and calls _showTooltip() if it wants one shown.
932
+ this.make_callback('tooltip', hit.line, hit.col, hit.text, x, y);
933
+ }, 400);
934
+ }
935
+
936
+ _lineColFromPoint(x, y) {
937
+ let cp = null;
938
+ if (document.caretPositionFromPoint) {
939
+ let p = document.caretPositionFromPoint(x, y);
940
+ if (p) cp = {node: p.offsetNode, offset: p.offset};
941
+ } else if (document.caretRangeFromPoint) {
942
+ let r = document.caretRangeFromPoint(x, y);
943
+ if (r) cp = {node: r.startContainer, offset: r.startOffset};
944
+ }
945
+ if (!cp || !cp.node) return null;
946
+ let el = cp.node.nodeType === Node.TEXT_NODE ? cp.node.parentNode
947
+ : cp.node;
948
+ let lineDiv = el && el.closest ? el.closest('.textsource-line') : null;
949
+ if (!lineDiv) return null;
950
+ // column = length of text from the line start up to the caret point
951
+ let range = document.createRange();
952
+ range.selectNodeContents(lineDiv);
953
+ try {
954
+ range.setEnd(cp.node, cp.offset);
955
+ } catch (err) {
956
+ return null;
957
+ }
958
+ return {line: parseInt(lineDiv.dataset.lineIndex, 10) || 0,
959
+ col: range.toString().length,
960
+ text: lineDiv.textContent};
961
+ }
962
+
963
+ /** Show (non-empty text) or hide (empty) a tooltip near (x, y). */
964
+ _showTooltip(text, x, y) {
965
+ if (!text) { this._hideTooltip(); return; }
966
+ if (this._tooltipEl === null) {
967
+ let el = document.createElement('div');
968
+ el.className = 'textsource-tooltip';
969
+ Object.assign(el.style, {
970
+ position: 'fixed', zIndex: '10000', background: '#ffffe0',
971
+ color: '#000', border: '1px solid #888', padding: '2px 6px',
972
+ font: '12px sans-serif', pointerEvents: 'none',
973
+ maxWidth: '400px', whiteSpace: 'pre-wrap',
974
+ });
975
+ document.body.appendChild(el);
976
+ this._tooltipEl = el;
977
+ }
978
+ this._tooltipEl.textContent = text;
979
+ this._tooltipEl.style.left = (x + 12) + 'px';
980
+ this._tooltipEl.style.top = (y + 16) + 'px';
981
+ this._tooltipEl.style.display = 'block';
982
+ }
983
+
984
+ _hideTooltip() {
985
+ if (this._tooltipTimer !== null) {
986
+ clearTimeout(this._tooltipTimer);
987
+ this._tooltipTimer = null;
988
+ }
989
+ if (this._tooltipEl !== null) {
990
+ this._tooltipEl.style.display = 'none';
991
+ }
992
+ }
993
+
864
994
  /**
865
995
  * Set (or clear) the icon associated with a TextBufferRef. The
866
996
  * icon is displayed on the line that contains the ref's current
@@ -1728,6 +1858,48 @@ class TextSource extends Widget {
1728
1858
  return Array.from(names);
1729
1859
  }
1730
1860
 
1861
+ /**
1862
+ * Returns the overall ``[startRef, endRef]`` span of a named tag —
1863
+ * from the first occurrence of the tag to the last — or ``null`` if
1864
+ * the tag is not applied anywhere. This is the replacement for the
1865
+ * old GTK ``get_region`` helper used by page-level code.
1866
+ * @param {string} name
1867
+ * @returns {?[TextBufferRef, TextBufferRef]}
1868
+ */
1869
+ get_tag_region(name) {
1870
+ let spans = this._tags.filter(t => t.name === name);
1871
+ if (spans.length === 0) return null;
1872
+ let start = Math.min(...spans.map(t => t.start));
1873
+ let end = Math.max(...spans.map(t => t.end));
1874
+ return [this.create_ref(start, 'right'),
1875
+ this.create_ref(end, 'right')];
1876
+ }
1877
+
1878
+ /**
1879
+ * Returns an array of ``[startRef, endRef]`` pairs, one per maximal
1880
+ * contiguous run of the named tag. Empty array if unapplied.
1881
+ * @param {string} name
1882
+ * @returns {Array<[TextBufferRef, TextBufferRef]>}
1883
+ */
1884
+ get_tag_regions(name) {
1885
+ let spans = this._tags.filter(t => t.name === name)
1886
+ .sort((a, b) => a.start - b.start);
1887
+ if (spans.length === 0) return [];
1888
+ let merged = [];
1889
+ let curStart = spans[0].start, curEnd = spans[0].end;
1890
+ for (let t of spans.slice(1)) {
1891
+ if (t.start <= curEnd) {
1892
+ curEnd = Math.max(curEnd, t.end);
1893
+ } else {
1894
+ merged.push([curStart, curEnd]);
1895
+ curStart = t.start; curEnd = t.end;
1896
+ }
1897
+ }
1898
+ merged.push([curStart, curEnd]);
1899
+ return merged.map(([s, e]) => [this.create_ref(s, 'right'),
1900
+ this.create_ref(e, 'right')]);
1901
+ }
1902
+
1731
1903
  _updateTagsOnInsert(offset, n) {
1732
1904
  for (let t of this._tags) {
1733
1905
  if (t.start >= offset) t.start += n;
@@ -1826,8 +1998,18 @@ class TextSource extends Widget {
1826
1998
  * @param {TextBufferRef} ref
1827
1999
  */
1828
2000
  scroll_to_ref(ref) {
1829
- let offset = this._offsetOf(ref);
1830
- let line = this._lineOfOffset(offset);
2001
+ this._scrollToOffset(this._offsetOf(ref));
2002
+ }
2003
+
2004
+ /**
2005
+ * Scroll so the line containing *offset* is visible. Reconstruction /
2006
+ * remote-driver counterpart to ``scroll_to_ref`` that avoids minting a
2007
+ * ref over the wire (the Python side owns the ref and passes its offset).
2008
+ * @private
2009
+ * @param {number} offset
2010
+ */
2011
+ _scrollToOffset(offset) {
2012
+ let line = this._lineOfOffset(this._clampOffset(offset));
1831
2013
  let lineDiv = this._edit.children[line];
1832
2014
  if (lineDiv && lineDiv.scrollIntoView) {
1833
2015
  lineDiv.scrollIntoView({ block: 'nearest' });