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
16 changes: 11 additions & 5 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#!groovy
@Library('waluigi@release/7') _

beehiveFlowBuild(
container: [
resourceRequestMemory: '4Gi',
resourceLimitCpu: '4',
resourceLimitMemory: '4Gi'
mixedBeehiveFlow(
container: [ resourceRequestMemory: '3Gi', resourceLimitMemory: '3Gi' ],
testPrefix: 'Tiny-Svelte',
platforms: [
[ browser: 'chrome', provider: 'lambdatest', os: 'macOS Sonoma', buckets: 1 ],
[ browser: 'firefox', provider: 'aws', buckets: 1 ],
[ browser: 'safari', provider: 'lambdatest', os: 'macOS Sonoma', buckets: 1 ]
],
customSteps: {
stage("update storybook") {
Expand All @@ -18,5 +20,9 @@ beehiveFlowBuild(
echo "Skipping as is not latest release"
}
}
},
preparePublish: {
yarnInstall()
sh "yarn build"
}
)
94 changes: 57 additions & 37 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,52 +1,72 @@
// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format
import storybook from "eslint-plugin-storybook";

// eslint.config.js
import tinymceEslintPlugin from "@tinymce/eslint-plugin";
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import svelteParser from 'svelte-eslint-parser';
import { defineConfig } from "eslint/config";

export default [{
files: ['**/*.svelte'],
languageOptions: {
ecmaVersion: 2022,
sourceType: 'module',
parser: svelteParser,
globals: {
...globals.browser,
...globals.node
export default defineConfig([
...tinymceEslintPlugin.configs.standard,
{
files: ['**/*.svelte'],
languageOptions: {
ecmaVersion: 2022,
sourceType: 'module',
parser: svelteParser,
globals: {
...globals.browser,
...globals.node
},
parserOptions: {
parser: tsparser,
extraFileExtensions: ['.svelte'],
projectService: true
}
},
parserOptions: {
parser: tsparser,
extraFileExtensions: ['.svelte']
plugins: {
svelte,
'@tinymce': tinymceEslintPlugin
},
rules: {
...svelte.configs.recommended.rules,
eqeqeq: 'error'
}
},
plugins: {
svelte,
'@typescript-eslint': tseslint
},
rules: {
...svelte.configs.recommended.rules,
eqeqeq: 'error'
}
}, {
files: ['**/*.ts'],
languageOptions: {
parser: tsparser,
parserOptions: {
project: './tsconfig.json'
{
files: ['src/main/**/*.ts'],
languageOptions: {
parser: tsparser,
parserOptions: {
project: './tsconfig.json'
},
},
plugins: {
'@tinymce': tinymceEslintPlugin
},
rules: {
'@tinymce/prefer-fun': 'off',
'@typescript-eslint/no-duplicate-imports': 'off',
}
},
plugins: {
'@typescript-eslint': tseslint,
"@tinymce": tinymceEslintPlugin
{
files: ['src/test/**/*.ts'],
languageOptions: {
parser: tsparser,
parserOptions: {
project: './tsconfig.test.json'
},
},
plugins: {
'@tinymce': tinymceEslintPlugin
},
rules: {
'@tinymce/prefer-fun': 'off',
'@typescript-eslint/no-duplicate-imports': 'off',
"@typescript-eslint/no-require-imports": "off"
}
},
rules: {
'@tinymce/prefer-fun': 'off',
'@typescript-eslint/no-duplicate-imports': 'off',
'@typescript-eslint/no-parameter-properties': 'off'
}
}, ...storybook.configs["flat/recommended"]];
...storybook.configs["flat/recommended"]
]);
23 changes: 18 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@
"build": "rollup -c",
"dev": "rollup -c -w",
"validate": "svelte-check",
"lint": "eslint src/main/**/*.{ts,svelte}",
"test": "echo 'No tests hooked up yet'",
"lint": "eslint 'src/**/*.{ts,svelte}'",
"test": "bedrock-auto --bundler rspack -b chrome-headless -f src/test/ts/**/*Test.ts -c tsconfig.test.json",
"test-manual": "bedrock --bundler rspack -f src/test/ts/**/*Test.ts -c tsconfig.test.json",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"deploy-storybook": "storybook build && gh-pages -d ./storybook-static -u 'tiny-bot <no-reply@tiny.cloud>' --nojekyll",
Expand Down Expand Up @@ -55,6 +56,12 @@
}
},
"devDependencies": {
"@ephox/agar": "^8.0.1",
"@ephox/bedrock-client": "^16.0.0",
"@ephox/bedrock-server": "^16.2.0",
"@ephox/katamari": "^9.1.6",
"@ephox/mcagar": "^9.0.1",
"@ephox/sugar": "^9.3.1",
"@rollup/plugin-commonjs": "^17.1.0",
"@rollup/plugin-node-resolve": "^11.2.1",
"@rollup/plugin-typescript": "^8.5.0",
Expand All @@ -64,10 +71,11 @@
"@storybook/svelte-vite": "^10.2.17",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@tinymce/beehive-flow": "^0.19.0",
"@tinymce/eslint-plugin": "3.0.0",
"@tinymce/eslint-plugin": "^3.0.0",
"@tinymce/miniature": "^6.0.0",
"@tsconfig/svelte": "^5.0.8",
"@typescript-eslint/eslint-plugin": "^8.57.0",
"@typescript-eslint/parser": "^8.46.2",
"@typescript-eslint/eslint-plugin": "^8.62.0",
"@typescript-eslint/parser": "^8.62.0",
"eslint": "^9.38.0",
"eslint-plugin-storybook": "10.2.17",
"eslint-plugin-svelte": "^3.15.2",
Expand All @@ -85,6 +93,11 @@
"svelte-loader": "^3.2.4",
"svelte-preprocess": "^6.0.0",
"tinymce": "^8.1.2",
"tinymce-5": "npm:tinymce@^5",
"tinymce-6": "npm:tinymce@^6",
"tinymce-7": "npm:tinymce@^7",
"tinymce-7.5": "npm:tinymce@7.5",
"tinymce-8": "npm:tinymce@^8.0.0",
"tslib": "^2.8.1",
"typescript": "^5.9.3",
"vite": "^5.4.21"
Expand Down
14 changes: 14 additions & 0 deletions scripts/svelte-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Minimal Svelte loader for webpack/rspack.
const { compile } = require('svelte/compiler');

module.exports = function svelteLoader(source) {
const result = compile(source, {
filename: this.resourcePath,
generate: 'client',
dev: true
});

result.warnings.forEach((w) => this.emitWarning(new Error(w.message)));

return result.js.code;
};
68 changes: 35 additions & 33 deletions src/main/component/Editor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@
-->

<script lang="ts" module>
declare let global: { tinymce: TinyMCE }
declare let window: Window & { tinymce: TinyMCE }
declare let global: { tinymce: TinyMCE };
declare let window: Window & { tinymce: TinyMCE };

const uuid = (prefix: string): string => {
return prefix + '_' + Math.floor(Math.random() * 1000000000) + String(Date.now());
};
const uuid = (prefix: string): string => prefix + '_' + Math.floor(Math.random() * 1000000000) + String(Date.now());

const isDisabledOptionSupported = (editor: TinyMCEEditor): boolean => {
return typeof editor.options.set === 'function' && editor.options.isRegistered('disabled')
};
const isDisabledOptionSupported = (editor: TinyMCEEditor): boolean => typeof editor.options.set === 'function' && editor.options.isRegistered('disabled');

const createScriptLoader = () => {
let state: {
listeners: Array<() => void>,
scriptId: string,
scriptLoaded: boolean,
injected: boolean
listeners: Array<() => void>;
scriptId: string;
scriptLoaded: boolean;
injected: boolean;
} = {
listeners: [],
scriptId: uuid('tiny-script'),
Expand All @@ -35,8 +31,12 @@
script.referrerPolicy = 'origin';
script.type = 'application/javascript';
script.src = url;
script.onload = () => { cb();}
if (doc.head) doc.head.appendChild(script);
script.onload = () => {
cb();
};
if (doc.head) {
doc.head.appendChild(script);
}
};

const load = (doc: Document, url: string, callback: () => void) => {
Expand All @@ -56,16 +56,16 @@

return {
load
}
};
};
let scriptLoader = createScriptLoader();
</script>

<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import type { TinyMCE, Editor as TinyMCEEditor } from 'tinymce';
import { bindHandlers } from './Utils';
import type { EventHandlers } from './Utils';

import { bindHandlers, type EventHandlers } from './Utils';

type EditorOptions = Parameters<TinyMCE['init']>[0];
type Channel = `${'4' | '5' | '6' | '7' | '8'}${'' | '-dev' | '-testing' | `.${number}` | `.${number}.${number}`}`;
Expand Down Expand Up @@ -109,28 +109,28 @@
// The following three variables are not meant to be reactive, but we need to track them to avoid unnecessary editor updates.
let lastVal = $state.snapshot(value);
// svelte-ignore state_referenced_locally
let disablindCache = $state.snapshot(disabled)
let disablindCache = $state.snapshot(disabled);
// svelte-ignore state_referenced_locally
let readonlyCache = $state.snapshot(readonly);

const setReadonly = (editor: TinyMCEEditor, readonlyValue: boolean) => {
if (typeof editor.mode?.set === 'function') {
editor.mode.set(readonlyValue ? 'readonly' : 'design');
}
}
};

const setDisabled = (editor: TinyMCEEditor, disabledValue: boolean) => {
if (isDisabledOptionSupported(editor)) {
editor.options.set('disabled', disabledValue);
} else {
editor.mode.set(disabledValue ? 'readonly' : 'design');
}
}
editor.options.set('disabled', disabledValue);
} else {
editor.mode.set(disabledValue ? 'readonly' : 'design');
}
};

$effect(() => {
if (editorRef && lastVal !== value) {
editorRef.setContent(value);
text = editorRef.getContent({format: 'text'});
text = editorRef.getContent({ format: 'text' });
}
if (editorRef && readonly !== readonlyCache) {
readonlyCache = readonly;
Expand All @@ -141,19 +141,18 @@
setDisabled(editorRef, disabled);
}
});

const getTinymce = (): TinyMCE | null => {
const getSink = (): { tinymce: TinyMCE } => {
return typeof window !== 'undefined' ? window : global;
};
const getSink = (): { tinymce: TinyMCE } => typeof window !== 'undefined' ? window : global;
const sink = getSink();
return sink && sink.tinymce ? sink.tinymce : null;
};

const init = () => {
const finalInit: EditorOptions = {
...conf,
target: element,
// eslint-disable-next-line no-nested-ternary
inline: inline !== undefined ? inline : conf.inline !== undefined ? conf.inline : false,
license_key: licenseKey,
setup: (editor: TinyMCEEditor) => {
Expand All @@ -169,7 +168,7 @@
lastVal = editor.getContent();
if (lastVal !== value) {
value = lastVal;
text = editor.getContent({format: 'text'});
text = editor.getContent({ format: 'text' });
}
});
});
Expand All @@ -179,15 +178,18 @@
}
},
};
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
element!.style.visibility = '';
// eslint-disable-next-line @typescript-eslint/no-floating-promises
void getTinymce()?.init(finalInit);
};

