diff --git a/.gitignore b/.gitignore index 6a779fd62..b622ef14a 100644 --- a/.gitignore +++ b/.gitignore @@ -220,3 +220,7 @@ public/pt/help.html public/pt/changelog.html public/pt/help/embed-api.html public/pt/index.html + +# Generated copies of the root legal notices for static hosting. +/public/LICENSE +/public/NOTICE diff --git a/CHANGELOG.md b/CHANGELOG.md index bb49a11bc..35e8247f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,14 +64,31 @@ notes. Entries describe what users experience, not internal refactors. the session on them, so a laptop keeps a recovery point about every 30 seconds while a phone under load backs off instead of competing with the document you are editing. -- **The ONLYOFFICE logo is back in the editor header, and the About pane with - it.** Both had been switched off as interface clutter. They are not: this - editor is a modified version of ONLYOFFICE, and the license it is published - under requires the product logo to stay. The About pane now also says that - this build is not an official ONLYOFFICE product and links to the source it - was built from. Every page of the site carries the same trademark notice in - its footer, and the repository has a NOTICE file with the full terms and the - list of changes made to the vendor build. +- **Neutral presentation with legal attribution retained.** Product logos + and ecosystem promotion are removed. A neutral document icon supplies PWA and browser icons. The editor's About pane stays + available with the upstream copyright and version, a modified-version notice, + license and source links. NOTICE explains the logo decision with reference to + the FSF's interpretation of AGPLv3; it does not claim a court ruling. Offline caching remains available. + +### Fixed + +- Browser icons, theme-color and native controls now follow the effective light + or dark theme, including manual choices opposite to the OS preference. + Universal PWA / touch icons remain stable. The editor's existing theme + follow behavior is covered by light/dark browser tests. + +- Save messages are accepted only from the same-origin editor frame. Embedded + commands are accepted only from the direct parent, with a fixed origin. + Exported document bytes no longer bypass the host API by going straight to + the top-level ancestor. +- Service Worker cache eviction stays within its `waitUntil` lifetime, removes + excess entries in a batch and tolerates storage failures. +- Editor title updates preserve the filename and unsaved marker without + restoring a product-name suffix. Language controls include the visible + language in their accessible names. +- Image-export tests use the current neutral icon. All README translations + distinguish local editing from optional cloud AI, qualify offline resource + availability and state the seven supported site languages. ### Known issues diff --git a/NOTICE b/NOTICE index 4fa8cb7e5..cb3585178 100644 --- a/NOTICE +++ b/NOTICE @@ -6,8 +6,10 @@ This product is a derivative work of ONLYOFFICE. The site (https://edit.chaxus.com/, https://github.com/ranuts/document) is licensed under the GNU Affero General Public License version 3 -- see LICENSE. It embeds the ONLYOFFICE document editors, which are distributed under the same -license with the additional terms permitted by Section 7 of the GNU AGPL. Those -terms are reproduced verbatim below and apply to this work as well. +license with the additional terms permitted by Section 7 of the GNU AGPL. The +received upstream notice is reproduced verbatim below for provenance. Valid +additional terms remain applicable; the logo-retention term is addressed +separately below rather than adopted as a downstream requirement. 1. ONLYOFFICE editors (sdkjs, web-apps) @@ -57,17 +59,41 @@ The notice carried by the upstream source files, reproduced in full: terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode -How this work complies with those terms ---------------------------------------- - -Section 7(b) -- product logo. The ONLYOFFICE logo is shown in the editor -header, and the About pane (product logo, version, Ascensio System SIA -copyright, onlyoffice.com link) is reachable from the left rail. Neither is -suppressed. lib/onlyoffice/guards/chrome.ts hides only the current-user and -co-users widgets, which describe a collaboration session this serverless build -cannot have, and lib/onlyoffice-editor.ts leaves `customization.about` at its -default. test/unit/branding-notice.test.ts and -test/e2e/vendor-branding.spec.ts keep both from being "cleaned up" again. +Neutral presentation and retained legal notices (2026-09-26) +----------------------------------------------------------- + +The interface uses descriptive functional names without project or upstream +product logos, promotional branding, or ecosystem advertising. The editor's +About pane stays reachable, retains the upstream version and publisher, and +adds copyright attribution, a modified-version notice, the warranty disclaimer, +license and source links. Site footers retain the trademark attribution and +non-affiliation notice. Source copyright headers are not removed. + +The upstream notice reproduced above requires retention of the original product +logo. In its statement of 15 April 2026, the Free Software Foundation identified +that requirement as an AGPLv3-incompatible further restriction removable under +Section 7: + https://www.fsf.org/blogs/licensing/agpl-is-not-a-tool-for-taking-freedom-away + +This project relies on that interpretation in omitting product-logo displays. +The quoted upstream notice is kept as a record of the terms received, not an +assertion that logo retention is a valid obligation for downstream recipients. +ONLYOFFICE has asserted a different interpretation; its position is available at: + https://www.onlyoffice.com/license-faq + +The FSF statement is a license interpretation, not a court judgment. This +branding decision does not claim that the dispute is judicially resolved or +that removing logos alone satisfies all copyright, source-distribution or +trademark obligations. Other valid additional terms and third-party licenses +remain unaffected, including the GUI material's CC BY-SA 4.0 license. + +lib/onlyoffice/guards/chrome.ts hides the header and About product marks, +independently of the legal text. Vendor entry HTML has matching styles to avoid +showing those marks during startup, neutral titles and no branded favicon. +lib/onlyoffice-editor.ts keeps About enabled, and +lib/onlyoffice/guards/about-source.ts provides the legal and source links. +test/unit/branding-notice.test.ts and test/e2e/vendor-branding.spec.ts verify +neutral presentation alongside accessible legal attribution. Section 7(e) -- trademarks. ONLYOFFICE and the ONLYOFFICE logo are trademarks of Ascensio System SIA. No rights under trademark law are granted by the @@ -85,7 +111,9 @@ The changes made to it are: well as in the editor frame (it branches on `typeof document` in three places), so conversion happens in a realm whose memory can be handed back. See docs/changelogs/2026-08-20-issue-144-memory-and-delivery.md and - docs/explorations/2026-09-12-x2t-in-a-worker.md. + docs/explorations/2026-09-12-x2t-in-a-worker.md. Modified 2026-09-26 to + send exported file bytes only to the immediate parent; outer ancestors + no longer receive an unsolicited copy. * public/sdkjs/common/wasm/x2t/x2t.worker.js -- added by this project. It loads the file above and drives it; no vendor code is reimplemented in it. * public/sdkjs/common/wasm/x2t/x2t.wasm -- published brotli-compressed only @@ -103,6 +131,11 @@ The changes made to it are: keys returned `undefined` and crashed the tooltip renderer. Values only; no key is removed. * public/web-apps help content trimmed from the shipped tree. + * public/web-apps/apps/{common,*/main}/index*.html -- entry shells with + branded titles now use neutral titles and an empty favicon. An inline + stylesheet suppresses header and About product marks before the + iframe paints. Copyright, publisher and version information remain. + Changed 2026-09-26. * public/fonts/ -- the font catalog's proprietary font files were replaced with redistributable open-source families (see docs/font-licenses.md and docs/changelogs/2026-08-22-font-licensing.md). @@ -112,7 +145,8 @@ The changes made to it are: still resolves, and nine families were added for scripts the remaining set did not cover. -Nothing else in public/sdkjs/ or public/web-apps/ is edited. The behavioural +Other than the changes listed above, public/sdkjs/ and public/web-apps/ +are not edited. The behavioural patches this site needs are applied at runtime from lib/onlyoffice/guards/, which leaves the rest of the vendor files byte-identical to the build they came from. @@ -140,3 +174,6 @@ third-party project https://github.com/cryptpad/onlyoffice-x2t-wasm. Other trademarks named in this repository and on the site (Microsoft Word, Excel, PowerPoint, and others) are the property of their respective owners and are used only to describe the file formats this editor reads and writes. + +The application icon is an independently drawn, neutral document illustration. +It contains no upstream product logo, trademark or project initials. diff --git a/bin/build-app-icons.mjs b/bin/build-app-icons.mjs new file mode 100644 index 000000000..768c28aad --- /dev/null +++ b/bin/build-app-icons.mjs @@ -0,0 +1,22 @@ +/** Rasterize the checked-in SVG sources without adding a runtime dependency. + * npm install --prefix /tmp/document-icon-tools --no-audit --no-fund @resvg/resvg-js@2.6.2 + * node bin/build-app-icons.mjs /tmp/document-icon-tools/package.json + */ +import { createRequire } from 'node:module'; +import { readFileSync, writeFileSync } from 'node:fs'; +import { resolve } from 'node:path'; + +if (!process.argv[2]) throw new Error('Pass the package.json path of an installation of @resvg/resvg-js.'); +const { Resvg } = createRequire(resolve(process.argv[2]))('@resvg/resvg-js'); +for (const [name, sizes] of [ + ['document', [32, 180, 192, 512]], + ['document-maskable', [512]], + ['document-light', [32]], + ['document-dark', [32]], +]) { + const source = new URL(`../public/icons/${name}.svg`, import.meta.url); + for (const size of sizes) { + const png = new Resvg(readFileSync(source), { fitTo: { mode: 'width', value: size } }).render().asPng(); + writeFileSync(new URL(`../public/icons/${name}-${size}.png`, import.meta.url), png); + } +} diff --git a/bin/pages/chrome.mjs b/bin/pages/chrome.mjs index 8b64f5d4e..25bc3976a 100644 --- a/bin/pages/chrome.mjs +++ b/bin/pages/chrome.mjs @@ -48,7 +48,7 @@ export const langMenu = (locale, locales, ui, hrefFor) => // as one control. `role` and the name go here instead, which is also what // ARIA's disclosure pattern asks for: one button, reporting its own state. role: 'button', - 'aria-label': ui.langAria, + 'aria-label': `${ui.langAria}: ${LOCALES[locale].label}`, }) .children( View('span') @@ -113,9 +113,6 @@ export const langMenu = (locale, locales, ui, hrefFor) => ) .serialize(); -export const GH_MARK = - 'M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z'; - export function routeFor(locale, slug) { return `${LOCALES[locale].prefix}/${slug}`; } diff --git a/bin/pages/entities.mjs b/bin/pages/entities.mjs index fb9b4b9db..7640c646a 100644 --- a/bin/pages/entities.mjs +++ b/bin/pages/entities.mjs @@ -19,28 +19,18 @@ import { LOCALES } from './locales.mjs'; * not three. */ export const ID = { - org: `${ORIGIN}/#organization`, site: `${ORIGIN}/#website`, app: `${ORIGIN}/#app`, source: `${ORIGIN}/#source`, }; -/** The publisher and the site, identical on every page so they merge into one. */ +/** The site identity is shared by every page, without promotional publisher branding. */ export const siteEntities = () => [ - { - '@type': 'Organization', - '@id': ID.org, - name: 'ranuts', - url: ORIGIN + '/', - logo: `${ORIGIN}/img/pwa-512.png`, - sameAs: [REPO, 'https://github.com/ranuts', 'https://ran.chaxus.com'], - }, { '@type': 'WebSite', '@id': ID.site, name: SITE_NAME, url: ORIGIN + '/', - publisher: { '@id': ID.org }, // The site is one site in seven languages, which is a fact about the site // and not about whichever page is being read. Each page states its own // language on its WebPage node. @@ -65,7 +55,6 @@ export const appEntity = (extra = {}) => ({ offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' }, // The repository is the editor's other public identity, not the org's. sameAs: [REPO], - publisher: { '@id': ID.org }, isPartOf: { '@id': ID.site }, ...extra, }); diff --git a/bin/pages/render-home.mjs b/bin/pages/render-home.mjs index 7b5c6b95b..564a1d9ab 100644 --- a/bin/pages/render-home.mjs +++ b/bin/pages/render-home.mjs @@ -8,7 +8,7 @@ import { ORIGIN, REPO } from './constants.mjs'; import { ID, appEntity, siteEntities, sourceEntity } from './entities.mjs'; import { DEFAULT_LOCALE, LOCALES } from './locales.mjs'; -import { GH_MARK, langMenu } from './chrome.mjs'; +import { langMenu } from './chrome.mjs'; import { escapeHtml } from './markdown.mjs'; import { UI } from './ui.mjs'; @@ -50,9 +50,6 @@ export function renderHome({ locale, data, locales }) { appEntity({ description: data.description, ...(data.featureList ? { featureList: data.featureList } : {}), - ...(data.ecosystem - ? { isPartOf: [{ '@id': ID.site }, { '@type': 'SoftwareApplication', ...data.ecosystem }] } - : {}), }), // This page: one homepage per language, each pointing at the same app. { @@ -64,7 +61,6 @@ export function renderHome({ locale, data, locales }) { inLanguage: L.lang, isPartOf: { '@id': ID.site }, about: { '@id': ID.app }, - primaryImageOfPage: `${ORIGIN}/img/pwa-512.png`, }, { '@type': 'FAQPage', @@ -129,9 +125,10 @@ export function renderHome({ locale, data, locales }) { + + + - - + diff --git a/history.html b/history.html index baeb7e6cb..e7b02cd1e 100644 --- a/history.html +++ b/history.html @@ -2,9 +2,10 @@ + + + - - @@ -24,6 +25,7 @@ } } catch (e) {} + diff --git a/index.html b/index.html index 365888408..ef0380eb2 100644 --- a/index.html +++ b/index.html @@ -3,9 +3,10 @@ + + + - -
- Close the tab by accident and nothing is lost: your edits are saved into this browser as you work. Saved copies stay for 7 days and are then deleted automatically — or delete them yourself at any time. + Turn on autosave to pick up where you left off. Recovery copies stay for 7 days; save important changes to a file. Saved documents
-
0 bytes uploadedno accountworks offline.docx .xlsx .pptx .csv
+
Open sourceno accountoffline support.docx .xlsx .pptx .csv
@@ -313,7 +282,7 @@

