Skip to content

feat(notes): גופן כתב-יד ללוח, בהגדרה פר-לוח - #3279

Merged
amirbiron merged 3 commits into
mainfrom
claude/bot-hacked-messages-comsrh
Aug 26, 2026
Merged

feat(notes): גופן כתב-יד ללוח, בהגדרה פר-לוח#3279
amirbiron merged 3 commits into
mainfrom
claude/bot-hacked-messages-comsrh

Conversation

@amirbiron

@amirbiron amirbiron commented Aug 26, 2026

Copy link
Copy Markdown
Owner

✨ תיאור קצר

מתג חדש במודאל הגדרות הלוח — כתב יד — שמציג את הפתקים בלוח בגופן כתב-יד עברי (Gveret Levin). ההגדרה היא לכל לוח בנפרד, כך שאפשר להחזיק לוח אחד ל"רשימות ביד" ולוחות אחרים כרגיל.

📦 שינויים עיקריים

  • קוד (Backend)
  • בוט טלגרם
  • מסד נתונים/מיגרציות
  • תיעוד (docs/)
  • DevOps/CI/CD

הגדרה, לא לוח קשיח

השאלה הפתוחה הייתה אם לייצר לוח מיוחד. התשובה היא הגדרה, כי למודאל כבר יש שני מתגים פר-לוח והשלישי נכנס לאותה תבנית בדיוק: 'board-handwriting:' + BOARD_ID לצד board-markdown: ו-board-infinite:. כך שם הלוח נשאר בידי המשתמש ואינו כתוב בקוד.

שתי החלטות שאינן קוסמטיות

המחלקה יושבת על <body> ולא על מכל הפתקים. פתק במצב screen מרונדר תחת document.body ולא בתוך המכל, ומחלקה על המכל הייתה מדלגת עליו בשקט — פתק אחד בלוח שנשאר בגופן אחר בלי שום סימן שמשהו לא עבד.

קוד נשאר מונוספייס. הסלקטור עם .board-handwriting ספציפי יותר מהכללים הקיימים של .sticky-md-code ו-.sticky-md-pre, ובלי החרגה מפורשת הוא היה גובר עליהם דרך הירושה מהמכל. נתיב קובץ בכתב-יד אינו קריא.

מה שנבדק מראש והסיר סיכון

  • ה-CSP אינו משתנה. הוא כבר מתיר את שני המארחים הנדרשים: style-src את fonts.googleapis.com, ו-font-src את fonts.gstatic.com. זה היה החשש הגדול.
  • התבנית קיימת. base.html כבר טוען Heebo מגוגל עם preconnect, ו-note_board.html יורש ממנו.
  • הגופן אומת מול המקור ולא מהסניפט שנמסר: curl החזיר HTTP 200, שם המשפחה הוא בדיוק 'Gveret Levin', והוא מכסה עברית (U+0590-05FF), U+20AA ולטינית.
  • אין רישום שצריך לעדכןALLOWED_VARIABLES_WHITELIST נוגע לטוקני ערכת נושא, וגופן על מחלקה אינו טוקן. לכן גם לא הוסף משתנה CSS חדש.

🧪 בדיקות

  • Unit
  • Integration
  • Manual

שני טסטים חדשים ב-tests/test_note_boards_ui.py, שניהם נופלים בלי השינוי — נבדק בהרצה:

  1. המפתח נושא את מזהה הלוח. זה מה שנבדק, לא רק קיום המתג: מפתח גלובלי היה מדליק את כל הלוחות יחד, וזה כשל שנראה זהה לחלוטין בבדיקה ידנית על לוח יחיד. הטסט בודק גם ששתי ההעדפות הקיימות שומרות על אותה צורה, כך ששינוי באחת יזכיר את השנייה.
  2. הגופן נטען — אחרת המתג מחליף למשפחה שאינה קיימת ושום דבר לא משתנה.

אימות בדפדפן — שלוש טענות שנמדדו

מה תוצאה
הגופן באמת מרונדר רוחב אותה מחרוזת עברית: 136 ← 160px עם הדלקת המחלקה
קובץ הגופן יורד רק כשהוא בשימוש אפס בקשות woff2 לפני ההדלקה, שתיים אחריה
הקוד נשאר מונוספייס ui-monospace בשני המצבים