onMount(() => {
if (getTinymce() !== null) {
init();
} else {
const script = scriptSrc ? scriptSrc : `https://cdn.tiny.cloud/1/${apiKey}/tinymce/${channel}/tinymce.min.js`;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
scriptLoader.load(container!.ownerDocument, script, () => {
init();
});
Expand Down
12 changes: 6 additions & 6 deletions src/main/component/Utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Editor, TinyMCE } from "tinymce";
import type { Editor, TinyMCE } from 'tinymce';

export const validEvents = [
'Activate',
Expand Down Expand Up @@ -73,17 +73,17 @@ export const validEvents = [
export type ValidEventTypes = Lowercase<typeof validEvents[number]>;
export type EventHandlers = {
[K in ValidEventTypes]: (event: any, editor: TinyMCE) => void;
}
};

export const bindHandlers = (editor: Editor, eventHandlers: Partial<EventHandlers>) => {
export const bindHandlers = (editor: Editor, eventHandlers: Partial<EventHandlers>): void => {
validEvents.forEach( (eventName) => {
editor.on(eventName, (e) => {
eventHandlers[eventName.toLowerCase()]?.(e, editor);
});
})};
});
};


export const injectTiny = (doc, url, cb) => {
export const injectTiny = (doc: any, url: string, cb: any): void => {
const script = doc.createElement('script');
script.referrerPolicy = 'origin';
script.type = 'application/javascript';
Expand Down
Loading
Loading