From afecb27e435cc55b35ac3a0de428f3e65b224b42 Mon Sep 17 00:00:00 2001 From: Jeff Zohrab Date: Sun, 29 Sep 2024 20:39:09 -0700 Subject: [PATCH 1/3] Add popup show/hide logic to service. --- lute/read/routes.py | 4 +- lute/read/service.py | 15 ++++++- tests/unit/read/test_service_popup_data.py | 47 +++++++++++++++++++++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/lute/read/routes.py b/lute/read/routes.py index 4bef86fa..fed6af31 100644 --- a/lute/read/routes.py +++ b/lute/read/routes.py @@ -214,9 +214,11 @@ def edit_term_form(term_id): @bp.route("/termpopup/", methods=["GET"]) def term_popup(termid): """ - Show a term popup for the given DBTerm. + Get popup html for DBTerm, or None if nothing should be shown. """ d = get_popup_data(termid) + if d is None: + return "" return render_template( "read/termpopup.html", term=d["term"], diff --git a/lute/read/service.py b/lute/read/service.py index f1ed19c4..ee34813a 100644 --- a/lute/read/service.py +++ b/lute/read/service.py @@ -93,9 +93,22 @@ def start_reading(dbbook, pagenum, db_session): def get_popup_data(termid): - "Get the data necessary to render a term popup." + "Get popup data, or None if popup shouldn't be shown." term = Term.find(termid) + if term.status in [Status.UNKNOWN, Status.WELLKNOWN, Status.IGNORED]: + return None + + def has_popup_data(cterm): + return ( + (cterm.translation or "").strip() != "" + or (cterm.romanization or "").strip() != "" + or cterm.get_current_image() is not None + ) + + if not any(has_popup_data(t) for t in (term, *term.parents)): + return None + term_tags = [tt.text for tt in term.term_tags] def make_array(t): diff --git a/tests/unit/read/test_service_popup_data.py b/tests/unit/read/test_service_popup_data.py index e7094894..a902008f 100644 --- a/tests/unit/read/test_service_popup_data.py +++ b/tests/unit/read/test_service_popup_data.py @@ -2,14 +2,53 @@ Term popup data tests. """ -from lute.models.term import Term +from lute.models.term import Term, Status from lute.read.service import get_popup_data from lute.db import db +def test_popup_data_is_none_if_no_data(spanish, app_context): + "Return None if no popup." + t = Term(spanish, "gato") + db.session.add(t) + db.session.commit() + + d = get_popup_data(t.id) + assert d is None, "No data, no popup" + + t.translation = "hello" + d = get_popup_data(t.id) + assert d is not None, "Have data, popup" + + for s in [Status.UNKNOWN, Status.WELLKNOWN, Status.IGNORED]: + t.status = s + d = get_popup_data(t.id) + assert d is None, "No popup for these statuses" + + +def test_popup_data_is_none_for_some_statuses(spanish, app_context): + "Return None if no-popup statuses." + t = Term(spanish, "gato") + db.session.add(t) + db.session.commit() + t.translation = "hello" + d = get_popup_data(t.id) + assert d is not None, "Have data, popup" + + for s in [Status.UNKNOWN, Status.WELLKNOWN, Status.IGNORED]: + t.status = s + d = get_popup_data(t.id) + assert d is None, "No popup for these statuses" + + t.status = 1 + d = get_popup_data(t.id) + assert d is not None, "Have data for these statuses" + + def test_term_with_no_parents(spanish, app_context): "Keep the lights on test, smoke only." t = Term(spanish, "gato") + t.translation = "cat" db.session.add(t) db.session.commit() @@ -101,6 +140,7 @@ def _c_to_string(c): def test_single_term_not_included_in_own_components(spanish, app_context): "Keep the lights on test, smoke only." t = Term(spanish, "gato") + t.translation = "cat" db.session.add(t) db.session.commit() @@ -111,6 +151,7 @@ def test_single_term_not_included_in_own_components(spanish, app_context): def test_component_without_translation_not_returned(spanish, app_context): "Component word is returned." t = Term(spanish, "un gato") + t.translation = "a cat" db.session.add(t) make_terms([("gato", "")], spanish) db.session.commit() @@ -122,6 +163,7 @@ def test_component_without_translation_not_returned(spanish, app_context): def test_component_word_with_translation_returned(spanish, app_context): "Component word is returned." t = Term(spanish, "un gato") + t.translation = "a cat" db.session.add(t) make_terms([("gato", "cat")], spanish) db.session.commit() @@ -133,6 +175,7 @@ def test_component_word_with_translation_returned(spanish, app_context): def test_nested_multiword_components(spanish, app_context): "Complete components are returned." t = Term(spanish, "un gato gordo") + t.translation = "a fat cat" db.session.add(t) make_terms([("gato", "cat"), ("gat", "x"), ("un gato", "a cat")], spanish) db.session.commit() @@ -144,6 +187,7 @@ def test_nested_multiword_components(spanish, app_context): def test_multiword_components_returned_in_order_of_appearance(spanish, app_context): "Complete components are returned." t = Term(spanish, "un gato gordo") + t.translation = "a fat cat" db.session.add(t) make_terms( [ @@ -165,6 +209,7 @@ def test_multiword_components_returned_in_order_of_appearance(spanish, app_conte def test_components_only_returned_once(spanish, app_context): "Component not returned multiple times if present multiple times." t = Term(spanish, "un gato gordo gato") + t.translation = "a cat fat cat" db.session.add(t) make_terms([("gato", "cat")], spanish) db.session.commit() From 6f5b34cfcda344c5a72916ed03f94cc907a8babe Mon Sep 17 00:00:00 2001 From: Jeff Zohrab Date: Sun, 29 Sep 2024 20:48:44 -0700 Subject: [PATCH 2/3] Remove redundant code. The tooltip is not shown if it has empty content. The service method now returns an empty string if a term shouldn't have a tooltip, so this code is no longer needed. --- lute/read/render/renderable_calculator.py | 47 ----------------------- lute/static/js/lute.js | 2 +- 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/lute/read/render/renderable_calculator.py b/lute/read/render/renderable_calculator.py index 8b0a7833..9adc1f32 100644 --- a/lute/read/render/renderable_calculator.py +++ b/lute/read/render/renderable_calculator.py @@ -448,13 +448,6 @@ def __init__(self, term=None): # Calls setter self.term = term - # The tooltip should be shown for well-known/ignored TextItems - # that merit a tooltip. e.g., if there isn't any actual Term - # entity associated with this TextItem, nothing more is needed. - # Also, if there is a Term entity but it's mostly empty, a - # tooltip isn't useful. - self._show_tooltip: bool = None - # The flash message can be None, so we need an extra flag # to determine if it has been loaded or not. self._flash_message_loaded: bool = False @@ -480,39 +473,7 @@ def term(self, t): self._term = t if t is None: return - self.wo_status = t.status - if t.status >= 1 and t.status <= 5: - self._show_tooltip = True - - @property - def show_tooltip(self): - """ - Show the tooltip if there is anything to show. - Lazy loaded as needed. - """ - if self._show_tooltip is not None: - return self._show_tooltip - if self.term is None: - return False - - def blank_string(s): - return s is None or s.strip() == "" - - def has_extra(cterm): - if cterm is None: - return False - no_extra = ( - blank_string(cterm.translation) - and blank_string(cterm.romanization) - and cterm.get_current_image() is None - ) - return not no_extra - - self._show_tooltip = has_extra(self.term) - for p in self.term.parents: - self._show_tooltip = self._show_tooltip or has_extra(p) - return self._show_tooltip @property def flash_message(self): @@ -575,14 +536,6 @@ def html_class_string(self): "word" + str(self.wo_id), ] - tooltip = ( - st not in (Status.WELLKNOWN, Status.IGNORED, Status.UNKNOWN) - or self.show_tooltip - or self.flash_message is not None - ) - if tooltip: - classes.append("showtooltip") - if self.flash_message is not None: classes.append("hasflash") diff --git a/lute/static/js/lute.js b/lute/static/js/lute.js index bf6b6ea6..82abce68 100644 --- a/lute/static/js/lute.js +++ b/lute/static/js/lute.js @@ -120,7 +120,7 @@ function prepareTextInteractions() { $('#thetext').tooltip({ position: _get_tooltip_pos(), - items: '.word.showtooltip', + items: '.word', show: { easing: 'easeOutCirc' }, content: function (setContent) { tooltip_textitem_hover_content($(this), setContent); } }); From b3dd9232be7b5d2e01d9630043d8de5519caa59b Mon Sep 17 00:00:00 2001 From: Jeff Zohrab Date: Sun, 29 Sep 2024 20:57:00 -0700 Subject: [PATCH 3/3] Fix lint. --- lute/read/render/renderable_calculator.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lute/read/render/renderable_calculator.py b/lute/read/render/renderable_calculator.py index 9adc1f32..d4db9275 100644 --- a/lute/read/render/renderable_calculator.py +++ b/lute/read/render/renderable_calculator.py @@ -5,7 +5,7 @@ import re import functools from lute.models.language import Language -from lute.models.term import Term, Status +from lute.models.term import Term # from lute.utils.debug_helpers import DebugTimer @@ -528,7 +528,6 @@ def html_class_string(self): classes = ["textitem", "click", "word"] return " ".join(classes) - st = self.wo_status classes = [ "textitem", "click",