Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
1016 commits
Select commit Hold shift + click to select a range
43f3766
Firefox listing privacy, in six languages: Google Drive, its identity…
frostdev-ops Oct 31, 2026
115be03
Chaos harness: tiny transfers (staged resumable uploads and ranged do…
frostdev-ops Oct 31, 2026
65bae65
Merge branch 'perf/ultra': Blackboard Ultra opens faster than stock, …
frostdev-ops Oct 31, 2026
45b9f30
Merge branch 'release/4.0.1-notes': version 4.0.1, changelog, store n…
frostdev-ops Oct 31, 2026
4366370
Chaos harness: staged-first-meeting is fixed
frostdev-ops Oct 31, 2026
12482aa
Keep a first meeting's whole link while its push waits for the run's …
frostdev-ops Oct 31, 2026
2e9dff5
Refresh the Safari resource mirror for the staged first meeting fix
frostdev-ops Oct 31, 2026
ff52246
Chaos harness: staged-kill-duplicate, open (a stopped staged first pu…
frostdev-ops Oct 31, 2026
d0de0a3
Merge branch 'drive/last-confirm': large-transfer fixes from the last…
frostdev-ops Oct 31, 2026
eb9bfc1
Changelog: a file over 5 MB stays on this device until large-file syn…
frostdev-ops Oct 31, 2026
dadc298
Changelog: records over 5 MB stay local too
frostdev-ops Oct 31, 2026
5593f72
Check that Sync leaves items past one request on the device, marked, …
frostdev-ops Oct 31, 2026
90f6284
Sync to Google Drive in 4.0.1: items past one request stay on the dev…
frostdev-ops Oct 31, 2026
0da0dfb
Documents marks a document Too large to sync, Settings counts them an…
frostdev-ops Oct 31, 2026
1cb9ce0
Chaos harness: tiny transfers hold 4.0.1 to nothing staged and every …
frostdev-ops Oct 31, 2026
238d6aa
Privacy and features: items over 5 MB don't sync yet and stay on the …
frostdev-ops Oct 31, 2026
7ce3b4f
Refresh the Safari resource mirror for 4.0.1's large-item rule
frostdev-ops Oct 31, 2026
9589ab9
Check that Settings counts what is too large to sync, only if any, an…
frostdev-ops Oct 31, 2026
695b6db
Settings test harness fills a string's placeholders, so the count it …
frostdev-ops Oct 31, 2026
a529959
Settings counts what is too large to sync with the same label, keepin…
frostdev-ops Oct 31, 2026
46f9c26
Check that a too-large mark never outlives the document or record it …
frostdev-ops Oct 31, 2026
d9ed76a
Let go of a too-large mark once its document or record is no longer o…
frostdev-ops Oct 31, 2026
08eea3c
Refresh the Safari resource mirror for the Settings label and the mar…
frostdev-ops Oct 31, 2026
de5586e
Chaos harness: copy-stop, open (a new file recorded, the worker stopp…
frostdev-ops Oct 31, 2026
1113e7a
Send a document's JSON copy after a push that recorded its new file s…
frostdev-ops Oct 31, 2026
1f6a1ed
Refresh the Safari resource mirror for copy-stop
frostdev-ops Oct 31, 2026
e9c6755
Reproduce copy-stop with missing local PDF bytes
frostdev-ops Oct 31, 2026
a222dfb
Finish a pending JSON copy without local export bytes
frostdev-ops Oct 31, 2026
80be166
Refresh Safari resources for pending JSON copy recovery
frostdev-ops Oct 31, 2026
78e0bbd
Ultra instant copies: the Grades fixture takes the live page's shape,…
frostdev-ops Oct 31, 2026
6c1fd92
Ultra instant copies: find Grades' course tiles anywhere under bb-bas…
frostdev-ops Oct 31, 2026
faff44e
Merge branch 'feature/drive': Google Drive in Chrome, Edge, Brave and…
frostdev-ops Oct 31, 2026
fc62c77
Merge branch 'release/4.0.1-drive-limit': the changelog says a file o…
frostdev-ops Oct 31, 2026
6300f5f
Merge branch 'release/4.0.1-docs': name where Google Calendar sync's …
frostdev-ops Oct 31, 2026
cf90051
Grades fixture: the current term's slide is container-term-current be…
frostdev-ops Oct 31, 2026
1b95bd2
Merge branch 'fix/ultra-instant-grades': Grades' instant copy is kept…
frostdev-ops Oct 31, 2026
0a684fc
Test that a standby past STALE is renewed while the page shows, on it…
frostdev-ops Oct 31, 2026
72d4482
Renew the course-tab standby once it passes STALE: the stale one goes…
frostdev-ops Oct 31, 2026
e757d9c
Test that the whole course-tab page script parses
frostdev-ops Oct 31, 2026
644432d
Name the standby's age check apart from the fresh-outline helper, so …
frostdev-ops Oct 31, 2026
4707488
Ultra perf check: name each layout shift's nodes and the LCP element,…
frostdev-ops Oct 31, 2026
b2cc4ac
Test that Glaze's footer waits for its stylesheet before it joins the…
frostdev-ops Oct 31, 2026
3bc079d
Glaze's footer joins the page once the site's sheet is in, so it no l…
frostdev-ops Oct 31, 2026
2af1576
Test that a clock set back cannot disarm the standby's renewal
frostdev-ops Oct 31, 2026
9b6316f
Test that a pass after a quiet spell runs at the next frame, still th…
frostdev-ops Oct 31, 2026
8ca008e
Check a standby's renewal again at its new age when the clock was set…
frostdev-ops Oct 31, 2026
9e9aac1
Merge branch 'perf/standby-renew': the waiting Ultra page is renewed …
frostdev-ops Oct 31, 2026
9b4b6f9
Test that the Courses page panel goes in as Ultra draws the page, fro…
frostdev-ops Oct 31, 2026
282630c
The Courses page panel goes in with the page Ultra has just drawn, fr…
frostdev-ops Oct 31, 2026
8909db8
Test the standby's limit as a setting: tabs.renew, 10 minutes by defa…
frostdev-ops Oct 31, 2026
fe190eb
Make how long the course-tab standby waits a setting: Renew the waiti…
frostdev-ops Oct 31, 2026
f841424
Ultra perf check: stop the heading sampler before the idle window, an…
frostdev-ops Oct 31, 2026
547d563
The early Courses page panel waits for the widgets' start, and moves …
frostdev-ops Oct 31, 2026
2ad2882
Canvas footer test: the footer joins once canvas.css is in
frostdev-ops Oct 31, 2026
6c9b5f6
Test that every choice the standby's limit offers survives normalizat…
frostdev-ops Oct 31, 2026
126a2eb
Hold the standby's limit to the minutes the settings offer, as writer…
frostdev-ops Oct 31, 2026
c8809a7
Merge branch 'perf/standby-renew': Renew the waiting page after, 2 mi…
frostdev-ops Oct 31, 2026
c7bbdb3
Merge branch 'perf/neo-shift': Glaze's footer and widget panel no lon…
frostdev-ops Oct 31, 2026
d7ed8b0
Test Writer Feedback in the draft's language: an answer-language fiel…
frostdev-ops Oct 31, 2026
dd16ac5
Test that Ultra's late Details & Actions keeps the room it took on th…
frostdev-ops Oct 31, 2026
74cd659
Ultra's Details & Actions keeps the room it took on the course last t…
frostdev-ops Oct 31, 2026
60ce52f
Ultra perf check: the outline's right column as live, with Details & …
frostdev-ops Oct 31, 2026
06cc3e8
Test instant copies of a course's Course Content, Announcements and G…
frostdev-ops Oct 31, 2026
9f89d27
Writer Feedback answers in the draft's language: cloud models are tol…
frostdev-ops Oct 31, 2026
ae57f15
Refresh the Safari mirror for Feedback's answer language
frostdev-ops Oct 31, 2026
aad89fb
Boards check: add cards with course data ahead of time off, so a card…
frostdev-ops Oct 31, 2026
11c993b
Reproduce five staged-transfer failures under tiny chaos: a dropped a…
frostdev-ops Oct 31, 2026
1f1e5db
Test that a click on Ultra answers within its frame: the pressed item…
frostdev-ops Oct 31, 2026
c54f310
Open a course's Course Content, Announcements and Gradebook from the …
frostdev-ops Oct 31, 2026
c33c7ea
Details & Actions hold: keep the room against the theme's margin, sav…
frostdev-ops Oct 31, 2026
04f6486
Test that the sidebar starts from its stored record when storage is r…
frostdev-ops Oct 31, 2026
771739c
The sidebar reads its record and Details & Actions' heights one key p…
frostdev-ops Oct 31, 2026
b6dc206
Ultra perf check: the outline sits in a course container beside its r…
frostdev-ops Oct 31, 2026
86d3046
Count an abbreviation's dot before a capitalized sentence, read Frenc…
frostdev-ops Oct 31, 2026
3e0de74
Test that Glaze's crossfade replaying a course tab's click keeps the …
frostdev-ops Oct 31, 2026
3f16356
Test that another page opened meanwhile takes the skeleton away, and …
frostdev-ops Oct 31, 2026
b3c6c1d
Ultra perf check: PERF_WIDTH widens the window, and each stage record…
frostdev-ops Oct 31, 2026
0238b20
Merge branch 'fix/feedback-lang2': Writer Feedback answers in the dra…
frostdev-ops Oct 31, 2026
ad84b34
Start a course page's copy in the standby once it is adopted: load th…
frostdev-ops Oct 31, 2026
c31bb37
Test Feedback's citation witnesses in all six languages: each languag…
frostdev-ops Oct 31, 2026
fe4dc16
Feedback's citation witnesses read all six languages: each language's…
frostdev-ops Oct 31, 2026
2cefb9c
Refresh the Safari mirror for Feedback's citation witnesses
frostdev-ops Oct 31, 2026
acc4940
Answer Ultra's clicks within a frame: Glaze's bar, course tabs, a cou…
frostdev-ops Oct 31, 2026
03359ce
Refresh the Safari copy of the pressed clicks and loading skeleton on…
frostdev-ops Oct 31, 2026
0236cda
Check the course pages' copies in the page and in course tabs: cold, …
frostdev-ops Oct 31, 2026
2af7ced
Test that held Details & Actions stays as tall while Ultra fills it, …
frostdev-ops Oct 31, 2026
cb2c958
Read Feedback's localized citation rules only in a non-English draft …
frostdev-ops Oct 31, 2026
08f8adc
Held Details & Actions keeps its height with min-height, so the brows…
frostdev-ops Oct 31, 2026
eeede26
Feel check: press once the item is still and hit at its centre and Gl…
frostdev-ops Oct 31, 2026
3c7b4da
Merge branch 'fix/feedback-witness': Writer Feedback recognises citat…
frostdev-ops Oct 31, 2026
446b062
Details & Actions hold: settle only on its own growth, watch its bloc…
frostdev-ops Oct 31, 2026
718848b
Test the click skeleton against new-window and download links, a rout…
frostdev-ops Oct 31, 2026
89473f4
Click skeleton: leave new-window and download links alone, look again…
frostdev-ops Oct 31, 2026
b991e15
Test that a course page's copy is never saved for the wrong course or…
frostdev-ops Oct 31, 2026
1b6cfe4
Save a course page's copy only from that course's view and only whole…
frostdev-ops Oct 31, 2026
f3b9cc5
Refresh the Safari copy of the click skeleton's review fixes
frostdev-ops Oct 31, 2026
f9becc1
Write a staged upload's answer as it comes, and hold its document or …
frostdev-ops Oct 31, 2026
783d1e5
Reproduce four more staged failures: a record's and a note merge's st…
frostdev-ops Oct 31, 2026
779325f
Aim staged record uploads at Drive's file as met, keep the lower id's…
frostdev-ops Oct 31, 2026
2e9d553
Merge branch 'perf/neo-shift': Glaze's notes and dock stay put while …
frostdev-ops Oct 31, 2026
499e0bc
Test a worker whose transfer stage won't open: small items sync as ev…
frostdev-ops Oct 31, 2026
5f25c12
Open the transfer stage only when a transfer needs it, and go in one …
frostdev-ops Oct 31, 2026
0670350
Feel check: take the lock's path and Chromium's launch through the sh…
frostdev-ops Oct 31, 2026
a297b64
Sync files over 5 MB to Google Drive: the worker stages transfers, an…
frostdev-ops Oct 31, 2026
a772b66
Refresh the Safari resource mirror for staged large sync
frostdev-ops Oct 31, 2026
a7eb58e
Merge branch 'perf/feel-feedback': a pressed link marks itself at onc…
frostdev-ops Oct 31, 2026
654c908
Merge branch 'perf/feel-copies': Course Content, a course's Announcem…
frostdev-ops Oct 31, 2026
813149d
4.0.1 notes: Open pages instantly covers a course's Content, Announce…
frostdev-ops Oct 31, 2026
81cd510
Test a staged record update against a later change back to its value,…
frostdev-ops Oct 31, 2026
01f6928
Aim a staged record update at the file's revision as met, and let go …
frostdev-ops Oct 31, 2026
92bf991
Refresh the Safari resource mirror for the record aim and stage-less …
frostdev-ops Oct 31, 2026
e3e6998
Reproduce an own unsent .docx left visible beside the file another de…
frostdev-ops Oct 31, 2026
2245b3a
Put away this device's own unsent file when it follows the file anoth…
frostdev-ops Oct 31, 2026
413f39e
Refresh the Safari resource mirror for the losing file put away
frostdev-ops Oct 31, 2026
15d4f1b
Reproduce an outside edit taken as Glaze's from a re-asked upload ans…
frostdev-ops Oct 31, 2026
1c7f95e
Record a re-asked upload answer's revision only for Glaze's own bytes…
frostdev-ops Oct 31, 2026
b965443
Refresh the Safari resource mirror for the re-asked answer and folder…
frostdev-ops Oct 31, 2026
a61c5bc
Reproduce a staged read left unused after a stopped take, and an owed…
frostdev-ops Oct 31, 2026
3fffee3
Keep a finished transfer until its owner's meeting has run, and let o…
frostdev-ops Oct 31, 2026
005f245
Refresh the Safari resource mirror for owed transfers
frostdev-ops Oct 31, 2026
76fc9a9
Feedback tests: a verified decision keeps its grade when no explanati…
frostdev-ops Oct 31, 2026
ddb5478
Feedback grading: a verified decision keeps its grade with Glaze's ru…
frostdev-ops Oct 31, 2026
ae52756
Feedback fallback (review): a cloud row's rating needs draft evidence…
frostdev-ops Oct 31, 2026
8c97e35
Reproduce a staged new record file sent beside the one another device…
frostdev-ops Oct 31, 2026
103d8c1
Look for another device's file before a staged new one goes, and keep…
frostdev-ops Oct 31, 2026
5271bf9
Refresh the Safari resource mirror for the staged create check
frostdev-ops Oct 31, 2026
c626585
Refresh the Safari resource mirror for the Feedback grade fallback
frostdev-ops Oct 31, 2026
9c869e1
Feedback tests: a contradiction with no re-check left is an explanati…
frostdev-ops Oct 31, 2026
4dcb6ec
Feedback grading: a contradiction with no re-check left reports the e…
frostdev-ops Oct 31, 2026
6698ecf
Refresh the Safari resource mirror for the contradiction fallback
frostdev-ops Oct 31, 2026
988b639
Merge branch 'fix/feedback-grade': Writer Feedback keeps a verified g…
frostdev-ops Oct 31, 2026
306f971
4.0.1 notes: Writer Feedback shows the rubric rating it checked inste…
frostdev-ops Oct 31, 2026
15d18c6
Parse the kept first-paint bar with DOMParser: Firefox's add-on linte…
frostdev-ops Oct 31, 2026
5a07b12
Test owed meetings: a denied replay, a small edit after a commit, no …
frostdev-ops Oct 31, 2026
db246fb
Keep an owed meeting through small pushes, restaging, a stage that wo…
frostdev-ops Oct 31, 2026
51ee7ee
Refresh the Safari resource mirror for owed meetings
frostdev-ops Oct 31, 2026
11e2a04
Merge commit '15d18c60' into drive/large-sync
frostdev-ops Oct 31, 2026
0ab1dbc
Test that Details & Actions added empty on a route and filled before …
frostdev-ops Oct 31, 2026
2971873
Hold Ultra's Details & Actions from when Ultra adds it, before the pa…
frostdev-ops Oct 31, 2026
5e40ad3
Hold Details & Actions in the site's pass that adds it, and check on …
frostdev-ops Oct 31, 2026
1dec953
Refresh the Safari resource mirror for the early Details & Actions hold
frostdev-ops Oct 31, 2026
6b268ac
Ultra feel check: a click's first change counts once painted, within …
frostdev-ops Oct 31, 2026
4e6ede0
Ultra: a main-menu or course-tab click is Ultra's at once, never held…
frostdev-ops Oct 31, 2026
23ea8da
Sign in to Google Calendar and Drive in Safari through the Glaze app,…
frostdev-ops Oct 31, 2026
b39f5d2
Test initial title paint timing
frostdev-ops Oct 31, 2026
24b3308
Preserve navigation origin for initial title paint
frostdev-ops Oct 31, 2026
c015955
Test outgoing empty Details ownership
frostdev-ops Oct 31, 2026
1b53189
Keep outgoing Details bound to its course
frostdev-ops Oct 31, 2026
7d6bc55
Test Details growth during sidebar adoption
frostdev-ops Oct 31, 2026
6fc8c8f
Reject Details growth during sidebar adoption
frostdev-ops Oct 31, 2026
5421ff9
Test missing widget dock in still-aside checks
frostdev-ops Oct 31, 2026
c79ddbc
Require the widget dock in still-aside checks
frostdev-ops Oct 31, 2026
6f8cc44
Test movement across hidden sidebar frames
frostdev-ops Oct 31, 2026
77aafa7
Track sidebar movement across hidden frames
frostdev-ops Oct 31, 2026
c515266
Test: one mutation batch on Ultra gates once, with every native node …
frostdev-ops Oct 31, 2026
bcae9df
Ultra: one gate per mutation batch, so a course open no longer re-pla…
frostdev-ops Oct 31, 2026
1289c70
Merge branch 'fix/details-hold-early': Ultra's Details & Actions is h…
frostdev-ops Oct 31, 2026
4d32816
Test that the sidebar takes a course outline's column as soon as Ultr…
frostdev-ops Oct 31, 2026
c93c9f3
Ultra feel check: PERF_DEVICE=neo and FEEL_MEASURE medians with long …
frostdev-ops Oct 31, 2026
923a976
Refresh the Safari resource mirror for click feel
frostdev-ops Oct 31, 2026
9596743
Take a course outline's column as soon as Ultra draws it, so Glaze's …
frostdev-ops Oct 31, 2026
adece8a
Let the Calendar worker tests set Safari's sign-in switch either way
frostdev-ops Oct 31, 2026
1983935
Test that a course outline's column Ultra has just drawn isn't shown …
frostdev-ops Oct 31, 2026
c344bec
Show a course outline's column only once the sidebar has taken it; th…
frostdev-ops Oct 31, 2026
eca02f4
Tests follow one gate per batch and the page-change section's removal
frostdev-ops Oct 31, 2026
4d0444a
Test that the dock in a newly taken course outline column waits for C…
frostdev-ops Oct 31, 2026
6325b72
Keep the dock in a newly taken course outline column out of view unti…
frostdev-ops Oct 31, 2026
c256c94
Test click measurements through transition paint holds
frostdev-ops Oct 31, 2026
686946d
Wait for transition paint before ending click measurements
frostdev-ops Oct 31, 2026
6b5c87e
Test invalid click measurement repetitions
frostdev-ops Oct 31, 2026
6e57f3a
Validate click measurement repetitions
frostdev-ops Oct 31, 2026
8cd06aa
Test profiler source line attribution
frostdev-ops Oct 31, 2026
76c72fb
Preserve trace source line numbers
frostdev-ops Oct 31, 2026
5bf5283
Clarify when a transition releases painting
frostdev-ops Oct 31, 2026
f4484c1
Recover a Safari grant the worker lost the reply to, confirm native D…
frostdev-ops Oct 31, 2026
6a751d0
Merge branch 'perf/click-feel': a click paints its first change at on…
frostdev-ops Oct 31, 2026
9af262e
Hold the dock back for Course notes only in the expanded outline colu…
frostdev-ops Oct 31, 2026
d72384f
Merge commit '6a751d05' into fix/details-hold-early
frostdev-ops Oct 31, 2026
55d8676
Merge branch 'feature/safari-google': Google Drive and Calendar sync …
frostdev-ops Oct 31, 2026
1136f41
Course notes wait: end it when Notes is turned off or the column chan…
frostdev-ops Oct 31, 2026
53627cc
From Google Drive in Safari: the picker page in a tab, back to Glaze'…
frostdev-ops Oct 31, 2026
6822cb4
Merge branch 'fix/details-hold-early': the sidebar takes a course out…
frostdev-ops Oct 31, 2026
12b4845
Safari's Picker: bind each wait to its pick, serialize its returns, o…
frostdev-ops Oct 31, 2026
2795d47
Give the Drive status test's worker slice the SAFARI flag the Picker'…
frostdev-ops Oct 31, 2026
98830f4
Test This page from the takeover, Course notes and the dock held back…
frostdev-ops Oct 31, 2026
3ae8112
Sidebar layout reads everything it measures before writing <html>, me…
frostdev-ops Oct 31, 2026
53381ed
Still-aside mode holds a course's first visit to it too
frostdev-ops Oct 31, 2026
2da6aa9
Merge branch 'feature/safari-picker': From Google Drive in Safari, th…
frostdev-ops Oct 31, 2026
684d0a8
Test that the sidebar's header keeps one row when Jump to widgets app…
frostdev-ops Oct 31, 2026
0fe0744
The sidebar's header keeps one row: Jump to widgets showing later tak…
frostdev-ops Oct 31, 2026
c8f3cc7
Sidebar layout measures with the computed style it already read, one …
frostdev-ops Oct 31, 2026
45fc126
Download all goes in after a folder's eye, so the eye isn't moved bac…
frostdev-ops Oct 31, 2026
78e2e05
Ultra's sheets give Chrome a class, id or tag to file each rule under…
frostdev-ops Oct 31, 2026
075fc90
Sidebar layout: measure again after offsets that move what follows, k…
frostdev-ops Oct 31, 2026
d68332e
Sidebar layout: new offsets alone don't measure again; a column pinne…
frostdev-ops Oct 31, 2026
7fe15aa
A list opened inside another keeps only the outer list's specificity …
frostdev-ops Oct 31, 2026
2e27934
Sidebar layout reads --gz-sb-bottom with its other measurements, befo…
frostdev-ops Oct 31, 2026
6bb5285
Sidebar Ultra check waits for the column to be on top after the side …
frostdev-ops Oct 31, 2026
9f799ef
Test that only a site with no saved Details height holds Course notes…
frostdev-ops Oct 31, 2026
ca6dfbe
Test solid panel selector specificity
frostdev-ops Oct 31, 2026
29f81f8
Hold Course notes and the dock back only on a site with no saved Deta…
frostdev-ops Oct 31, 2026
b7fa160
Preserve solid panel selector specificity
frostdev-ops Oct 31, 2026
778a540
Test CSS ratchet delimiter and escape handling
frostdev-ops Oct 31, 2026
892a233
Respect CSS strings and escapes in the selector ratchet
frostdev-ops Oct 31, 2026
8973a0f
Test parity mode coverage and pixel instability
frostdev-ops Oct 31, 2026
4dde6be
Compare styles and pixels in every parity mode
frostdev-ops Oct 31, 2026
b90fcde
Report every unstable parity screenshot
frostdev-ops Oct 31, 2026
b2d3b87
Sidebar: closing the drawer inside a layout doesn't lay out again, a …
frostdev-ops Oct 31, 2026
6c59973
Merge branch 'fix/details-hold-early': This page from the takeover, a…
frostdev-ops Oct 31, 2026
a13d13b
The solid-background rule keeps its ::before arm as written (it match…
frostdev-ops Oct 31, 2026
30c31e9
Merge branch 'perf/css-cost': Ultra's course open restyles less (one …
frostdev-ops Oct 31, 2026
1166f95
Sidebar: one selector per entry for the first-visit hide and the head…
frostdev-ops Oct 31, 2026
dc0f241
Solid background test: the announcement header's ::before is named wh…
frostdev-ops Oct 31, 2026
4b1e50a
Solid background: the announcement header's ::before gets its own rul…
frostdev-ops Oct 31, 2026
224571b
4.0.1 notes: Sync to Google Drive carries large files in pieces; a cl…
frostdev-ops Oct 31, 2026
a7e4e1a
Perf check still-aside mode: motion on as the owner has it, the cours…
frostdev-ops Nov 1, 2026
4f532d0
Test that Content fades in without rising while the sidebar is a colu…
frostdev-ops Nov 1, 2026
2f9f65f
While the sidebar is a column, a course opens with a fade and no rise…
frostdev-ops Nov 1, 2026
0e3d2e2
Perf check: Details & Actions stays ng-hide (display: none) while Ult…
frostdev-ops Nov 1, 2026
9dd3b65
Test that a held Details & Actions Angular keeps ng-hide keeps its ro…
frostdev-ops Nov 1, 2026
0978f1d
A held Details & Actions that Angular keeps ng-hide keeps its room as…
frostdev-ops Nov 1, 2026
1eb7b9c
Find Safari's app group container by writing to it, not by access(2),…
frostdev-ops Nov 1, 2026
151c7aa
ng-hide Details: expiring timers don't release or reveal while Angula…
frostdev-ops Nov 1, 2026
c0d77f4
Probe the group container with the same atomic, non-empty write the s…
frostdev-ops Nov 1, 2026
b4d4076
Switch on Google Drive and Calendar sync in Safari, through the Glaze…
frostdev-ops Oct 31, 2026
0f8d3c8
Merge branch 'fix/details-hold-early': the outline column stands at i…
frostdev-ops Nov 1, 2026
351b7b1
Merge branch 'fix/safari-group-container': Safari's handler tests its…
frostdev-ops Nov 1, 2026
edb5150
Merge branch 'feature/safari-google-on': Google Drive and Calendar sy…
frostdev-ops Nov 1, 2026
c307ae5
4.0.1 notes: Google Drive and Calendar sync in Safari too
frostdev-ops Nov 1, 2026
c309de3
Test a calm cold load on Ultra: one skeleton or the copy from the fir…
frostdev-ops Nov 1, 2026
3da9e16
A cold load on Ultra shows one calm state: Ultra's boot screen hidden…
frostdev-ops Nov 1, 2026
f35fe26
Cold loads: the early sheets also block the first paint on a school's…
frostdev-ops Nov 1, 2026
fe8bc4f
Safari mirror for the calm cold load
frostdev-ops Nov 1, 2026
a97e3d3
Cold-load check: Chromium and the lock through the shared helper
frostdev-ops Nov 1, 2026
60356af
Keep the cold-load skeleton when an instant copy is disabled
frostdev-ops Nov 1, 2026
6d1989d
Finish course container entrances when an instant copy clears
frostdev-ops Nov 1, 2026
85add2f
Leave native boot visibility alone when loading feedback is off
frostdev-ops Nov 1, 2026
7606518
Wait for the requested course before revealing a cold load
frostdev-ops Nov 1, 2026
c9f8986
Handle full routed views during cold loading
frostdev-ops Nov 1, 2026
3ca724d
Cold-load sheet comment rewrapped
frostdev-ops Nov 1, 2026
846a990
Merge branch 'fix/calm-cold-load': a cold load shows one loading stat…
frostdev-ops Nov 1, 2026
b3cd5b5
Documents check and page test: Close in a document shows the list
frostdev-ops Nov 1, 2026
07da1d7
Close in a document shows Documents' list, stepping back over the doc…
frostdev-ops Nov 1, 2026
b23d377
Documents check reads the tab's history by its length and one Back
frostdev-ops Nov 1, 2026
4ed6394
Test repeated document Close before history traversal
frostdev-ops Nov 1, 2026
d50392c
Keep repeated document Close to one history traversal
frostdev-ops Nov 1, 2026
257f2dd
Test document Close waiting for Word saves
frostdev-ops Nov 1, 2026
b5584c5
Wait for Word saves before leaving Documents
frostdev-ops Nov 1, 2026
7def78b
Merge branch 'fix/docs-close': Close in a document goes back to the D…
frostdev-ops Nov 1, 2026
010b64f
4.0.1 notes: pages load behind one loading layout instead of Blackboa…
frostdev-ops Nov 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .github/pins/chromium.pins
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# The Chromium that .github/pins/playwright.pins's playwright-core installs, checked by tools/dev/ci-chromium.js before it runs. Each hash
# matches Google's Chrome for Testing zip of that version, unpacked.
chromium-1243 153.0.8010.12 linux-x64 de81033ef46a2ebc03cd1865fccace6f7955ba3b8b45adb4e485ecf51ebdceac
chromium-1243 153.0.8010.12 darwin-arm64 37eeed7899f5e4b2524e05af529c8ca9ca4dce83ffee579b85b92ec04dc797a4
chromium-1243 153.0.8010.12 win32-x64 bdb90fb4515be221f8b2b9abe8fb3f9f8cd3af6fd06873872e4ccc921ddc28db
File renamed without changes.
4 changes: 4 additions & 0 deletions .github/pins/playwright.pins
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# The Playwright the browser gate installs (.github/workflows/browser.yml), checked by tools/vendor/npm-integrity.js. To upgrade,
# change PLAYWRIGHT there, copy each package's `npm view <name>@<version> dist.integrity` here, and repin .github/pins/chromium.pins and .github/pins/ffmpeg.pins.
playwright@1.63.0 sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==
playwright-core@1.63.0 sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==
10 changes: 5 additions & 5 deletions .github/workflows/browser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ jobs:
with:
node-version: 26

# Install scripts off; every package checked against ci/playwright.pins, and Chromium/FFmpeg against ci/*.pins,
# Install scripts off; every package checked against .github/pins/playwright.pins, and Chromium/FFmpeg against .github/pins/*.pins,
# before either runs.
- name: Install the pinned Playwright
run: |
echo "NODE_PATH=$RUNNER_TEMP/playwright/node_modules" >> "$GITHUB_ENV"
echo "PLAYWRIGHT_BROWSERS_PATH=$RUNNER_TEMP/ms-playwright" >> "$GITHUB_ENV"
npm install --prefix "$RUNNER_TEMP/playwright" --no-save --no-package-lock --ignore-scripts --no-audit --no-fund --registry https://registry.npmjs.org/ "playwright@$PLAYWRIGHT"
node scripts/npm-integrity.js "$RUNNER_TEMP/playwright/node_modules/.package-lock.json" ci/playwright.pins playwright playwright-core
node tools/vendor/npm-integrity.js "$RUNNER_TEMP/playwright/node_modules/.package-lock.json" .github/pins/playwright.pins playwright playwright-core
- name: Install its Chromium
run: |
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=1 "$RUNNER_TEMP/playwright/node_modules/.bin/playwright" install --with-deps --no-shell chromium
node scripts/ci-chromium.js
node tools/dev/ci-chromium.js

- name: Settings, popup, sites and pointer checks
run: nice -n 10 node scripts/ci-browser-checks.js "$RUNNER_TEMP/browser-evidence"
- name: Settings, popup, sites, pointer and agent link checks
run: nice -n 10 node tools/dev/ci-browser-checks.js "$RUNNER_TEMP/browser-evidence"

- name: Keep the logs and screenshots
if: failure()
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ jobs:

# A tag that names another version would attach a zip of the manifest's version to the wrong release.
- name: Check the tag names the manifest's version
run: test "v$(node -p 'require("./manifest.json").version')" = "${GITHUB_REF_NAME%%-rc*}"
run: test "v$(node -p 'require("./extension/manifest.json").version')" = "${GITHUB_REF_NAME%%-rc*}"

- name: Validate the tagged source
run: node --test

- name: Build the Chrome zip
run: ./package.sh
run: tools/build/package.sh

- name: Hand the zip to the release job
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
# The worker's code takes crypto from the browser, and Node 18 has no global one: the flag gives the test files one.
# The helper processes they start run without it.
- name: MCP and agent tests
run: node ${{ matrix.node == 18 && '--experimental-global-webcrypto' || '' }} --test test/mcp-*.test.js test/agent-*.test.js
run: node ${{ matrix.node == 18 && '--experimental-global-webcrypto' || '' }} --test test/agents/mcp-*.test.js test/*/agent-*.test.js

# As browser.yml installs it: scripts off, every package and both builds checked against their pins before any of
# it runs. No --with-deps: on Windows it only adds a media pack.
Expand All @@ -63,15 +63,15 @@ jobs:
echo "NODE_PATH=$RUNNER_TEMP/playwright/node_modules" >> "$GITHUB_ENV"
echo "PLAYWRIGHT_BROWSERS_PATH=$RUNNER_TEMP/ms-playwright" >> "$GITHUB_ENV"
npm install --prefix "$RUNNER_TEMP/playwright" --no-save --no-package-lock --ignore-scripts --no-audit --no-fund --registry https://registry.npmjs.org/ "playwright@$PLAYWRIGHT"
node scripts/npm-integrity.js "$RUNNER_TEMP/playwright/node_modules/.package-lock.json" ci/playwright.pins playwright playwright-core
node tools/vendor/npm-integrity.js "$RUNNER_TEMP/playwright/node_modules/.package-lock.json" .github/pins/playwright.pins playwright playwright-core
- name: Install its Chromium
if: matrix.node == 26
run: |
node "$RUNNER_TEMP/playwright/node_modules/playwright/cli.js" install --no-shell chromium
node scripts/ci-chromium.js
node tools/dev/ci-chromium.js
- name: A real native-messaging host in Chromium
if: matrix.node == 26
run: node scripts/mcp-windows-check.js "$RUNNER_TEMP/mcp-windows-evidence"
run: node checks/agents/mcp-windows-check.js "$RUNNER_TEMP/mcp-windows-evidence"
- name: Keep the check's evidence
if: failure() && matrix.node == 26
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ dist/
release/
safari/**/xcuserdata/
*.xcuserstate
assets/ads/
extension/assets/ads/

# Local secrets (e.g. cloudflare-r2.env for the share relay)
*.env
Expand Down
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,36 @@ All notable changes to Glaze are documented here. The format follows

## [Unreleased]

## [4.0.1] — 2026-10-31

### Added

- Chrome and Safari: **Google Calendar sync** (Settings → Sharing) keeps a calendar named Glaze in step with Export calendar (.ics), touching nothing else. Off until you connect.
- **Google Drive** in Settings → Writer → Papers (Chrome, Edge, Brave, Firefox and Safari; off until you connect). **From Google Drive** opens a file in Documents or attaches it to a Blackboard submission; **Save to Google Drive** saves a document's file or a paper as a Google Doc, never overwriting one edited outside Glaze; **Sync to Google Drive** keeps your documents and what Back up… covers in a Glaze folder, across devices; large files sync in pieces; only a document over 64 MB or a record over 32 MB stays on this device, marked **Too large to sync**. Glaze reaches only the files it made or you pick. Disconnect is per device.
- Blackboard, in Settings → Course tabs: **Open course tabs ahead of time** (a tab opens from a page already loaded), **Keep Course Content ready** (back from an item is instant, at the same place) and **Load course data ahead of time**.
- Blackboard: **Open pages instantly** (Settings → Course pages → Blackboard Dashboard) shows your last view of Grades, Courses, Activity and a course's Content, Announcements and Gradebook while Blackboard loads. **Show pages loading at once** answers each click.
- PDFs: Highlight, Pen, Text, Image, Shapes and signatures, and a pages panel to move, turn, delete, add or import pages.
- Blackboard: **Attach from Documents** adds your documents to a submission. Workbooks from .xlsm export and submit as .xlsm.
- Canvas: **Open in Glaze** on PDF, slide and spreadsheet files (Settings → Documents). Slides: **Print with notes…**
- Documents cards show spreadsheet charts, 3-D pies and columns included.

### Changed

- Blackboard: a click shows the next page at once, a page loads behind one loading layout in your Look (no grey screen or stacked spinners), and Glaze's bar, footer, notes and panels never push the page. To Do, grades and the sidebar appear from saved data once Blackboard confirms it's you.
- A PDF keeps one copy, its latest marked-up version.
- Saved PDF and slide previews offer **Open in Documents**; an unsaved spreadsheet stays read-only.
- Imports show progress at once and store large files faster.

### Fixed

- Writer: Feedback answers in your draft's language, its citation checks work in all six languages, and a failed comment shows the rubric rating instead of withholding the grade.
- Documents: Close in a document goes back to your documents.
- Writer: a tab opened while Glaze saves settings gets Glaze; a viewer that fails goes back to Blackboard's editor.
- Canvas's document viewer: pen marks stay put on zoom, and Undo takes back Clear page.
- Agents: only Glaze's background can change an app's pairing or the name in its approval window.
- Firefox: a site whose access you took back is no longer retried.
- The announcement pop-up has Close in its footer; a note with very many line breaks opens.

## [4.0.0] — 2026-10-30

### Added
Expand Down
16 changes: 10 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Development loop

1. `chrome://extensions` → **Developer mode** → **Load unpacked** → pick this folder.
1. `chrome://extensions` → **Developer mode** → **Load unpacked** → pick the `extension` folder.
2. Edit a file.
3. Hit the reload arrow on the Glaze card, then reload your Blackboard Ultra or Canvas tab.

Expand All @@ -11,15 +11,19 @@ extension reload. Run `node --test` before sending a change.

## Layout

- `content.js` — runs on Ultra, Canvas and Moodle pages: adds the stylesheets, applies settings, the DOM sweep, tooltips and the extras. What only one site does is in its part, `content-ultra.js` or `content-canvas.js`, listed before `content.js` for that site (Moodle has none); each site's first script has its own budget (`test/perf-budget.test.js`).
- `theme.css` (palette and page polish), `motion.css` (motion levels), `extras.css` (backgrounds and extras).
- `defaults.js` — the settings schema, defaults, presets and `GZ_SANITIZE`. `lib/` — pure helpers with tests in `test/`, plus `scene.js` (the animated backgrounds) and the vendored `three.js`.
- `popup.*`, `options.*`, `ui.*` — the popup, the editor and what they share. `preview.html` is the editor's mock Ultra page.
The whole tree, with diagrams: [docs/layout.md](docs/layout.md).

- `extension/` — the extension as the stores ship it; the paths below are inside it. `checks/` holds the browser checks and `test/` the unit tests, each by feature area; `tools/` the build, release, vendor, fidelity and dev scripts.
- `content/content.js` — runs on Ultra, Canvas and Moodle pages: adds the stylesheets, applies settings, the DOM sweep, tooltips and the extras. What only one site does is in its part, `content/content-ultra.js` or `content/content-canvas.js`, listed before `content.js` for that site (Moodle has none); each site's first script has its own budget (`test/platform/perf-budget.test.js`).
- `content/theme.css` (palette and page polish), `content/motion.css` (motion levels), `content/extras.css` (backgrounds and extras).
- `content/defaults.js` — the settings schema, defaults, presets and `GZ_SANITIZE`.
- One folder per feature area: `looks/`, `navigation/`, `courses/`, `planner/`, `writer/`, `documents/`, `ai/`, `agents/`, `sharing/`, `mods/`, `pet/`, `settings/`, with `core/` shared by all and `background/` the worker. An area's helpers sit at its top, with tests in `test/<area>/`; the code that touches the LMS page is in `<area>/page/`. `looks/scene.js` draws the animated backgrounds; third-party code (three.js, pdf.js, ProseMirror …) is in `vendor/`.
- `popup.html`, `options.html` (their scripts in `settings/`) and `core/ui.*` — the popup, the editor and what they share. `preview.html` is the editor's mock Ultra page.
- [Development](docs/development.md) — architecture, supported build paths, feature gates and release requirements.

## Conventions

- No build step, no dependencies, no bundler. Vanilla JS, plain CSS, files loaded directly. The exceptions are `lib/three.js`, a checked-in, tree-shaken, readable three.js (`scripts/vendor-three.sh` rebuilds it), lottie-web's official readable light canvas player in `lib/lottie/` (`scripts/vendor-lottie.sh` fetches it by a pinned hash), pdf.js in `lib/pdfjs/` and Tesseract in `lib/tesseract/` (`scripts/vendor-pdfjs.sh`, `scripts/vendor-tesseract.sh`), ProseMirror as one readable bundle in `lib/pm.js` and `lib/pm.css` (`scripts/vendor-prosemirror.sh`), harper.js in `lib/harper/` (`scripts/vendor-harper.sh`), and Writer's paper fonts in `lib/fonts/` (`scripts/vendor-paper-fonts.sh`); only an upgrade needs any of them.
- No build step, no dependencies, no bundler. Vanilla JS, plain CSS, files loaded directly. The exceptions are `vendor/three.js`, a checked-in, tree-shaken, readable three.js (`tools/vendor/vendor-three.sh` rebuilds it), lottie-web's official readable light canvas player in `vendor/lottie/` (`tools/vendor/vendor-lottie.sh` fetches it by a pinned hash), pdf.js in `vendor/pdfjs/` and Tesseract in `vendor/tesseract/` (`tools/vendor/vendor-pdfjs.sh`, `tools/vendor/vendor-tesseract.sh`), ProseMirror as one readable bundle in `vendor/pm.js` and `vendor/pm.css` (`tools/vendor/vendor-prosemirror.sh`), harper.js in `vendor/harper/` (`tools/vendor/vendor-harper.sh`), and Writer's paper fonts in `vendor/fonts/` (`tools/vendor/vendor-paper-fonts.sh`); only an upgrade needs any of them.
- Keep diffs small and focused. One change per PR.
- Defaults live in exactly one place: `defaults.js`. Don't duplicate a colour or a toggle elsewhere.
- Every setting reaches the page as a `--gz-*` variable or an `html[data-gz-*]` attribute. CSS matches on those; it never waits on JavaScript.
Expand Down
Loading
Loading