Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Step 1: Set up session - this should be part of the application's user management process.
// Open-source plugins below are only for editing the demo HTML (lists, links, tables). TinyMCE AI options are the focus.
// Share one TinyMCE AI configuration between every editor. Each editor sets its own group, so the page holds two independent groups.
const sharedSettings = {
height: '400px',
plugins: ['tinymceai', 'advlist', 'lists', 'link', 'autolink', 'table', 'wordcount'],
toolbar: 'undo redo | tinymceai-chat tinymceai-review ai-quickactions-translate | styles | bold italic | bullist numlist | link',
tinymceai_sidebar_type: 'floating',
tinymceai_chat_welcome_message: '<p>Welcome to TinyMCE AI. Pick an action below or type your own prompt.</p>',
tinymceai_chat_welcome_actions: [
{ text: 'Here are some actions to get started:' },
{ title: 'Summarize the document', command: 'TinyMCEAIQuickActionsSummarize' },
{ title: 'Continue writing', command: 'TinyMCEAIQuickActionContinueWriting' },
{ title: 'Translate to Spanish', command: 'TinyMCEAIQuickActionTranslate', value: 'spanish' },
{ title: 'Review my document', command: 'ToggleSidebar', value: 'tinymceai-review' }
],
tinymceai_token_provider: async () => {
return fetch('/api/tinymceai-token', { credentials: 'include' })
.then(resp => resp.text())
.then(token => ({ token }));
},
tinymceai_chat_fetch_sources: () => Promise.resolve([{
label: 'TinyMCE resources',
sources: [
{ id: 'docs', label: 'TinyMCE Documentation', type: 'web-resource' },
{ id: 'blog', label: 'Tiny Blog', type: 'web-resource' },
{ id: 'survey-2023', label: 'State of rich text editing 2023', type: 'web-resource' },
]
}]),
tinymceai_chat_fetch_source: (id) => {
const urls = {
'docs': 'https://www.tiny.cloud/docs/tinymce/latest/',
'blog': 'https://www.tiny.cloud/blog/',
'survey-2023': 'https://www.tiny.cloud/developer-survey-results-2023/',
};
return Promise.resolve({ type: 'web-resource', url: urls[id] });
},
tinymceai_quickactions_custom: [
{
type: 'chat',
title: 'Challenge',
prompt: 'Challenge statements, verify facts and identify assumptions'
}
],
tinymceai_languages: [
{ title: 'English', language: 'english' },
{ title: 'Chinese (Simplified)', language: 'chinese' },
{ title: 'Spanish', language: 'spanish' },
{ title: 'German', language: 'german' },
{ title: 'Japanese', language: 'japanese' },
{ title: 'Portuguese', language: 'portuguese' },
{ title: 'Swedish', language: 'swedish' },
{ title: 'Korean', language: 'korean' },
{ title: 'Hindi (Devanagari)', language: 'hindi devanagari' },
{ title: 'Italian', language: 'italian' },
{ title: 'Klingon', language: 'klingon' },
{ title: 'Dothraki', language: 'dothraki' },
]
};

// Group 1: the Introduction and Native integration editors share one AI sidebar.
tinymce.init({
...sharedSettings,
selector: 'textarea#tinymceai-multi-editor-groups-introduction',
tinymceai_group: 'article-opening',
tinymceai_document_name: 'Introduction',
tinymceai_document_description: 'The introduction of the article. A title, a short paragraph that sets out the topic, and a figure.'
});

tinymce.init({
...sharedSettings,
selector: 'textarea#tinymceai-multi-editor-groups-native-integration',
tinymceai_group: 'article-opening',
tinymceai_document_name: 'Native integration',
tinymceai_document_description: 'The section on moving from external AI tools to AI built into the editor, with a bulleted list of benefits.'
});