Open Word, Excel & PowerPoint files, -

Everything you type stays on this device.

+

Your document, edited on your device.

@@ -323,10 +292,10 @@

Open Word, Excel & PowerPoint files, You · just now - 0 bytes uploaded — check the network tab. + Make your changes. Save to your own file. -
network · 0 requests · 0 bytes out
+
Local processing · no document uploads
@@ -339,43 +308,43 @@

No Office installed? No problem.

.docx Open DOCX - Word documents with fonts, tables and images intact. + View and edit text, tables and images in Word documents. .xlsx Open XLSX - Formulas, charts and multiple sheets, fully rendered. + Work with cells, formulas, charts and multiple sheets. .pptx Open PPTX - Slides with layouts, themes and media preserved. + View and adjust slide text, images and layouts. .pdf Open PDF - Read, comment and annotate, then save it back. + Read, comment and annotate, then save as PDF. .odt .ods .odp Open OpenDocument - LibreOffice formats — save back as ODT, DOCX or PDF. + Open ODT, ODS and ODP and export to common office formats. .docx → .pdf Convert to PDF - Word, Excel and PowerPoint become PDFs on your device. + Turn Word, Excel and PowerPoint files into PDFs on your device. .xlsx → .csv Convert between formats - Spreadsheets to CSV and back, without uploading a byte. + Convert spreadsheets to CSV and back on your device. @@ -384,13 +353,18 @@

