Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions sdkjs-plugins/content/curly/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Change Log

## 1.0.0

* Initial release.
2 changes: 2 additions & 0 deletions sdkjs-plugins/content/curly/bundle/addin.css

Large diffs are not rendered by default.

778 changes: 778 additions & 0 deletions sdkjs-plugins/content/curly/bundle/addin.js

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions sdkjs-plugins/content/curly/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"name": "Curly",
"guid": "asc.{CE3A8C7D-2C4F-4E1A-9A5A-C8B1A7D0F2E3}",
"offered": "Foundasys",
"version": "1.0.0",
"baseUrl": "",
"variations": [
{
"description": "Turn any document into a reusable template: mark the parts that change with {tags} and fill them from the task pane — a finished, ready-to-send copy in seconds.",
"descriptionLocale": {
"nl": "Maak van elk document een herbruikbare sjabloon: markeer de variabele delen met {tags} en vul ze in vanuit het taakvenster — binnen enkele seconden een verzendklaar document.",
"de": "Machen Sie aus jedem Dokument eine wiederverwendbare Vorlage: Markieren Sie veränderliche Stellen mit {Tags} und füllen Sie sie im Seitenbereich aus — in Sekunden ein versandfertiges Dokument.",
"fr": "Transformez n'importe quel document en modèle réutilisable : marquez les parties variables avec des {balises} et remplissez-les depuis le panneau latéral — un document prêt à envoyer en quelques secondes.",
"es": "Convierta cualquier documento en una plantilla reutilizable: marque las partes variables con {etiquetas} y rellénelas desde el panel lateral — un documento listo para enviar en segundos.",
"pt-BR": "Transforme qualquer documento em um modelo reutilizável: marque as partes variáveis com {tags} e preencha-as no painel lateral — um documento pronto para envio em segundos.",
"it": "Trasforma qualsiasi documento in un modello riutilizzabile: contrassegna le parti variabili con {tag} e compilale dal pannello laterale — un documento pronto da inviare in pochi secondi."
},
"url": "index.html",
"icons": ["resources/light/icon.png", "resources/light/icon@2x.png"],
"icons2": [
{
"style": "light",
"100%": { "normal": "resources/light/icon.png" },
"125%": { "normal": "resources/light/icon@1.25x.png" },
"150%": { "normal": "resources/light/icon@1.5x.png" },
"175%": { "normal": "resources/light/icon@1.75x.png" },
"200%": { "normal": "resources/light/icon@2x.png" }
},
{
"style": "dark",
"100%": { "normal": "resources/dark/icon.png" },
"125%": { "normal": "resources/dark/icon@1.25x.png" },
"150%": { "normal": "resources/dark/icon@1.5x.png" },
"175%": { "normal": "resources/dark/icon@1.75x.png" },
"200%": { "normal": "resources/dark/icon@2x.png" }
}
],
"isViewer": true,
"EditorsSupport": ["word"],
"isVisual": true,
"isModal": false,
"isInsideMode": true,
"initDataType": "none",
"initData": "",
"isUpdateOleOnResize": true,
"buttons": [
{ "text": "Close", "primary": false }
],
"size": [320, 600],
"store": {
"background": {
"light": "#F5F5F5",
"dark": "#444444"
},
"screenshots": [
"resources/store/screenshots/screen_1.png",
"resources/store/screenshots/screen_2.png"
],
"icons": {
"light": "resources/store/icons",
"dark": "resources/store/icons"
},
"categories": ["work"]
}
}
]
}
20 changes: 20 additions & 0 deletions sdkjs-plugins/content/curly/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Curly</title>
<!--
OnlyOffice plugin bootstrap. The plugin SDK exposes Asc.plugin to us.
We then load our React bundle which auto-detects Asc.plugin and uses
the OnlyOfficeAdapter.
-->
<script src="https://onlyoffice.github.io/sdkjs-plugins/v1/plugins.js"></script>
<script src="pluginCode.js"></script>
<link rel="stylesheet" href="bundle/addin.css" />
</head>
<body>
<div id="app"></div>
<script type="module" src="bundle/addin.js"></script>
</body>
</html>
77 changes: 77 additions & 0 deletions sdkjs-plugins/content/curly/pluginCode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* OnlyOffice plugin bridge — runs at top level of the plugin frame.
*
* Responsibilities:
* - Complete the Asc.plugin handshake by implementing init()
* - Expose a global readiness flag our React bundle waits on
* - Mirror the editor theme onto our Tailwind `.dark` class
* - Handle the Close button from the task panel
*
* The actual React UI lives in bundle/addin.js and picks up the plugin
* via the OnlyOfficeAdapter.
*/
(function () {
'use strict';

// The SDK injects window.Asc.plugin before this script runs.
if (typeof window.Asc === 'undefined' || !window.Asc.plugin) {
console.error('[Curly] Asc.plugin not available — is plugins.js loaded?');

return;
}

// plugins.js paints the pane body for the editor theme (dark background,
// light inherited text) but knows nothing about our component palette.
// Without flipping our own `.dark` class the pane renders a half-dark
// hybrid: shadcn's outline button keeps its LIGHT background while
// inheriting the injected light text — white-on-white, invisible label.
// Theme objects differ across SDK builds (type/Type/name), so sniff all.
function applyEditorTheme(theme) {
var label = String((theme && (theme.type || theme.Type || theme.name)) || 'light');
document.documentElement.classList.toggle('dark', label.toLowerCase().indexOf('dark') !== -1);
}

window.Asc.plugin.onThemeChanged = function (theme) {
// Keep the SDK's own default styling pass, then ours on top.
if (typeof window.Asc.plugin.onThemeChangedBase === 'function') {
window.Asc.plugin.onThemeChangedBase(theme);
}

applyEditorTheme(theme);
};

// Desktop builds (observed v9, 2026-07) do NOT invoke onThemeChanged at
// startup: Asc.plugin.theme simply appears a few ticks AFTER init() —
// checking it inside init() loses the race and the pane stays light.
// Poll briefly until the host has delivered the current theme.
var themePoll = setInterval(function () {
if (window.Asc.plugin.theme) {
applyEditorTheme(window.Asc.plugin.theme);
clearInterval(themePoll);
themePoll = null;
}
}, 100);

setTimeout(function () {
if (themePoll) {
clearInterval(themePoll);
}
}, 10000);

window.Asc.plugin.init = function () {
// Editors that don't fire onThemeChanged on startup still expose the
// current theme here.
if (window.Asc.plugin.theme) {
applyEditorTheme(window.Asc.plugin.theme);
}

window.__curlyOnlyOfficeReady = true;
var ev = new CustomEvent('curly:onlyoffice-ready');
window.dispatchEvent(ev);
};

window.Asc.plugin.button = function () {
// The only button defined in config.json is "Close" (id === 0).
this.executeCommand('close', '');
};
})();
Binary file added sdkjs-plugins/content/curly/resources/dark/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added sdkjs-plugins/content/curly/resources/light/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions sdkjs-plugins/content/curly/resources/store/icons/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion store/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@
{ "name": "odata", "discussion": "" },
{"name": "lizardtypst", "discussion": ""},
{"name": "chineseconvertor", "discussion": ""},
{"name": "chineseautoformattool", "discussion": ""}
{"name": "chineseautoformattool", "discussion": ""},
{"name": "curly", "discussion": "607"}
]