השורה הראשונה חשובה במיוחד: getComputedStyle().fontFamily לבדו אינו ראיה — הוא מציג את מה שהוצהר ב-CSS, לא את מה שרונדר. בבדיקה ראשונה הוא הראה "Gveret Levin" בזמן שהגופן כלל לא נטען. רוחב הטקסט הוא מה שמבדיל.

לא אימתתי שהגיליון מגוגל נטען בפרודקשן, כי Chromium בסביבה הזו חסום מ-Google Fonts (net::ERR_CONNECTION_RESET); לצורך האימות הגשתי את קובצי ה-woff2 מקומית תחת אותו שם משפחה. ה-CSP מתיר, ו-Heebo כבר נטען באותה דרך.

📝 סוג שינוי

  • feat: פיצ'ר חדש
  • docs: שינוי תיעוד

✅ צ'קליסט

  • בדיקות רצות ועוברות
  • תיעוד עודכן — docs/user/sticky_notes.rst, לפי הכלל שנוסף ב-feat(notes): מארקדאון מרונדר כברירת מחדל בכל שלושת יעדי הפתקים #3277
  • אין סודות/מפתחות בקוד
  • אין מחיקות מסוכנות
  • הודעת הקומיט תואמת Conventional Commits
  • עיינתי במסמכי אתר התיעוד — נתיב: docs/dev/sticky_notes_extending.rst | המשפט: הכלל "התיעוד למשתמש הוא חלק מהפיצ'ר" חייב את עדכון עמוד המשתמש באותו PR, והכלל על innerHTML נבדק ונמצא לא רלוונטי כאן (CSS ומתג, בלי רינדור טקסט משתמש).

🧩 השפעות/סיכונים

  • עלות בעמודים שאינם משתמשים בגופן: בקשת גיליון סגנון אחת של 736 בתים. קובץ ה-woff2 (11KB עברית) יורד רק כשהגופן מוחל בפועל — נמדד.
  • לגופן משקל 400 בלבד, ולכן טקסט מודגש מוצג בהדגשה שהדפדפן מסנתז. נבדק בצילום ונמצא קריא כהדגשה ולא מרוח.
  • ההעדפה מקומית לדפדפן, כמו שתי ההעדפות הקיימות לצידה.

🔗 ממצא נלווה (לא תוקן כאן)

בקריאת sticky_notes_extending.rst התגלה שהפסקה תחת "רוחב" התיישנה: היא טוענת ש-max-width: 100% על טבלה "דוחסת את העמודות במקום להיגלל, נמדד בדפדפן". המדידה שמאחוריה נעשתה על פתק צר שנבנה לצורך הבדיקה ואינו מייצג את הרוחב שבו הפתקים בשימוש. תיאור הקוד עצמו עדיין מדויק — רק הנימוק חלש. לא צורף לכאן כדי לא לערבב נושאים.

🧯 סיכון / החזרה לאחור

תבניות ו-CSS בלבד, בלי מיגרציה ובלי שינוי סכימה. חזרה לאחור היא git revert של הקומיט.


Generated by Claude Code

Summary by Sourcery

Add an optional per-board handwriting style for sticky notes while preserving existing board preferences and code readability.

New Features:

  • Add a per-board handwriting font setting for sticky notes using Gveret Levin, with the preference persisted locally and applied across the board surface.

Enhancements:

  • Load the handwriting font conditionally and preserve monospace styling for code content.

Documentation:

  • Document the new handwriting display option in the sticky notes user documentation.

Tests:

  • Add template and JavaScript coverage for per-board preference isolation, font loading behavior, local-storage failures, and style application.

Review in cubic

הבקשה הייתה שלוח מסוים — "רשימות ביד" — יציג את הפתקים בכתב יד. **המימוש
הוא הגדרה ולא לוח קשיח:** למודאל הגדרות הלוח כבר יש שני מתגים פר-לוח,
והשלישי נכנס לאותה תבנית בדיוק, עם ``'board-handwriting:' + BOARD_ID``
לצד ``board-markdown:`` ו-``board-infinite:``. כך שם הלוח נשאר בידי
המשתמש ואינו כתוב בקוד.

**המחלקה יושבת על ``<body>`` ולא על מכל הפתקים.** פתק במצב ``screen``
מרונדר תחת ``document.body`` ולא בתוך המכל, ומחלקה על המכל הייתה מדלגת
עליו בשקט — פתק אחד בלוח שנשאר בגופן אחר בלי שום סימן.