No Office installed? No problem.

Why it's different -

Private by design, not by promise

+

Open code. Your files in your hands.

- 100% client-side -

Files never leave your device

-

Every document is opened, edited and saved locally. There is no server to upload to.

+ Local processing +

Edit without uploading your documents

+

Open, edit and convert local files on your device.

+
+
+ AGPL-3.0 +

Source code you can inspect

+

Read the code on GitHub to see how files are handled, or host your own copy.

No account @@ -399,13 +373,8 @@

Nothing to sign up for

PWA · offline -

Install it, use it on a plane

-

Add it to your home screen and it keeps working with no internet connection.

-
-
- AGPL-3.0 -

Open source & self-hostable

-

Audit exactly what runs, or host your own copy. Powered by OnlyOffice.

+

Keep editing when you disconnect

+

Before your trip, open the files you need online, try editing and exporting, and check they work offline.

@@ -425,13 +394,13 @@

Open a file

02

Edit for real

-

Full formatting, tables, charts and formulas via OnlyOffice.

+

Full formatting, tables, charts and formulas in your browser.

stays on device
03

Save it back

-

Export to the same format. Nothing was ever uploaded.

+

Save into your own file or download a copy.

stays on device
@@ -447,23 +416,23 @@

Questions, answered

Can it save back into my own file, or only download a copy? -

It saves back into your own file. The first save asks you to pick the file; every save after that writes straight into it, with no dialog and no duplicate in your downloads folder. This uses the browser's File System Access API, so it works in Chrome, Edge and other Chromium browsers; Safari and Firefox download a copy instead. Either way the file goes from the browser to your own disk and is never uploaded.

+

In supported browsers such as Chrome and Edge, the first save asks you to choose a file; later saves update that file. Other browsers download a copy. Use File → Download as to export another format. Autosave recovery copies are separate from the files you save.

Are my files uploaded anywhere? -

No. There is no server. Files are opened and saved locally on your device and are never uploaded — you can verify it in the network tab, or read the source.

+

No. When you open local files directly on this site, viewing, editing and conversion happen on your device without uploading your documents.

Which formats can I edit? -

Word (DOCX), Excel (XLSX), PowerPoint (PPTX) and CSV, powered by OnlyOffice running in WebAssembly.

+

Word (DOCX), Excel (XLSX), PowerPoint (PPTX) and CSV. You can also view and annotate PDF files.

What happens if I close the tab or refresh the page? -

Nothing is lost. Your edits are saved into this browser as you work, so reopening the editor offers the document back and a refresh returns to it. The saved copies stay on your device for 7 days and are then deleted automatically; you can also delete any of them yourself at any time. Nothing is uploaded — the copies exist only in this browser.

+

With autosave enabled, you can recover your work in the same browser. Copies stay for 7 days after the last edit or open and can be managed at /history (Saved documents). Browser data can be cleared, so save important changes to a file.

Does it work offline? -

Yes. It is an installable PWA — once loaded it keeps working with no internet, because all editing runs locally in your browser.

+

Yes, with some preparation. Open the files you need online and try editing and exporting, then disconnect to check they work. Clearing browser data may require reconnecting. Files opened from links need a connection.

Do I need an account? @@ -473,21 +442,6 @@

Questions, answered

-
-
- - - Part of the ran ecosystem · all open source - - -
-
-