// Group 2: the Workflow comparison and Adoption challenges editors share a separate AI sidebar and never see the content of group 1.
tinymce.init({
...sharedSettings,
selector: 'textarea#tinymceai-multi-editor-groups-workflow-comparison',
tinymceai_group: 'article-analysis',
tinymceai_document_name: 'Workflow comparison',
tinymceai_document_description: 'The section that compares traditional and AI-enhanced workflows. Keep the comparison table.'
});

tinymce.init({
...sharedSettings,
selector: 'textarea#tinymceai-multi-editor-groups-adoption-challenges',
tinymceai_group: 'article-analysis',
tinymceai_document_name: 'Adoption challenges',
tinymceai_document_description: 'The closing section on adoption challenges. Two short paragraphs.'
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<div style="max-width: 900px;">
<div style="border: 2px solid #d6dbe0; border-radius: 8px; padding: 12px; margin-bottom: 20px;">
<h3>Group 1: <code>article-opening</code></h3>
<h4>Introduction (hosts the AI sidebar of group 1)</h4>
<textarea id="tinymceai-multi-editor-groups-introduction">
<h1>The Future of Content Creation: Integrating GenAI into Modern Workflows</h1>
<p>The landscape of digital content creation is undergoing a seismic shift. For years, the process of writing, editing, and publishing remained largely manual, requiring significant cognitive load for every draft. However, the emergence of Generative AI (GenAI) has introduced a new paradigm. By embedding intelligence directly into the tools where writing happens, organizations can unlock unprecedented levels of productivity and creativity.</p>
<figure class="image"><img style="width: 566px; aspect-ratio: 1536 / 1024; display: block; margin-left: auto; margin-right: auto;" src="https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/preview/" sizes="(min-width: 1536px) 1536px, 100vw" srcset="https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/resize/100x/ 100w,https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/resize/200x/ 200w,https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/resize/300x/ 300w,https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/resize/500x/ 500w,https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/resize/750x/ 750w,https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/resize/1000x/ 1000w,https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/resize/1250x/ 1250w,https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/resize/1500x/ 1500w,https://tiny.ucarecdn.com/c273f5d9-8931-4f66-86a4-347a6137ca88/-/preview/ 1536w" alt="Retro pop art illustration in red and blue halftone style showing a friendly robot collaborating with three people using laptops and tablets, symbolizing AI-assisted content creation and teamwork." height="357">
<figcaption>By embedding intelligence directly into the tools where writing happens, organizations unlock unprecedented levels of productivity and creativity.</figcaption>
</figure>
</textarea>

<h4>Native integration (shares the AI sidebar of group 1)</h4>
<textarea id="tinymceai-multi-editor-groups-native-integration">
<h2>The Shift from External Tools to Native Integration</h2>
<p>Many early adopters of AI technology rely on external chat interfaces. While powerful, this "copy-paste" workflow introduces friction and disrupts the creative flow. Native integration&mdash;where the AI exists within the text editor itself&mdash;allows creators to remain focused. Instead of switching tabs to generate a summary or check facts, the AI acts as a collaborative partner that understands the context of the current document.</p>
<h3>Key Benefits of Integrated AI</h3>
<ul>
<li><strong>Contextual Awareness:</strong> AI can analyze existing text to suggest relevant follow-up points or maintain a consistent brand voice.</li>
<li><strong>Reduced Cognitive Load:</strong> By automating repetitive tasks like formatting and basic proofreading, writers can focus on high-level strategy and storytelling.</li>
<li><strong>Streamlined Collaboration:</strong> Integrated tools allow teams to brainstorm and refine ideas within a single shared environment, accelerating the approval process.</li>
<li><strong>Enhanced Accuracy:</strong> When connected to internal knowledge bases, GenAI can provide fact-checking capabilities that generic models lack.</li>
</ul>
</textarea>
</div>
<div style="border: 2px solid #d6dbe0; border-radius: 8px; padding: 12px; margin-bottom: 20px;">
<h3>Group 2: <code>article-analysis</code></h3>
<h4>Workflow comparison (hosts the AI sidebar of group 2)</h4>
<textarea id="tinymceai-multi-editor-groups-workflow-comparison">
<h2>Evaluating Workflow Improvements</h2>
<p>To understand the impact of GenAI integration, it is helpful to compare traditional workflows against AI-enhanced processes. The following table highlights common content tasks and how native AI transforms the output and efficiency for different stakeholders.</p>
<table style="width: 100%; border-collapse: collapse; margin-top: 20px; margin-bottom: 20px; border: 1px solid rgb(206, 212, 217);" border="1">
<thead>
<tr>
<th style="border-color: #ced4d9; background-color: #ecf0f1; width: 26.6364%;">Workflow Task</th>
<th style="border-color: #ced4d9; background-color: #ecf0f1; width: 35.8714%;">Traditional Method</th>
<th style="border-color: #ced4d9; background-color: #ecf0f1; width: 37.4922%;">GenAI-Enhanced Method</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border-color: #ced4d9; width: 26.6364%;"><strong>Drafting</strong></td>
<td style="border-color: #ced4d9; width: 35.8714%;">Starting from a blank page.</td>
<td style="border-color: #ced4d9; width: 37.4922%;">AI-generated outlines and initial drafts.</td>
</tr>
<tr>
<td style="border-color: #ced4d9; width: 26.6364%;"><strong>Research</strong></td>
<td style="border-color: #ced4d9; width: 35.8714%;">Manual searching across multiple tabs.</td>
<td style="border-color: #ced4d9; width: 37.4922%;">Instant retrieval of internal/external data.</td>
</tr>
<tr>
<td style="border-color: #ced4d9; width: 26.6364%;"><strong>Tone Adjustment</strong></td>
<td style="border-color: #ced4d9; width: 35.8714%;">Manual rewriting for different audiences.</td>
<td style="border-color: #ced4d9; width: 37.4922%;">One-click conversion (e.g., Casual to Formal).</td>
</tr>
<tr>
<td style="border-color: #ced4d9; width: 26.6364%;"><strong>Summarization</strong></td>
<td style="border-color: #ced4d9; width: 35.8714%;">Reading full text and manual condensing.</td>
<td style="border-color: #ced4d9; width: 37.4922%;">Automated key takeaway generation.</td>
</tr>
<tr>
<td style="border-color: #ced4d9; width: 26.6364%;"><strong>Localization</strong></td>
<td style="border-color: #ced4d9; width: 35.8714%;">External translation services required.</td>
<td style="border-color: #ced4d9; width: 37.4922%;">In-editor multilingual support and translation.</td>
</tr>
</tbody>
</table>
</textarea>

<h4>Adoption challenges (shares the AI sidebar of group 2)</h4>
<textarea id="tinymceai-multi-editor-groups-adoption-challenges">
<h2>Overcoming Adoption Challenges</h2>
<p>While the advantages are clear, implementing GenAI requires a strategic approach. Concerns regarding data privacy, output quality, and the "human touch" are common. <em>To address these, organizations should prioritize tools that offer "human-in-the-loop" functionality</em>. AI should be viewed as an assistant&mdash;a co-pilot that offers suggestions while leaving final editorial control in the hands of the writer.</p>
<p>Furthermore, technical teams must focus on the "integrator" experience. Providing developers with straightforward APIs and pre-built UI components ensures that these advanced features can be deployed quickly <strong>without the risk of building complex AI infrastructure from scratch</strong>. As we look toward the future, the goal is simple: technology that fades into the background, empowering creators to do their best work with less friction.</p>
</textarea>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Step 1: Set up session - this should be part of the application's user management process. We simulate that here by creating a session for a random user.
const apiKey = '{{tinymceai_demo_api_key}}';
const isLoggedIn = fetch(`https://demo.api.tiny.cloud/1/${apiKey}/auth/random`, { method: "POST", credentials: "include" });

const mentions_fetch = async (query, success) => {
const searchPhrase = query.term.toLowerCase();
await fetch(`https://demouserdirectory.tiny.cloud/v1/users?q=${encodeURIComponent(searchPhrase)}`)
.then((response) => response.json())
.then((users) => success(users.data.map((userInfo) => ({
id: userInfo.id,
name: userInfo.name,
image: userInfo.avatar,
description: userInfo.custom.role
}))))
.catch(() => {});
};

const fetch_users = (userIds) => Promise.all(userIds.map((userId) => fetch(`https://demouserdirectory.tiny.cloud/v1/users/${userId}`).then((response) => response.json()).catch(() => ({ id: userId }))));

// Each editor seeds its revision history from its own textarea.
const createRevisionHistoryFetch = (selector) => () => {
const textarea = document.querySelector(selector);
const initialContent = textarea ? textarea.value : '';
const revisions = [
{
revisionId: '1',
createdAt: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate() - 1, 14, 32, 0).getTime(),
author: {
id: 'jade-scott',
name: 'Jade Scott',
avatar: 'https://sneak-preview.tiny.cloud/demouserdirectory/images/employee_jade-scott_128_515dc6a1.jpg',
},
content: initialContent
},
{
revisionId: '0',
createdAt: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate() - 1, 14, 32, 0).getTime(),
author: {
id: 'jade-scott',
name: 'Jade Scott',
avatar: 'https://sneak-preview.tiny.cloud/demouserdirectory/images/employee_jade-scott_128_515dc6a1.jpg',
},
content: ''
}
];
return Promise.resolve(revisions.sort((a, b) => (new Date(a.createdAt) < new Date(b.createdAt) ? -1 : 1)));
};