**קוד נשאר מונוספייס.** הסלקטור עם ``.board-handwriting`` ספציפי יותר
מהכללים הקיימים של ``.sticky-md-code`` ו-``.sticky-md-pre``, ובלי החרגה
מפורשת הוא היה גובר עליהם דרך הירושה. נתיב קובץ בכתב-יד אינו קריא.

מה שנבדק מראש: ה-CSP כבר מתיר את שני המארחים — ``style-src`` את
``fonts.googleapis.com`` ו-``font-src`` את ``fonts.gstatic.com`` — ולכן
אין בו שינוי. ``base.html`` כבר טוען Heebo מגוגל עם ``preconnect``,
ו-``note_board.html`` יורש ממנו, כך שהגופן נוסף באותה תבנית.

הגופן אומת מול המקור ולא מהסניפט: ``curl`` החזיר HTTP 200, שם המשפחה
הוא ``'Gveret Levin'``, והוא מכסה עברית (``U+0590-05FF``), ``U+20AA``
ולטינית. יש לו משקל 400 בלבד, ולכן מודגש מסונתז — נבדק בצילום ונמצא
קריא כהדגשה.

אימות בדפדפן, שלוש טענות שנמדדו ולא הונחו:

- **הגופן באמת מרונדר** — רוחב אותה מחרוזת עברית עבר מ-136 ל-160 פיקסלים
  עם הדלקת המחלקה. ``getComputedStyle`` לבדו אינו ראיה: הוא מציג את מה
  שהוצהר ב-CSS, לא את מה שרונדר.
- **קובץ הגופן יורד רק כשהוא בשימוש** — אפס בקשות woff2 לפני ההדלקה,
  ושתיים אחריה. זו הטענה על העלות, ולכן היא נמדדה.
- **הקוד נשאר מונוספייס** בשני המצבים.

לא אימתתי שהגיליון מגוגל נטען בפרודקשן, כי Chromium בסביבה הזו חסום
מ-Google Fonts (``net::ERR_CONNECTION_RESET``); לצורך האימות הגשתי את
קובצי ה-woff2 מקומית תחת אותו שם משפחה. ה-CSP מתיר, ו-Heebo כבר נטען
באותה דרך.

שני טסטים חדשים, ושניהם נופלים בלי השינוי: שהמפתח נושא את מזהה הלוח
(מפתח גלובלי היה מדליק את כל הלוחות יחד — כשל שנראה זהה בבדיקה ידנית
על לוח יחיד), ושהגופן אכן נטען.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YULCppaQRPYN1RgeY6NBu
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @amirbiron, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 8 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions

Copy link
Copy Markdown

🧯 Dangerous deletes guard report

Policy: see .cursorrules — dangerous deletions are blocked unless wrapped safely.

Summary:

  • Flagged findings (blocking): 0
    0
  • Excluded matches (not blocking): 15
  • Total matches (all files): 129

Flagged findings (file:line:snippet):
(none)

