Skip to content

Commit fe72730

Browse files
authored
DOC-3404 - Update Full-Featured Premium Demo to use TinyMCE AI plugin (#4043)
* Docs: DOC-3404 - Update Full-Featured Premium Demo to use TinyMCE AI plugin Replace legacy AI Assistant plugin with the new TinyMCE AI plugin in the full-featured premium demo. Updates toolbar buttons, quickbar actions, sidebar default, translation configuration, and custom quick actions to align with the TinyMCE AI plugin documentation demos. * Docs: DOC-3404 - Restore standard quickbar items alongside AI actions * Docs: DOC-3404 - Remove AI Assistant from excluded plugins table * Docs: DOC-3404 - Replace Translate toolbar button with full Quick Actions menu
1 parent 16fe854 commit fe72730

3 files changed

Lines changed: 99 additions & 278 deletions

File tree

modules/ROOT/examples/live-demos/full-featured/example.js

Lines changed: 47 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
const fetchApi = import('https://cdn.skypack.dev/@microsoft/fetch-event-source@2.0.1')
2-
.then((module) => module.fetchEventSource);
3-
41
const API_URL = 'https://demouserdirectory.tiny.cloud/v1/users';
52

63
const user_id = 'james-wilson';
@@ -250,136 +247,6 @@ const tinycomments_fetch = (conversationUids, done) => {
250247
setTimeout(() => done({ conversations: fetchedConversations }), fakeDelay);
251248
};
252249

253-
const ai_request = (request, respondWith) => {
254-
respondWith.stream((signal, streamMessage) => {
255-
// Adds each previous query and response as individual messages
256-
const conversation = request.thread.flatMap((event) => {
257-
if (event.response) {
258-
return [
259-
{ role: "user", content: event.request.query },
260-
{ role: "assistant", content: event.response.data },
261-
];
262-
} else {
263-
return [];
264-
}
265-
});
266-
267-
// System messages provided by the plugin to format the output as HTML content.
268-
const systemMessages = request.system.map((content) => ({
269-
role: "system",
270-
content,
271-
}));
272-
273-
// Forms the new query sent to the API
274-
const content =
275-
request.context.length === 0 || conversation.length > 0
276-
? request.query
277-
: `Question: ${request.query} Context: """${request.context}"""`;
278-
279-
const messages = [
280-
...conversation,
281-
...systemMessages,
282-
{ role: "user", content },
283-
];
284-
285-
let hasHead = false;
286-
let markdownHead = "";
287-
288-
const hasMarkdown = (message) => {
289-
if (message.includes("`") && markdownHead !== "```") {
290-
const numBackticks = message.split("`").length - 1;
291-
markdownHead += "`".repeat(numBackticks);
292-
if (hasHead && markdownHead === "```") {
293-
markdownHead = "";
294-
hasHead = false;
295-
}
296-
return true;
297-
} else if (message.includes("html") && markdownHead === "```") {
298-
markdownHead = "";
299-
hasHead = true;
300-
return true;
301-
}
302-
return false;
303-
};
304-
305-
const requestBody = {
306-
model: "gpt-4o",
307-
temperature: 0.7,
308-
max_tokens: 4000,
309-
messages,
310-
stream: true,
311-
};
312-
313-
const openAiOptions = {
314-
signal,
315-
method: "POST",
316-
headers: {
317-
"Content-Type": "application/json",
318-
Authorization: `Bearer {{ openai_proxy_token }}`,
319-
},
320-
body: JSON.stringify(requestBody),
321-
};
322-
323-
const onopen = async (response) => {
324-
if (response) {
325-
const contentType = response.headers.get("content-type");
326-
if (response.ok && contentType?.includes("text/event-stream")) {
327-
return;
328-
} else if (contentType?.includes("application/json")) {
329-
const data = await response.json();
330-
if (data.error) {
331-
throw new Error(`${data.error.type}: ${data.error.message}`);
332-
}
333-
}
334-
} else {
335-
throw new Error("Failed to communicate with the ChatGPT API");
336-
}
337-
};
338-
339-
// This function passes each new message into the plugin via the `streamMessage` callback.
340-
const onmessage = (ev) => {
341-
const data = ev.data;
342-
if (data !== "[DONE]") {
343-
const parsedData = JSON.parse(data);
344-
const firstChoice = parsedData?.choices[0];
345-
const message = firstChoice?.delta?.content;
346-
if (message && message !== "") {
347-
if (!hasMarkdown(message)) {
348-
streamMessage(message);
349-
}
350-
}
351-
}
352-
};
353-
354-
const onerror = (error) => {
355-
// Stop operation and do not retry by the fetch-event-source
356-
throw error;
357-
};
358-
359-
// Use microsoft's fetch-event-source library to work around the 2000 character limit
360-
// of the browser `EventSource` API, which requires query strings
361-
return fetchApi
362-
.then((fetchEventSource) =>
363-
fetchEventSource("{{ openai_proxy_url }}", {
364-
...openAiOptions,
365-
openWhenHidden: true,
366-
onopen,
367-
onmessage,
368-
onerror,
369-
})
370-
)
371-
.then(async (response) => {
372-
if (response && !response.ok) {
373-
const data = await response.json();
374-
if (data.error) {
375-
throw new Error(`${data.error.type}: ${data.error.message}`);
376-
}
377-
}
378-
})
379-
.catch(onerror);
380-
});
381-
};
382-
383250
const revisions = [
384251
{
385252
revisionId: '3',
@@ -537,7 +404,7 @@ const revisionhistory_fetch_revision = (_editor, revision) => new Promise((resol
537404
tinymce.init({
538405
selector: 'textarea#full-featured',
539406
plugins: [
540-
'ai', 'suggestededits', 'preview', 'powerpaste', 'casechange', 'importcss', 'searchreplace',
407+
'tinymceai', 'suggestededits', 'preview', 'powerpaste', 'casechange', 'importcss', 'searchreplace',
541408
'autolink', 'autosave', 'save', 'directionality', 'advcode', 'visualblocks', 'visualchars', 'fullscreen',
542409
'link', 'math', 'media', 'mediaembed', 'codesample', 'table', 'charmap', 'pagebreak', 'nonbreaking',
543410
'anchor', 'tableofcontents', 'insertdatetime', 'advlist', 'lists', 'checklist', 'wordcount', 'tinymcespellchecker',
@@ -553,9 +420,9 @@ tinymce.init({
553420
},
554421
menubar: 'file edit view insert format tools table tc help',
555422
// Note: if a toolbar item requires a plugin, the item will not present in the toolbar if the plugin is not also loaded.
556-
toolbar: "undo redo | insertfile |importword exportword exportpdf | suggestededits | revisionhistory | aidialog aishortcuts | blocks fontsizeinput | bold italic | align numlist bullist | link uploadcare uploadcare-video | table math media pageembed | lineheight outdent indent | strikethrough forecolor backcolor formatpainter removeformat | charmap emoticons checklist | code fullscreen preview | save print | pagebreak anchor codesample footnotes mergetags | addtemplate inserttemplate | addcomment showcomments | ltr rtl casechange | spellcheckdialog a11ycheck",
423+
toolbar: "undo redo | insertfile |importword exportword exportpdf | suggestededits | revisionhistory | tinymceai-chat tinymceai-review tinymceai-quickactions | blocks fontsizeinput | bold italic | align numlist bullist | link uploadcare uploadcare-video | table math media pageembed | lineheight outdent indent | strikethrough forecolor backcolor formatpainter removeformat | charmap emoticons checklist | code fullscreen preview | save print | pagebreak anchor codesample footnotes mergetags | addtemplate inserttemplate | addcomment showcomments | ltr rtl casechange | spellcheckdialog a11ycheck",
557424
mobile: {
558-
plugins: 'ai suggestededits preview powerpaste casechange importcss searchreplace autolink autosave save directionality advcode visualblocks visualchars fullscreen link math media mediaembed codesample table charmap pagebreak nonbreaking anchor tableofcontents insertdatetime advlist lists checklist wordcount tinymcespellchecker a11ychecker help formatpainter pageembed charmap mentions quickbars emoticons advtable footnotes mergetags autocorrect typography advtemplate uploadcare'
425+
plugins: 'tinymceai suggestededits preview powerpaste casechange importcss searchreplace autolink autosave save directionality advcode visualblocks visualchars fullscreen link math media mediaembed codesample table charmap pagebreak nonbreaking anchor tableofcontents insertdatetime advlist lists checklist wordcount tinymcespellchecker a11ychecker help formatpainter pageembed charmap mentions quickbars emoticons advtable footnotes mergetags autocorrect typography advtemplate uploadcare'
559426
},
560427

561428
autosave_ask_before_unload: true,
@@ -628,19 +495,60 @@ tinymce.init({
628495
],
629496
importcss_append: true,
630497
height: 600,
631-
quickbars_selection_toolbar: 'bold italic | quicklink h2 h3 blockquote quicktable | addcomment showcomments',
498+
quickbars_selection_toolbar: 'tinymceai-quickactions ai-quickactions-translate | bold italic | quicklink h2 h3 blockquote quicktable | addcomment',
632499
noneditable_class: 'mceNonEditable',
633500
toolbar_mode: 'sliding',
634501
spellchecker_ignore_list: ['Ephox', 'Moxiecode', 'tinymce', 'TinyMCE'],
635502
content_style: '.mymention{ color: gray; }' +
636503
'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }',
637504
contextmenu: 'link uploadcare uploadcare-video table spellchecker configurepermanentpen',
638505

639-
ai_request,
506+
tinymceai_token_provider: async () => {
507+
return fetch('/api/tinymceai-token', { credentials: 'include' })
508+
.then(resp => resp.text())
509+
.then(token => ({ token }));
510+
},
511+
tinymceai_chat_fetch_sources: () => Promise.resolve([{
512+
label: 'TinyMCE resources',
513+
sources: [
514+
{ id: 'docs', label: 'TinyMCE Documentation', type: 'web-resource' },
515+
{ id: 'blog', label: 'Tiny Blog', type: 'web-resource' },
516+
{ id: 'survey-2023', label: 'State of rich text editing 2023', type: 'web-resource' },
517+
]
518+
}]),
519+
tinymceai_chat_fetch_source: (id) => {
520+
const urls = {
521+
'docs': 'https://www.tiny.cloud/docs/tinymce/latest/',
522+
'blog': 'https://www.tiny.cloud/blog/',
523+
'survey-2023': 'https://www.tiny.cloud/developer-survey-results-2023/',
524+
};
525+
return Promise.resolve({ type: 'web-resource', url: urls[id] });
526+
},
527+
tinymceai_quickactions_custom: [
528+
{
529+
type: 'chat',
530+
title: 'Challenge',
531+
prompt: 'Challenge statements, verify facts and identify assumptions'
532+
}
533+
],
534+
tinymceai_languages: [
535+
{ title: 'English', language: 'english' },
536+
{ title: 'Chinese (Simplified)', language: 'chinese' },
537+
{ title: 'Spanish', language: 'spanish' },
538+
{ title: 'German', language: 'german' },
539+
{ title: 'Japanese', language: 'japanese' },
540+
{ title: 'Portuguese', language: 'portuguese' },
541+
{ title: 'Swedish', language: 'swedish' },
542+
{ title: 'Korean', language: 'korean' },
543+
{ title: 'Hindi (Devanagari)', language: 'hindi devanagari' },
544+
{ title: 'Italian', language: 'italian' },
545+
{ title: 'Klingon', language: 'klingon' },
546+
{ title: 'Dothraki', language: 'dothraki' },
547+
],
640548

641549
tinycomments_mode: 'callback',
642550
tinycomments_mentions_enabled: true,
643-
sidebar_show: 'showcomments',
551+
sidebar_show: 'tinymceai-chat',
644552
tinycomments_create,
645553
tinycomments_reply,
646554
tinycomments_delete,

modules/ROOT/examples/live-demos/full-featured/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<textarea id="full-featured">
22
<h1 style="text-align: left;">Welcome to the TinyMCE editor demo!</h1>
3-
<p>Meet <strong>TinyMCE, </strong>the Internet's most&nbsp;<span style="background-color: #eccafa;">battle-tested <span class="mce-annotation tox-comment" data-mce-annotation-uid="mce-conversation_19679600221621399703915" data-mce-annotation="tinycomments">rich text editor</span></span> with over 60 features including: <em>Advanced formatting, </em><span style="color: #ba372a;"><strong><em>Export to and from Word and PDF, </em></strong></span><span style="font-family: 'times new roman', times, serif; font-size: 14pt;">Accessibility and spelling checkers</span>,&nbsp;Mentions and comments, and <strong><span style="color: #169179;">an AI assistant</span></strong>.</p>
3+
<p>Meet <strong>TinyMCE, </strong>the Internet's most&nbsp;<span style="background-color: #eccafa;">battle-tested <span class="mce-annotation tox-comment" data-mce-annotation-uid="mce-conversation_19679600221621399703915" data-mce-annotation="tinycomments">rich text editor</span></span> with over 60 features including: <em>Advanced formatting, </em><span style="color: #ba372a;"><strong><em>Export to and from Word and PDF, </em></strong></span><span style="font-family: 'times new roman', times, serif; font-size: 14pt;">Accessibility and spelling checkers</span>,&nbsp;Mentions and comments, and <strong><span style="color: #169179;">TinyMCE AI</span></strong>.</p>
44
<p><span style="font-family: terminal, monaco, monospace;">TinyMCE is easy to implement and configure</span>. <a href="https://www.tiny.cloud/auth/signup/?utm_campaign=tiny_docs&amp;utm_source=site&amp;keyword=docs">Try it out yourself today</a>.</p>
55
<h2>⭐️ Popular features</h2>
66
<ul>

0 commit comments

Comments
 (0)