// Share one TinyMCE AI configuration between every editor. Each editor sets its own group, so the page holds two independent groups.
const sharedSettings = {
height: '400px',
plugins: [
'autolink', 'link', 'emoticons', 'lists', 'table', 'advlist', 'searchreplace', 'wordcount', 'autocorrect', 'tinymcespellchecker', 'charmap', 'fullscreen', 'advcode', 'accordion', 'anchor', 'footnotes', 'powerpaste', 'importword', 'exportpdf', 'exportword', 'markdown', 'a11ychecker', 'typography', 'casechange', 'checklist', 'advtable', 'formatpainter', 'permanentpen', 'tableofcontents', 'help', 'math', 'linkchecker', 'media', 'mediaembed',
'quickbars', 'tinymceai', 'tinycomments', 'mentions', 'revisionhistory', 'suggestededits', 'uploadcare'
],
toolbar: 'undo redo | tinymceai-chat tinymceai-review ai-quickactions-translate | styles | bold italic | bullist numlist | link',
tinymceai_sidebar_type: 'floating',
quickbars_selection_toolbar: 'tinymceai-quickactions addcomment',
tinymceai_chat_welcome_message: '<p>Welcome to TinyMCE AI. Pick an action below or type your own prompt.</p>',
tinymceai_chat_welcome_actions: [
{ text: 'Here are some actions to get started:' },
{ title: 'Summarize the document', command: 'TinyMCEAIQuickActionsSummarize' },
{ title: 'Continue writing', command: 'TinyMCEAIQuickActionContinueWriting' },
{ title: 'Translate to Spanish', command: 'TinyMCEAIQuickActionTranslate', value: 'spanish' },
{ title: 'Review my document', command: 'ToggleSidebar', value: 'tinymceai-review' }
],
toolbar_mode: 'sliding',
visual: false,
images_file_types: 'jpeg,jpg,jpe,jfi,jif,jfif,png,gif,bmp,webp,svg',
user_id: 'james-wilson',
spellchecker_active: true,
spellchecker_dialog: true,
uploadcare_public_key: '630992ad50fe2291c406',
uploadcare_store_type: 'temporary',
advcode_inline: true,
tinycomments_mode: 'embedded',
suggestededits_content: 'html',
mentions_item_type: 'profile',
mentions_fetch,
fetch_users,
revisionhistory_display_author: true,
tinymceai_token_provider: async () => {
// Step 2: Check we have a session then fetch JWT
return isLoggedIn.then(() =>
fetch(`https://demo.api.tiny.cloud/1/${apiKey}/jwt/tinymceai`, { credentials: "include" })
.then(resp => resp.text())
.then(token => ({ token }))
);
},
tinymceai_chat_fetch_sources: () => Promise.resolve([{
label: 'TinyMCE resources',
sources: [
{ id: 'docs', label: 'TinyMCE Documentation', type: 'web-resource' },
{ id: 'blog', label: 'Tiny Blog', type: 'web-resource' },
{ id: 'survey-2023', label: 'State of rich text editing 2023', type: 'web-resource' },
]
}]),
tinymceai_chat_fetch_source: (id) => {
const urls = {
'docs': 'https://www.tiny.cloud/docs/tinymce/latest/',
'blog': 'https://www.tiny.cloud/blog/',
'survey-2023': 'https://www.tiny.cloud/developer-survey-results-2023/',
};
return Promise.resolve({ type: 'web-resource', url: urls[id] });
},
tinymceai_quickactions_custom: [
{
type: 'chat',
title: 'Challenge',
prompt: 'Challenge statements, verify facts and identify assumptions'
}
],
tinymceai_languages: [
{ title: 'English', language: 'english' },
{ title: 'Chinese (Simplified)', language: 'chinese' },
{ title: 'Spanish', language: 'spanish' },
{ title: 'German', language: 'german' },
{ title: 'Japanese', language: 'japanese' },
{ title: 'Portuguese', language: 'portuguese' },
{ title: 'Swedish', language: 'swedish' },
{ title: 'Korean', language: 'korean' },
{ title: 'Hindi (Devanagari)', language: 'hindi devanagari' },
{ title: 'Italian', language: 'italian' },
{ title: 'Klingon', language: 'klingon' },
{ title: 'Dothraki', language: 'dothraki' },
]
};

// Group 1: the Introduction and Native integration editors share one AI sidebar.
tinymce.init({
...sharedSettings,
selector: 'textarea#tinymceai-multi-editor-groups-introduction',
revisionhistory_fetch: createRevisionHistoryFetch('textarea#tinymceai-multi-editor-groups-introduction'),
tinymceai_group: 'article-opening',
tinymceai_document_name: 'Introduction',
tinymceai_document_description: 'The introduction of the article. A title, a short paragraph that sets out the topic, and a figure.'
});

tinymce.init({
...sharedSettings,
selector: 'textarea#tinymceai-multi-editor-groups-native-integration',
revisionhistory_fetch: createRevisionHistoryFetch('textarea#tinymceai-multi-editor-groups-native-integration'),
tinymceai_group: 'article-opening',
tinymceai_document_name: 'Native integration',
tinymceai_document_description: 'The section on moving from external AI tools to AI built into the editor, with a bulleted list of benefits.'
});

// Group 2: the Workflow comparison and Adoption challenges editors share a separate AI sidebar and never see the content of group 1.
tinymce.init({
...sharedSettings,
selector: 'textarea#tinymceai-multi-editor-groups-workflow-comparison',
revisionhistory_fetch: createRevisionHistoryFetch('textarea#tinymceai-multi-editor-groups-workflow-comparison'),
tinymceai_group: 'article-analysis',
tinymceai_document_name: 'Workflow comparison',
tinymceai_document_description: 'The section that compares traditional and AI-enhanced workflows. Keep the comparison table.'
});

tinymce.init({
...sharedSettings,
selector: 'textarea#tinymceai-multi-editor-groups-adoption-challenges',
revisionhistory_fetch: createRevisionHistoryFetch('textarea#tinymceai-multi-editor-groups-adoption-challenges'),
tinymceai_group: 'article-analysis',
tinymceai_document_name: 'Adoption challenges',
tinymceai_document_description: 'The closing section on adoption challenges. Two short paragraphs.'
});
Loading
Loading