Excluded matches (by path pattern)
./webapp/static/js/md_preview.bundle.js.map:4:  "sourcesContent": ["// Markdown-it plugin to render GitHub-style task lists; see\n//\n// https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments\n// https://github.com/blog/1825-t … [truncated]
./README.md:842:find . -name "__pycache__" -exec rm -rf {} +
./docs/DOCUMENTATION_GUIDE.md:453:rm -rf _build
./docs/Makefile:24:	rm -rf $(BUILDDIR)
./Dockerfile:42:    rm -rf /var/lib/apt/lists/*
./Dockerfile:121:    rm -rf /var/lib/apt/lists/*
./node_modules/katex/src/fonts/Makefile:139:	rm -rf pfa ff otf ttf woff woff2
./node_modules/katex/package.json:153:    "build": "rimraf dist/ && mkdirp dist && cp README.md dist && rollup -c --failAfterWarnings && webpack && node update-sri.js package dist/README.md",
./node_modules/mermaid/dist/mermaid.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values for tr … [truncated]
./node_modules/mermaid/dist/mermaid.min.js:1524:`,"getStyles"),c1e=RQe});var h1e={};dr(h1e,{diagram:()=>NQe});var NQe,f1e=N(()=>{"use strict";$ge();a1e();l1e();u1e();NQe={parser:Fge,db:n1e,renderer:o1e,styles:c1e}});var m1e,g1e=N(()=>{"use  … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm/chunk-2M32CCKP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence d … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.core/chunk-KS23V3DP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence  … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequen … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs:1:var r={name:"mermaid",version:"11.12.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graph … [truncated]
./node_modules/mermaid/dist/mermaid.min.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values fo … [truncated]

@sourcery-ai

sourcery-ai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Introduces an opt-in, per-board handwriting presentation mode using the Gveret Levin web font, persisted via board-scoped localStorage, applied at the document body level for all note rendering paths, with code blocks explicitly kept monospace and backed by unit tests and user documentation.

Sequence diagram for per-board handwriting mode

sequenceDiagram
    participant User
    participant NoteBoard
    participant LocalStorage
    participant DocumentBody
    participant Browser

    NoteBoard->>LocalStorage: readHandwriting()
    LocalStorage-->>NoteBoard: board-handwriting:BOARD_ID
    NoteBoard->>DocumentBody: applyHandwriting(on)
    DocumentBody->>Browser: toggle board-handwriting
    Browser->>Browser: Apply Gveret Levin to note content
    Browser->>Browser: Keep sticky-md-code and sticky-md-pre monospace

    User->>NoteBoard: change handwritingToggle
    NoteBoard->>LocalStorage: writeHandwriting(on)
    NoteBoard->>DocumentBody: applyHandwriting(on)
    DocumentBody->>Browser: toggle board-handwriting
    Browser->>Browser: Load Gveret Levin when used
Loading

File-Level Changes

Change Details Files
Adds a per-board handwriting-font preference with persisted browser-local state and a settings-panel toggle.
  • Stores the setting under a board-specific board-handwriting: key.
  • Initializes and updates the toggle and applies/removes a class on <body>.
  • Keeps the feature disabled by default and avoids schema or migration changes.
webapp/templates/note_board.html
Loads and applies the Gveret Levin font while preserving readable monospace styling for code content.
  • Adds the Google Fonts stylesheet alongside the existing Heebo import.
  • Applies handwriting styling and a small size adjustment to note titles, content, and tasks.
  • Explicitly preserves monospace fonts and sizing for code and preformatted content.
webapp/templates/base.html
webapp/static/css/sticky-notes.css
Adds regression coverage for board scoping and font availability.
  • Verifies the handwriting preference key includes the board ID and existing preference keys retain their pattern.
  • Verifies board pages include the Gveret Levin font import and Google Fonts preconnect.
tests/test_note_boards_ui.py
Documents the new per-board handwriting setting for users.
  • Updates the sticky-notes user documentation with the new toggle and its behavior.
docs/user/sticky_notes.rst

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 06f78296-ef08-491a-ae95-18e889681e4c

📥 Commits

Reviewing files that changed from the base of the PR and between 6e86ad2 and cd54ad6.

📒 Files selected for processing (6)
  • docs/user/sticky_notes.rst
  • tests/board-handwriting.test.js
  • tests/test_note_boards_ui.py
  • webapp/static/css/sticky-notes.css
  • webapp/templates/base.html
  • webapp/templates/note_board.html
💤 Files with no reviewable changes (1)
  • webapp/templates/base.html

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

נוסף מתג כתב יד לכל לוח פתקים. ההעדפה נשמרת לפי מזהה הלוח, הגופן נטען רק בעת הצורך, וגושי קוד נשארים בגופן מונוספייס. נוספו סגנונות, בדיקות ותיעוד.

Changes

מצב כתב יד

שכבה / קבצים סיכום
טעינת גופן ועיצוב פתקים
webapp/templates/note_board.html, webapp/static/css/sticky-notes.css
הגופן נטען עצלתיים וללא טעינה כפולה. מחלקת board-handwriting מפעילה את עיצוב כתב היד. גושי קוד נשארים בגופן מונוספייס.
העדפה נפרדת לכל לוח
webapp/templates/note_board.html
נוסף המתג handwritingToggle. ההעדפה נקראת ונשמרת ב־localStorage לפי מזהה הלוח, ומתעדכנת בעת שינוי המתג.
בדיקות ותיעוד
tests/board-handwriting.test.js, tests/test_note_boards_ui.py, docs/user/sticky_notes.rst, webapp/templates/base.html
נוספו בדיקות לטעינת הגופן, לבידוד בין לוחות, לטיפול בכשלי אחסון ולרינדור הממשק. נוסף תיעוד למתג כתב היד.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to cd54a

The PR adds an optional per-board handwriting font setting without introducing an actionable merge-blocking risk; it is merge-ready after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  actor משתמש
  participant note_board.html
  participant localStorage
  participant GoogleFonts
  participant document.body
  משתמש->>note_board.html: פתיחת לוח או שינוי המתג
  note_board.html->>localStorage: קריאה או שמירת ההעדפה לפי מזהה הלוח
  note_board.html->>GoogleFonts: טעינת הגופן כאשר ההעדפה פעילה
  note_board.html->>document.body: החלה או הסרה של board-handwriting
Loading

Poem

מתג קטן נדלק בלוח,

וגופן עברי מגיע בנחת.
כל לוח שומר את בחירתו,
והקוד נשאר במונוספייס.
Claude Code כתב את הזרימה,
CodeKeeper forever 💫

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed הכותרת קצרה, ברורה ומתארת את השינוי המרכזי: הוספת גופן כתב-יד ללוח עם הגדרה נפרדת לכל לוח.
Description check ✅ Passed התיאור ברובו מלא ומכסה את המטרה, השינויים, הבדיקות, הסיכונים, התיעוד ותוכנית החזרה לאחור. התיאור המפורט של Claude Code מספק הקשר טכני שימושי. חלק מסעיפי הצ'קליסט, כגון Required Checks וקישורים, נשארו …
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 2 files. (3 skipped: 3 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

התיאור ברובו מלא ומכסה את המטרה, השינויים, הבדיקות, הסיכונים, התיעוד ותוכנית החזרה לאחור. התיאור המפורט של Claude Code מספק הקשר טכני שימושי. חלק מסעיפי הצ'קליסט, כגון Required Checks וקישורים, נשארו ללא סימון או ללא מידע.

Full details: Docstring Coverage

Explanation

Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 2 files. (3 skipped: 3 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/bot-hacked-messages-comsrh

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

⏱️ Performance report

(No performance test durations collected. Mark tests with @pytest.mark.performance.)

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

📖 Documentation Preview

The documentation has been built successfully!

To view locally:

  1. Download the artifacts
  2. Extract the zip file
  3. Open index.html in your browser

Comment thread tests/test_note_boards_ui.py Fixed
@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread tests/test_note_boards_ui.py
Comment thread webapp/static/css/sticky-notes.css
Comment thread webapp/templates/base.html Outdated
Comment thread webapp/templates/base.html Outdated
Comment thread webapp/templates/note_board.html Outdated
Comment thread webapp/static/css/sticky-notes.css
חמישה ממצאי ריוויו על #3279, כולם אומתו בהרצה. אחד מהם התברר עמוק יותר
ממה שדווח, ואזהרת CodeQL אינה בעיית אבטחה.

**היקף — הגופן נטען בכל 48 התבניות.** ה-``<link>`` ישב ב-``base.html``,
שכל התבניות יורשות ממנו, ולכן כל עמוד באפליקציה שילם בקשת CSS
חוסמת-רינדור לגופן שמשמש בלוחות בלבד. ההערה שכתבתי ספרה 736 בתים
והחמיצה את הלוך-ושוב. הועבר ל-``extra_css`` של ``note_board.html``.

**גודל הקוד — הממצא היה תסמין, והמדידה מצאה את השורש.** דווח שהבלוק
מציב ``.92em`` גם ל-``.sticky-md-pre`` שהוא ``.88em``. נכון, אבל הקפיצה
העיקרית הגיעה מ-``font-size: 1.08em`` על המכל: ``em`` הוא יחסי ומתרבה
פנימה, ובלוק קוד קפץ מ-12.32px ל-15.21px.

ואבחון נוסף הפך את התיקון: **ב-``font-size``, ``em`` נפתר מול ההורה ולא
מול הבסיס של האלמנט.** ``1.08em`` לא הגדיל את ``font-size: 14px`` של
המכל ב-8% — הוא **החליף** אותו ב-``16px × 1.08 = 17.28px``, כלומר 23%.
ההגדלה מעולם לא עשתה את מה שהיא נועדה לעשות.

**ההגדלה הוסרה כליל**, ולא תוקנה. הנימוק שלה היה שהגופן "צר ונמוך";
מדידה הראתה שבאותו ``font-size`` הגובה **זהה** והגופן רק צר יותר, כלומר
היא פיצתה על רוחב בכלי שמשנה גובה. בלי ההגדלה, גודל הטקסט וגודל הקוד
זהים בדיוק למצב הרגיל — נמדד — ואין מה לנטרל.

**ההערה על ההחרגה תיארה מנגנון שגוי.** כתבתי שבלעדיה הגופן "היה גובר על
הקוד דרך הירושה, כי הסלקטור ספציפי יותר". הצהרה על האלמנט עצמו תמיד
גוברת על ערך שעובר בירושה, וספציפיות האב אינה נכנסת למשוואה. הוכח
בדפדפן בנטרול הכלל בזמן ריצה. הכלל נשאר כהגנה עתידית, וההערה נכתבה מחדש.

**ההערה על השמירה משקרה.** "רק הדלקה מפורשת נשמרת" בזמן ש-
``writeHandwriting`` שומר גם ``'1'`` וגם ``'0'``. אין באג, אבל ההערה
מבטיחה צורה שאינה קיימת. תוקנה לפי הקוד ולא הפוך.

**כיסוי — הטסטים בדקו HTML ולא התנהגות.** נוסף
``tests/board-handwriting.test.js``: מחלץ את שלוש הפונקציות מהסקריפט
המוטבע בתבנית ומריץ אותן מול ``localStorage`` ו-``document`` מדומים.
חמש בדיקות — המפתח נושא את מזהה הלוח, המחלקה מתווספת ומוסרת, הלוך-ושוב
מלא של ההעדפה, אי-דליפה בין לוחות, ואחסון חסום שאינו מפיל את הלוח. שלוש
מוטציות נבדקו וכל אחת מפילה לפחות טסט אחד.

**CodeQL אינו בעיית אבטחה.** הוא יורה על ``assert 'https://fonts.gstatic.com'
in html`` — טסט על תבנית מרונדרת, לא אימות URL, ושום החלטת אבטחה אינה
נגזרת ממנו. האסרשן עוגן בכל זאת לתגית ה-``preconnect`` המלאה, כי בדיקת
הכלה עוברת גם כשההקשר שגוי.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YULCppaQRPYN1RgeY6NBu

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread webapp/templates/note_board.html Outdated
ה-<link> לגופן היה נטען בכל עמוד לוח, גם למי שלא הדליק את ההגדרה מעולם.
ההחלטה עוברת לסקריפט inline ב-extra_head שקורא את ההעדפה מ-localStorage
בזמן פרסור ה-head: כבוי - אפס בקשות, דלוק - מוקדם בדיוק כמו קישור סטטי.

זה אותו דפוס שבו base.html קובע data-theme לפני טעינת ה-CSS, ומאותה
סיבה: העדפה שהשרת אינו יכול לדעת, שחייבת להיסגר לפני שהעמוד מצויר.

הזרקה בטעינה בלבד אינה מספיקה - הדלקת המתג באמצע הסשן הייתה מחילה את
המחלקה על גופן שמעולם לא נטען, והטקסט היה נופל ל-cursive הגנרי. לכן
ensureHandwritingFont אידמפוטנטית ונקראת גם מ-applyHandwriting.

מפתח ה-localStorage מוגדר פעם אחת בסקריפט הראש ונקרא משם, כדי ששתי
מחרוזות נפרדות לא ייסחפו בשקט.

וההערה שהוסרה טענה שהמעבר מ-base.html חסך הלוך-ושוב - הוא לא היה קיים
מלכתחילה, כי base.html כבר עושה preconnect ומושך את Heebo מאותו מקור.

אימות: 12 טסטי התנהגות חדשים, ארבע מוטציות שכל אחת מפילה את הטסט הנכון,
ומדידה בדפדפן - כבוי 0 בקשות, דלוק בקשה אחת, הדלקה באמצע הסשן טוענת
ומרנדרת (רוחב טקסט 156.5 ← 122.1), וטעינה חוזרת נשארת בקישור אחד.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YULCppaQRPYN1RgeY6NBu
@amirbiron
amirbiron merged commit b3c4439 into main Aug 26, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants