Skip to content

Posting-4: Added third-party plugins#139

Open
mlv-dev wants to merge 1 commit intoposting.finalfrom
posting-4.plugins
Open

Posting-4: Added third-party plugins#139
mlv-dev wants to merge 1 commit intoposting.finalfrom
posting-4.plugins

Conversation

@mlv-dev
Copy link
Copy Markdown
Collaborator

@mlv-dev mlv-dev commented Aug 27, 2025

Summary by CodeRabbit

  • New Features

    • Emoji picker with autocomplete and UI styling; added extensive language support.
    • Automatic link creation while typing and on paste.
    • Auto-growing editor height with configurable limits.
    • Improved Google Docs paste handling with dedicated cleanup.
    • “Select All” context menu translations across many locales.
  • Documentation

    • Added samples demonstrating Emoji and AutoGrow usage.
  • Chores

    • Updated repository attributes to mark vendored plugin code.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 27, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Introduces multiple CKEditor 4 plugins and assets: ajax, autocomplete (with skin), autogrow (with sample), autolink, emoji (plugin, skin, sample, languages), floating panel stack (panel, floatpanel, panelbutton), Google Docs paste filter and handler, and numerous select-all context menu translations. Also updates .gitattributes to mark most CKEditor plugins as vendored, excluding tweet-splitter.

Changes

Cohort / File(s) Summary
Repo metadata
.gitattributes
Marks static/ckeditor/ckeditor/plugins/** as linguist-vendored except .../tweet-splitter/**.
AJAX utility plugin
static/ckeditor/ckeditor/plugins/ajax/plugin.js
Adds CKEDITOR.ajax singleton with GET/POST helpers, sync/async loading, and convenience loaders; registers ajax plugin.
Autocomplete plugin + skin
.../plugins/autocomplete/plugin.js, .../plugins/autocomplete/skins/default.css
Adds autocomplete framework (model/view/controller), keyboard navigation, templates, ARIA, and default skin CSS.
Autogrow plugin + sample
.../plugins/autogrow/plugin.js, .../plugins/autogrow/samples/autogrow.html
Adds auto-resizing for iframe editors with command, events, config, and demo sample page.
Autolink plugin
.../plugins/autolink/plugin.js
Adds URL/email auto-linking on paste/keystrokes with configurable regexes and commit keystrokes.
Emoji plugin core + UI assets
.../plugins/emoji/plugin.js, .../plugins/emoji/skins/default.css, .../plugins/emoji/samples/emoji.html
Adds emoji picker and colon-triggered autocomplete, config options, UI skin, and sample page.
Emoji languages
.../plugins/emoji/lang/*
Adds multiple locale files for emoji plugin (cs, da, de, de-ch, el, en, en-au, et, fa, fr, gl, hr, hu, it, nl, pl, pt-br, sk, sr, sr-latn, sv, tr, uk, zh, zh-cn).
Panel infrastructure
.../plugins/panel/plugin.js, .../plugins/floatpanel/plugin.js, .../plugins/panelbutton/plugin.js
Adds base panel (panel), floating panel (floatpanel), and toolbar-integrated panel button (panelbutton) with UI classes and behaviors.
Paste from Google Docs
.../plugins/pastefromgdocs/plugin.js, .../plugins/pastefromgdocs/filter/default.js
Adds GDocs paste detection and filter pipeline, including style/list/table normalization and filter registration.
Select All context menu languages
.../plugins/selectallcontextmenu/lang/*
Adds numerous locale files for select-all toolbar/context menu label (af, ar, bg, bn, bs, ca, cs, cy, da, de, de-ch, el, en, en-au, en-ca, en-gb, eo, es, et, eu, fa, fi, fo, fr, fr-ca, gl, gu, he, hi, hr, hu, id, is, it, ja, ka, km, ko, ku, lt, lv, mk, mn, ms, nb, nl, no, pl, pt, pt-br, ro, ru, si, sk, sl, sq, sr, sr-latn, sv, th, tr, tt, ug, uk, vi, zh, zh-cn).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Editor
  participant PanelButton as UI PanelButton
  participant FloatPanel as ui.floatPanel
  participant Block as panel.block

  User->>Editor: Click toolbar button
  Editor->>PanelButton: onClick
  PanelButton->>FloatPanel: create/showBlock(...)
  FloatPanel->>Block: render + focus
  Note over FloatPanel,Block: Handles positioning, ARIA, blur/focus
  User->>FloatPanel: Interact/Select
  FloatPanel-->>PanelButton: onHide/onEscape
  PanelButton-->>Editor: restore focus/state
Loading
sequenceDiagram
  autonumber
  actor User
  participant Editor
  participant PasteTools as pasteTools
  participant GDocsPlugin as pastefromgdocs
  participant GDocsFilter as pasteFilters.gdocs

  User->>Editor: Paste (Ctrl+V)
  Editor->>PasteTools: paste event
  PasteTools->>GDocsPlugin: canHandle(html)
  alt Matches GDocs GUID
    GDocsPlugin->>GDocsFilter: transform(html)
    GDocsFilter-->>GDocsPlugin: cleaned HTML
    GDocsPlugin->>PasteTools: set dataValue (html)
  else Not GDocs
    PasteTools-->>Editor: continue default
  end
  PasteTools-->>Editor: insert content
Loading
sequenceDiagram
  autonumber
  actor User
  participant Editor
  participant Autocomplete as plugins.autocomplete
  participant Model
  participant View

  User->>Editor: Type ":" + query
  Editor->>Autocomplete: textWatcher trigger
  Autocomplete->>Model: setQuery(query, range)
  Model-->>Autocomplete: results (via dataCallback)
  Autocomplete->>View: render dropdown
  User->>View: Navigate/Commit
  View-->>Autocomplete: selected item
  Autocomplete->>Editor: insert HTML/text
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch posting-4.plugins

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@mlv-dev mlv-dev force-pushed the posting-4.plugins branch from a5c18d8 to 131a9d4 Compare August 27, 2025 15:49
@mlv-dev mlv-dev changed the base branch from master to posting.final August 27, 2025 15:51
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 28

♻️ Duplicate comments (6)
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/fo.js (1)

5-7: Same verification applies as in et.js.

Please include 'fo' in the plugin’s lang: list and check for duplicates as per the previous script.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/eo.js (1)

5-7: Same verification applies as in et.js.

Ensure 'eo' is present in the plugin’s lang: list; duplicate check recommended.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/gl.js (1)

5-7: Same verification applies as in et.js.

Confirm 'gl' is included in the plugin’s lang: list and check for duplicates.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/sv.js (1)

5-7: Same mapping concern as zh.js.
setLang targets 'selectall' while file lives under selectallcontextmenu. Please confirm.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/sk.js (1)

5-7: Same mapping concern as zh.js.
Verify plugin id alignment.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/fi.js (1)

5-7: Same mapping concern as zh.js.
Confirm that 'selectall' bundle is the intended source for context menu text.

🧹 Nitpick comments (56)
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ku.js (1)

5-7: Confirm plugin key: 'selectall' vs. 'selectallcontextmenu'.

This file lives under selectallcontextmenu but registers strings for selectall. If the plugin code reads editor.lang.selectall.toolbar intentionally, fine. If it expects editor.lang.selectallcontextmenu.*, these strings won’t load—switch the key.

-CKEDITOR.plugins.setLang( 'selectall', 'ku', {
+CKEDITOR.plugins.setLang( 'selectallcontextmenu', 'ku', {
 	toolbar: 'دیاریکردنی هەمووی'
 } );
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/km.js (1)

7-7: Tiny nit: add trailing newline

Add a newline at EOF to satisfy common linters and keep diffs cleaner.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/hi.js (1)

6-6: Hindi string likely non-standard; prefer a clearer translation.

Current text mixes Marathi diacritics (“ॅ”). Suggest replacing with standard Hindi:

-	toolbar: 'सब सॅलॅक्ट करें'
+	toolbar: 'सभी चुनें'

Alternative (more formal): 'सभी का चयन करें'.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/gu.js (1)

7-7: Add trailing newline at EOF.

Minor POSIX/style nit; avoids noisy diffs.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ja.js (1)

1-4: License header OK for CKEditor vendored assets.

Header matches CKEditor 4 conventions. No action unless your policy requires normalizing to https in the URL (optional).

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ms.js (1)

2-3: Nit: use HTTPS in the license URL.

-For licensing, see LICENSE.md or http://ckeditor.com/license
+For licensing, see LICENSE.md or https://ckeditor.com/license
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/uk.js (1)

2-3: Nit: switch license URL to HTTPS.

-For licensing, see LICENSE.md or http://ckeditor.com/license
+For licensing, see LICENSE.md or https://ckeditor.com/license
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/lv.js (1)

2-3: Nit: use HTTPS in the license URL.

-For licensing, see LICENSE.md or http://ckeditor.com/license
+For licensing, see LICENSE.md or https://ckeditor.com/license
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/si.js (1)

6-6: Trim trailing whitespace in the label.

There’s a trailing space in the Sinhala string which may render visibly in some UIs.

-	toolbar: 'සියල්ලම '
+	toolbar: 'සියල්ලම'
static/ckeditor/ckeditor/plugins/autocomplete/skins/default.css (2)

6-22: Consider setting a stacking context (z-index) for the panel to avoid being hidden behind editor chrome.

Autocomplete popovers often need an explicit z-index to appear above the editable area, toolbar, and dialogs.

Apply:

 .cke_autocomplete_panel
 {
 	position: absolute;
 	display: none;
 	box-sizing: border-box;
 	width: 200px;
 	max-height: 300px;
 	overflow: auto;
 	padding: 0;
 	margin: 0;
 	list-style: none;
 	background: #FFF;
 	border: 1px solid #b6b6b6;
 	border-bottom-color: #999;
 	border-radius: 3px;
 	font: 12px Arial, Helvetica, Tahoma, Verdana, Sans-Serif;
+	z-index: 10000; /* keep above editor chrome; tune if your theme uses higher layers */
 }

Verification: open a long document, scroll so the editor is near other positioned elements and confirm the suggestions are never occluded.


27-38: Add keyboard focus styles for accessibility.

Currently only hover/selected states are styled; focus indication is missing for keyboard users.

Append:

 .cke_autocomplete_panel > li:hover
 {
 	cursor: pointer;
 }
 .cke_autocomplete_selected, .cke_autocomplete_panel > li:hover
 {
 	background-color: #EFF0EF;
 }
+
+/* Visible focus for keyboard navigation */
+.cke_autocomplete_panel > li:focus,
+.cke_autocomplete_panel > li:focus-visible {
+	outline: 2px solid #2684FF;
+	outline-offset: -2px;
+}
static/ckeditor/ckeditor/plugins/emoji/lang/tr.js (1)

6-18: Minor copy tweaks for consistency (ellipsis, optional diacritic).

Optional: align placeholder with other locales using the ellipsis character; consider “mekânlar” (with circumflex) if your style guide prefers it.

-	searchPlaceholder: 'Emoji ara...',
+	searchPlaceholder: 'Emoji ara…',
@@
-		travel: 'Seyahat ve mekanlar',
+		travel: 'Seyahat ve mekânlar',
static/ckeditor/ckeditor/plugins/emoji/lang/nl.js (1)

6-20: Dutch compound noun: use “Emoji-lijst”.

Small language polish; hyphenated compound is more idiomatic.

-	title: 'Emoji Lijst',
+	title: 'Emoji-lijst',
static/ckeditor/ckeditor/plugins/emoji/lang/zh-cn.js (2)

7-8: Localize the remaining English strings (searchLabel, navigationLabel).

Replace placeholders with Chinese to avoid mixed-language UI.

-	searchLabel: 'Input field responsible for searching and filtering emoji inside panel.', // MISSING
-	navigationLabel: 'Groups navigation for emoji sections.', // MISSING
+	searchLabel: '用于在面板中搜索和筛选表情的输入框。',
+	navigationLabel: '表情分组导航。'

9-9: Nit: Prefer 更常见的用语“列表”。

“表情列表”更贴近常见 UI 术语;可读性更好。

-	title: '表情清单',
+	title: '表情列表',
static/ckeditor/ckeditor/plugins/emoji/lang/de.js (1)

7-8: Translate missing German labels.

Provide native strings to match the rest of the locale.

-	searchLabel: 'Input field responsible for searching and filtering emoji inside panel.', // MISSING
-	navigationLabel: 'Groups navigation for emoji sections.', // MISSING
+	searchLabel: 'Eingabefeld zum Suchen und Filtern von Emojis im Panel.',
+	navigationLabel: 'Navigation für Emoji-Gruppen.',
static/ckeditor/ckeditor/plugins/emoji/lang/fr.js (1)

6-9: Fix FR grammar, gender, and UI phrasing.

Use “Rechercher…”, correct gender/plurals, and streamline labels.

-	searchPlaceholder: 'Chercher un émoticône',
-	searchLabel: 'Champ de saisie chargé de rechercher et de filtrer les émoticônes à l\'intérieur du panneau',
-	navigationLabel: 'Catégorisation des sections d\'émoticône',
+	searchPlaceholder: 'Rechercher des émoticônes…',
+	searchLabel: 'Champ de saisie permettant de rechercher et de filtrer les émoticônes dans le panneau.',
+	navigationLabel: 'Navigation des sections d\'émoticônes.',
-		nature: 'Nature et animal',
-		travel: 'Lieu et voyage',
+		nature: 'Nature et animaux',
+		travel: 'Lieux et voyages',

Also applies to: 12-15

static/ckeditor/ckeditor/plugins/ajax/plugin.js (4)

118-118: Header casing

Use the canonical Content-Type.

-			xhr.setRequestHeader( 'Content-type', contentType || 'application/x-www-form-urlencoded; charset=UTF-8' );
+			xhr.setRequestHeader( 'Content-Type', contentType || 'application/x-www-form-urlencoded; charset=UTF-8' );

87-94: Clean up XHR handler to reduce leak risk in legacy browsers

Null the handler before releasing the reference.

-				xhr.onreadystatechange = function() {
+				xhr.onreadystatechange = function() {
 					if ( xhr.readyState == 4 ) {
-						callback( getResponse( xhr, responseType ) );
-						xhr = null;
+						var res = getResponse( xhr, responseType );
+						this.onreadystatechange = null; // prevent leaks in old IEs
+						callback( res );
+						xhr = null;
 					}
 				};

44-52: Status 0 handling can misclassify failures

status === 0 is treated as success (OK for file:), but it also occurs on CORS/network failures. Consider gating it by location.protocol === 'file:'.

Would you like me to propose a small guard that only treats 0 as success for file: URLs?


72-99: Synchronous XHR path

Sync XHR blocks the main thread and is restricted by browsers. Prefer async usage; if sync is required, document constraints and avoid in UI-critical paths.

static/ckeditor/ckeditor/plugins/autogrow/plugin.js (1)

16-25: Unreachable inline branch or unintended early return

init returns for ELEMENT_MODE_INLINE, so the subsequent inline handling in instanceReady never runs. Decide whether inline editors should get height:auto or the branch should be removed.

Option A (support inline; remove early return):

-			if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE )
-				return;

Option B (no inline support; remove dead branch):

-				// Simply set auto height with div wysiwyg.
-				if ( editor.editable().isInline() )
-					editor.ui.space( 'contents' ).setStyle( 'height', 'auto' );
-				// For classic (`iframe`-based) wysiwyg we need to resize the editor.
-				else
-					initIframeAutogrow( editor );
+				initIframeAutogrow( editor );

Do you want inline editors to auto-size?

static/ckeditor/ckeditor/plugins/autogrow/samples/autogrow.html (2)

1-124: Do not serve samples in production

These demo pages expand the public attack surface and bloat static assets. Exclude plugins/**/samples/** from production builds or blocklist them at the web server.


66-91: Nonstandard plugins config may confuse

plugins: [ ... ] is not a typical runtime config; extraPlugins is. Consider removing this from the sample or adding a clarifying comment.

-				CKEDITOR.replace( 'editor1', {
-					plugins: [
+				CKEDITOR.replace( 'editor1', {
+					// Note: 'plugins' below is used only for the sample showcase; not a typical runtime config.
 					'wysiwygarea',
static/ckeditor/ckeditor/plugins/autolink/plugin.js (1)

23-39: Paste handler: defensive check

evt.data.dataTransfer can be falsy in some paste sources. Guard before calling getTransferType(...).

-				if ( evt.data.dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_INTERNAL ) {
+				if ( evt.data.dataTransfer && evt.data.dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_INTERNAL ) {
 					return;
 				}
static/ckeditor/ckeditor/plugins/autocomplete/plugin.js (5)

200-202: Don’t overwrite model.itemsLimit with undefined.

Only assign when provided to preserve the model’s default (0 = unlimited).

Apply:

-		this.model = this.getModel( config.dataCallback );
-		this.model.itemsLimit = config.itemsLimit;
+		this.model = this.getModel( config.dataCallback );
+		if ( typeof config.itemsLimit !== 'undefined' ) {
+			this.model.itemsLimit = config.itemsLimit;
+		}

268-322: Track the contentDom listener for clean teardown.

If the instance is destroyed manually (not only on editor destroy), the contentDom listener won’t be removed. Push it to _listeners like others for symmetry.

Apply:

-			editor.on( 'contentDom', function() {
-				this.registerPanelNavigation();
-				this.addAriaAttributesToEditable();
-			}, this );
+			var contentDomListener = editor.on( 'contentDom', function() {
+				this.registerPanelNavigation();
+				this.addAriaAttributesToEditable();
+			}, this );
+			this._listeners.push( contentDomListener );

620-628: Guard against null selectedItem.

If the item node is not found (edge timing), getAttribute on null will throw. Add a null check.

Apply:

-			this.updateAriaActiveDescendantAttributeOnEditable( selectedItem.getAttribute( 'id' ) );
+			if ( selectedItem ) {
+				this.updateAriaActiveDescendantAttributeOnEditable( selectedItem.getAttribute( 'id' ) );
+			}

1424-1455: Defensive handling of dataCallback results.

data.slice assumes an array. Coerce to an array to avoid runtime errors from misbehaving providers.

Apply:

-			function handleData( data ) {
+			function handleData( data ) {
+				data = CKEDITOR.tools.array.isArray( data ) ? data : [];
 				// Handle only the response for the most recent setQuery call.
 				if ( requestId == that.lastRequestId ) {

457-466: Detach watcher on destroy (if supported).

For completeness, detach the textWatcher when tearing down to avoid stale handlers.

Apply:

 		destroy: function() {
 			CKEDITOR.tools.array.forEach( this._listeners, function( obj ) {
 				obj.removeListener();
 			} );

 			this._listeners = [];
-
+			if ( this.textWatcher && typeof this.textWatcher.detach == 'function' ) {
+				this.textWatcher.detach();
+			}
 			this.view.element && this.view.element.remove();
 			this.removeAriaAttributesFromEditable();
 		},
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/da.js (1)

1-7: Optional: add trailing newline at EOF to align with common style.

Minor formatting nit; safe to skip if mirroring upstream vendor files.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/pt-br.js (1)

6-6: Nit: prefer sentence case for pt-BR ('Selecionar tudo').

Matches common UI style and upstream phrasing.

-	toolbar: 'Selecionar Tudo'
+	toolbar: 'Selecionar tudo'
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/fa.js (1)

6-6: Consider using the more common Persian phrasing 'انتخاب همه'.

This is widely used in Persian UIs; please confirm with your localization source.

-	toolbar: 'گزینش همه'
+	toolbar: 'انتخاب همه'
static/ckeditor/ckeditor/plugins/emoji/lang/gl.js (1)

12-12: Possible typo in Galician string: "aimais" vs "animais"

Please confirm spelling for nature group. If it’s a typo, apply:

-		nature: 'Natureza e aimais',
+		nature: 'Natureza e animais',
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/hr.js (1)

5-7: Verify plugin key: setLang targets 'selectall' from inside 'selectallcontextmenu'

If intentional (vendored upstream using 'selectall' strings for the context menu), keep as-is. If not, either:

  • move this file under plugins/selectall/lang, or
  • change the key to 'selectallcontextmenu' and ensure the plugin reads it.

Provide confirmation before altering vendored code.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/fr.js (1)

5-7: Same key mismatch check as hr.js

setLang('selectall', ...) inside selectallcontextmenu. Confirm intent vs. relocation/renaming as noted in hr.js comment.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/en.js (1)

5-7: Confirm language key alignment with plugin

As with other locales, ensure 'selectall' is the intended target key for strings delivered by selectallcontextmenu. If not, relocate or update the key.

static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ar.js (1)

5-7: Confirm target plugin key; also verify RTL rendering

  • Verify 'selectall' vs 'selectallcontextmenu' key as in other files.
  • Quick manual check in an RTL locale build to ensure the string displays correctly in context menus.
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/zh.js (1)

5-7: Optional: verify locale fallback behavior.
Since both zh (Traditional) and zh-cn exist, confirm your CKEditor language config resolves as intended for users in different Chinese locales.

static/ckeditor/ckeditor/plugins/emoji/skins/default.css (5)

10-11: Reorder font-family fallbacks.
Place the generic family last so specific fonts are tried first.

-	font-family: sans-serif, Arial, Verdana, "Trebuchet MS", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+	font-family: Arial, Verdana, "Trebuchet MS", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif;

14-15: Add Linux/Android emoji fallback.
Include "Noto Color Emoji" for broader coverage.

-	font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+	font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";

Also applies to: 165-166, 210-211


124-136: Add unprefixed appearance for modern browsers.
Keeps Safari fix while covering others.

 .cke_emoji-search input {
-	-webkit-appearance: none;
+	-webkit-appearance: none;
+	appearance: none;
 	border: none;

141-150: Improve mobile scrolling.
Smooths scrolling on iOS.

 .cke_emoji-outer_emoji_block {
 	height: 180px;
 	overflow-x: hidden;
 	overflow-y: auto;
+	-webkit-overflow-scrolling: touch;

235-237: Enhance focus visibility.
Avoids focus outline being clipped.

 .cke_emoji-inner_panel a:focus, .cke_emoji-inner_panel input:focus {
 	outline: 2px solid #139FF7;
+	outline-offset: 2px;
 }
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/de-ch.js (1)

5-7: Same potential plugin key mismatch as af.js

Lang file is under selectallcontextmenu but sets 'selectall'. Align or confirm intended cross-plugin reuse.

-CKEDITOR.plugins.setLang( 'selectall', 'de-ch', {
+CKEDITOR.plugins.setLang( 'selectallcontextmenu', 'de-ch', {
static/ckeditor/ckeditor/plugins/emoji/lang/fa.js (1)

7-8: Complete missing Persian translations; fix minor typography

Replace English placeholders and use ZWNJ in “فعالیت‌ها” for consistency.

-	searchLabel: 'Input field responsible for searching and filtering emoji inside panel.', // MISSING
-	navigationLabel: 'Groups navigation for emoji sections.', // MISSING
+	searchLabel: 'فیلد ورودی برای جست‌وجو و فیلتر کردن ایموجی‌ها در پنل.',
+	navigationLabel: 'ناوبری گروه‌ها برای بخش‌های ایموجی.',
@@
-		activities: 'فعالیت ها',
+		activities: 'فعالیت‌ها',

Also applies to: 15-15

static/ckeditor/ckeditor/plugins/emoji/lang/sr-latn.js (1)

6-6: Optional: use typographic ellipsis for consistency (… instead of ...).

Many locales in this set use a single ellipsis character.

-	searchPlaceholder: 'Traži emoji...',
+	searchPlaceholder: 'Traži emoji…',
static/ckeditor/ckeditor/plugins/pastefromgdocs/plugin.js (1)

1-1: Remove BOM (byte order mark).

The file starts with a BOM (before /**). Some build/packaging tools and diffs dislike it.

static/ckeditor/ckeditor/plugins/emoji/lang/sv.js (2)

7-9: Provide Swedish translations instead of placeholders.

Replace English strings and remove the “// MISSING” markers.

-	searchLabel: 'Input field responsible for searching and filtering emoji inside panel.', // MISSING
-	navigationLabel: 'Groups navigation for emoji sections.', // MISSING
+	searchLabel: 'Inmatningsfält för att söka och filtrera emojis i panelen.',
+	navigationLabel: 'Navigering mellan emoji-grupper.',

6-6: Optional: use typographic ellipsis for consistency.

-	searchPlaceholder: 'Sök emoji...',
+	searchPlaceholder: 'Sök emoji…',
static/ckeditor/ckeditor/plugins/pastefromgdocs/filter/default.js (2)

52-55: Trim class attribute after removing gdocs-specific tokens.

Prevent leftover whitespace-only class values.

-					'class': function( classes ) {
-						return falseIfEmpty( classes.replace( /kix-line-break/ig, '' ) );
-					}
+					'class': function( classes ) {
+						var cleaned = classes
+							.replace( /kix-line-break/ig, '' )
+							.replace( /\s{2,}/g, ' ' )
+							.trim();
+						return falseIfEmpty( cleaned );
+					}

167-220: Make colgroup width propagation resilient to missing/invalid widths.

Avoid NaN propagation and only set widths when valid.

-		table.attributes.width = overallWidth;
+		if ( isFinite( overallWidth ) && overallWidth > 0 ) {
+			table.attributes.width = overallWidth;
+		}
 		addWidthToCells( getFirstRow( table ), colsWidths );
@@
-		function getWidths( cols ) {
-			return CKEDITOR.tools.array.map( cols, function( col ) {
-				return Number( col.attributes.width );
-			} );
-		}
+		function getWidths( cols ) {
+			return CKEDITOR.tools.array.map( cols, function( col ) {
+				var w = parseInt( col.attributes.width, 10 );
+				return isFinite( w ) ? w : 0;
+			} );
+		}
@@
-		function addWidthToCells( row, widths ) {
+		function addWidthToCells( row, widths ) {
@@
-			for ( i = 0; i < widths.length; i++ ) {
-				if ( !cells[ i ] ) {
-					break;
-				}
-				cells[ i ].attributes.width = widths[ i ];
-			}
+			for ( i = 0; i < widths.length; i++ ) {
+				if ( !cells[ i ] ) break;
+				if ( isFinite( widths[ i ] ) && widths[ i ] > 0 ) {
+					cells[ i ].attributes.width = widths[ i ];
+				}
+			}
static/ckeditor/ckeditor/plugins/emoji/plugin.js (2)

296-299: Graceful i18n fallback for missing labels.

Some locales have missing keys; ensure a sensible fallback to avoid aria-label="undefined".

-						'<input placeholder="' + htmlEncode( this.lang.searchPlaceholder ) +
-						'" type="search" aria-label="' + htmlEncode( this.lang.searchLabel ) + '" role="search" _cke_focus="1"></label>';
+						'<input placeholder="' + htmlEncode( this.lang.searchPlaceholder || this.lang.title || 'Search emojis' ) +
+						'" type="search" aria-label="' + htmlEncode( this.lang.searchLabel || this.lang.title || 'Search emojis' ) + '" role="search" _cke_focus="1"></label>';

107-109: Remove stray TODO-like note.

“Below line might be removable” is ambiguous. Either remove the line or the comment to avoid confusion.

-				// Below line might be removable
 				editor.ui.addToolbarGroup( 'emoji', 'insert' );
static/ckeditor/ckeditor/plugins/panel/plugin.js (1)

67-71: Duplicate CSS class in panel template.

cke_panel appears twice.

-	var panelTpl = CKEDITOR.addTemplate( 'panel', '<div lang="{langCode}" id="{id}" dir={dir}' +
-		' class="cke cke_reset_all {editorId} cke_panel cke_panel {cls} cke_{dir}"' +
+	var panelTpl = CKEDITOR.addTemplate( 'panel', '<div lang="{langCode}" id="{id}" dir={dir}' +
+		' class="cke cke_reset_all {editorId} cke_panel {cls} cke_{dir}"' +
 		' style="z-index:{z-index}" role="presentation">' +
 		'{frame}' +
 		'</div>' );
static/ckeditor/ckeditor/plugins/panelbutton/plugin.js (1)

81-83: Use the same document context for the button element.

Avoid mixing CKEDITOR.document with this.document (which already respects custom parents).

-						buttonElement = CKEDITOR.document.getById( this._.id ),
+						buttonElement = this.document.getById( this._.id ),
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between cb7a71d and 131a9d4.

⛔ Files ignored due to path filters (6)
  • static/ckeditor/ckeditor/plugins/emoji/assets/iconsall.png is excluded by !**/*.png
  • static/ckeditor/ckeditor/plugins/emoji/assets/iconsall.svg is excluded by !**/*.svg
  • static/ckeditor/ckeditor/plugins/emoji/icons/emojipanel.png is excluded by !**/*.png
  • static/ckeditor/ckeditor/plugins/emoji/icons/hidpi/emojipanel.png is excluded by !**/*.png
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/icons/hidpi/selectall.png is excluded by !**/*.png
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/icons/selectall.png is excluded by !**/*.png
📒 Files selected for processing (107)
  • .gitattributes (1 hunks)
  • static/ckeditor/ckeditor/plugins/ajax/plugin.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/autocomplete/plugin.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/autocomplete/skins/default.css (1 hunks)
  • static/ckeditor/ckeditor/plugins/autogrow/plugin.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/autogrow/samples/autogrow.html (1 hunks)
  • static/ckeditor/ckeditor/plugins/autolink/plugin.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/cs.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/da.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/de-ch.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/de.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/el.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/en-au.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/en.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/et.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/fa.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/fr.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/gl.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/hr.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/hu.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/it.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/nl.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/pl.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/pt-br.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/sk.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/sr-latn.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/sr.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/sv.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/tr.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/uk.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/zh-cn.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/lang/zh.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/plugin.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/samples/emoji.html (1 hunks)
  • static/ckeditor/ckeditor/plugins/emoji/skins/default.css (1 hunks)
  • static/ckeditor/ckeditor/plugins/floatpanel/plugin.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/panel/plugin.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/panelbutton/plugin.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/pastefromgdocs/filter/default.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/pastefromgdocs/plugin.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/af.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ar.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/bg.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/bn.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/bs.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ca.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/cs.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/cy.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/da.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/de-ch.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/de.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/el.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/en-au.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/en-ca.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/en-gb.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/en.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/eo.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/es.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/et.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/eu.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/fa.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/fi.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/fo.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/fr-ca.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/fr.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/gl.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/gu.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/he.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/hi.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/hr.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/hu.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/id.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/is.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/it.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ja.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ka.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/km.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ko.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ku.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/lt.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/lv.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/mk.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/mn.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ms.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/nb.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/nl.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/no.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/pl.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/pt-br.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/pt.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ro.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ru.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/si.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/sk.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/sl.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/sq.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/sr-latn.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/sr.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/sv.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/th.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/tr.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/tt.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ug.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/uk.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/vi.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/zh-cn.js (1 hunks)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/zh.js (1 hunks)
⛔ Files not processed due to max files limit (3)
  • static/ckeditor/ckeditor/plugins/selectallcontextmenu/plugin.js
  • static/ckeditor/ckeditor/plugins/textmatch/plugin.js
  • static/ckeditor/ckeditor/plugins/textwatcher/plugin.js
🧰 Additional context used
🪛 Biome (2.1.2)
static/ckeditor/ckeditor/plugins/ajax/plugin.js

[error] 63-63: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

static/ckeditor/ckeditor/plugins/panel/plugin.js

[error] 390-392: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

Comment thread .gitattributes Outdated
static/ckeditor/ckeditor/plugins/** linguist-vendored

# Отменить правило для плагина кастомного плагина
static/ckeditor/ckeditor/plugins/tweet-splitter/** !linguist-vendored
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Fix Linguist negation syntax (use =false or leading dash).

In .gitattributes, attributes are unset with -attr or attr=false, not !attr. As written, the tweet-splitter exception won’t take effect.

Apply:

-static/ckeditor/ckeditor/plugins/tweet-splitter/** !linguist-vendored
+static/ckeditor/ckeditor/plugins/tweet-splitter/** linguist-vendored=false

Run to verify attributes resolve as intended:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# One vendored plugin file (not tweet-splitter)
vendored_file="$(fd -t f 'plugin.js' static/ckeditor/ckeditor/plugins | rg -v 'tweet-splitter' | head -n1)"
echo "Checking vendored attr on: $vendored_file"
git check-attr linguist-vendored -- "$vendored_file"

# One tweet-splitter file
ts_file="$(fd -t f . static/ckeditor/ckeditor/plugins/tweet-splitter | head -n1 || true)"
if [[ -n "${ts_file:-}" ]]; then
  echo "Checking vendored attr on: $ts_file"
  git check-attr linguist-vendored -- "$ts_file"
else
  echo "tweet-splitter files not found; verify path."
fi

Length of output: 830


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching for tweet-splitter references in static directory"
rg -n "tweet-splitter" -C2 static || true

echo "Searching for tweet-splitter directory anywhere"
fd -t d tweet-splitter || true

Length of output: 319


Fix .gitattributes rule for tweet-splitter plugin

The tweet-splitter entry in .gitattributes is neither matching any files (the directory doesn’t exist) nor using valid negation syntax (!linguist-vendored). As a result, Linguist will never treat those files as non-vendored.

Please address the following critical issues:

  • The path static/ckeditor/ckeditor/plugins/tweet-splitter/ doesn’t exist in the repo; no files are being matched.
  • Negation via !linguist-vendored is invalid. Use linguist-vendored=false (or a leading dash: -linguist-vendored) instead.

Actions:

• Confirm the correct plugin location (for example, it may live under static/ckeditor/plugins/tweet-splitter/ or another path) and update the pattern accordingly.
• Replace the negation syntax with a supported form.

Suggested diff if the path is correct:

-static/ckeditor/ckeditor/plugins/tweet-splitter/** !linguist-vendored
+static/ckeditor/ckeditor/plugins/tweet-splitter/** linguist-vendored=false

—or, if the plugin folder has moved——

-static/ckeditor/ckeditor/plugins/tweet-splitter/** !linguist-vendored
+static/ckeditor/plugins/tweet-splitter/** linguist-vendored=false

If the tweet-splitter plugin is no longer part of the codebase, simply remove the stale line:

-static/ckeditor/ckeditor/plugins/tweet-splitter/** !linguist-vendored
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
static/ckeditor/ckeditor/plugins/tweet-splitter/** !linguist-vendored
static/ckeditor/ckeditor/plugins/tweet-splitter/** linguist-vendored=false
🤖 Prompt for AI Agents
In .gitattributes around line 5, the entry
"static/ckeditor/ckeditor/plugins/tweet-splitter/** !linguist-vendored" is
stale/invalid: verify whether the plugin actually lives under
static/ckeditor/plugins/tweet-splitter/ (or another correct path) and update the
glob to that path, and replace the invalid negation with a supported form (e.g.
append " linguist-vendored=false" or use "-linguist-vendored") so Linguist
treats the files as non-vendored; if the plugin folder no longer exists in the
repo, simply remove this line.

Comment on lines +59 to +66
switch ( type ) {
case 'text':
return xhr.responseText;
case 'xml':
var xml = xhr.responseXML;
return new CKEDITOR.xml( xml && xml.firstChild ? xml : xhr.responseText );
case 'arraybuffer':
return xhr.response;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix switch-case declaration scope (lint: noSwitchDeclarations)

Wrap the case 'xml' declarations in a block to avoid leaking xml into other cases.

-				case 'xml':
-					var xml = xhr.responseXML;
-					return new CKEDITOR.xml( xml && xml.firstChild ? xml : xhr.responseText );
+				case 'xml': {
+					var xml = xhr.responseXML;
+					return new CKEDITOR.xml( xml && xml.firstChild ? xml : xhr.responseText );
+				}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
switch ( type ) {
case 'text':
return xhr.responseText;
case 'xml':
var xml = xhr.responseXML;
return new CKEDITOR.xml( xml && xml.firstChild ? xml : xhr.responseText );
case 'arraybuffer':
return xhr.response;
switch ( type ) {
case 'text':
return xhr.responseText;
case 'xml': {
var xml = xhr.responseXML;
return new CKEDITOR.xml( xml && xml.firstChild ? xml : xhr.responseText );
}
case 'arraybuffer':
return xhr.response;
🧰 Tools
🪛 Biome (2.1.2)

[error] 63-63: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

🤖 Prompt for AI Agents
In static/ckeditor/ckeditor/plugins/ajax/plugin.js around lines 59 to 66, the
variable declared in the case 'xml' branch leaks into other switch cases; wrap
the case body in a block scope and use a block-scoped variable (let/const) for
xml, e.g. open a { } block for case 'xml', declare xml with let/const inside it
and return from that block so the xml identifier does not leak to other cases.

Comment on lines +47 to +51
var matched = CKEDITOR.plugins.textMatch.match( editor.getSelection().getRanges()[ 0 ], matchCallback );

if ( matched ) {
insertLink( matched );
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Guard against missing selection/range

getRanges()[0] may be undefined; prevent runtime errors.

-				var matched = CKEDITOR.plugins.textMatch.match( editor.getSelection().getRanges()[ 0 ], matchCallback );
+				var ranges = editor.getSelection().getRanges();
+				if ( !ranges || !ranges.length ) {
+					return;
+				}
+				var matched = CKEDITOR.plugins.textMatch.match( ranges[ 0 ], matchCallback );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var matched = CKEDITOR.plugins.textMatch.match( editor.getSelection().getRanges()[ 0 ], matchCallback );
if ( matched ) {
insertLink( matched );
}
var ranges = editor.getSelection().getRanges();
if ( !ranges || !ranges.length ) {
return;
}
var matched = CKEDITOR.plugins.textMatch.match( ranges[ 0 ], matchCallback );
if ( matched ) {
insertLink( matched );
}
🤖 Prompt for AI Agents
In static/ckeditor/ckeditor/plugins/autolink/plugin.js around lines 47 to 51,
the code assumes editor.getSelection().getRanges()[0] exists which can be
undefined and cause runtime errors; guard by checking that editor.getSelection()
is non-null and that getRanges() returns a non-empty array (or a truthy first
element) before passing the range to CKEDITOR.plugins.textMatch.match, and bail
out (or skip insertLink) if no valid range is present.

Comment on lines +56 to +63
var selection = editor.getSelection();
// We don't want to insert a link if selection is already inside another link.
if ( selection.getRanges()[ 0 ].startContainer.getAscendant( 'a', true ) ) {
return;
}

selection.selectRanges( [ match.range ] );
editor.insertHtml( getHtmlToInsert( match.text ), 'text' );
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Also guard inside insertLink

Ensure selection and ranges exist before access.

-				var selection = editor.getSelection();
+				var selection = editor.getSelection();
+				if ( !selection ) {
+					return;
+				}
-				// We don't want to insert a link if selection is already inside another link.
-				if ( selection.getRanges()[ 0 ].startContainer.getAscendant( 'a', true ) ) {
+				var sRanges = selection.getRanges();
+				if ( !sRanges || !sRanges.length ) {
+					return;
+				}
+				// We don't want to insert a link if selection is already inside another link.
+				if ( sRanges[ 0 ].startContainer.getAscendant( 'a', true ) ) {
 					return;
 				}
 
-				selection.selectRanges( [ match.range ] );
+				selection.selectRanges( [ match.range ] );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var selection = editor.getSelection();
// We don't want to insert a link if selection is already inside another link.
if ( selection.getRanges()[ 0 ].startContainer.getAscendant( 'a', true ) ) {
return;
}
selection.selectRanges( [ match.range ] );
editor.insertHtml( getHtmlToInsert( match.text ), 'text' );
var selection = editor.getSelection();
if ( !selection ) {
return;
}
var sRanges = selection.getRanges();
if ( !sRanges || !sRanges.length ) {
return;
}
// We don't want to insert a link if selection is already inside another link.
if ( sRanges[ 0 ].startContainer.getAscendant( 'a', true ) ) {
return;
}
selection.selectRanges( [ match.range ] );
editor.insertHtml( getHtmlToInsert( match.text ), 'text' );
🤖 Prompt for AI Agents
In static/ckeditor/ckeditor/plugins/autolink/plugin.js around lines 56 to 63,
the code accesses selection and its ranges without null/length checks which can
throw when no selection or ranges exist; add guards to verify
editor.getSelection() returns a selection and that selection.getRanges() returns
a non-empty array before referencing [0] or calling startContainer.getAscendant,
and also add the same defensive checks inside the insertLink code path so you
only call selection.selectRanges and editor.insertHtml when selection and ranges
are present; if absent, bail out early.

Comment on lines +133 to +135
* // Default configuration (13 = Enter, 32 = space).
* config.autolink_commitKeystrokes = [ 9, 13 ];
* ```
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Docs: incorrect default snippet

The snippet claims defaults [9, 13] but the actual default is [13, 32]. Fix the example.

-	 * // Default configuration (13 = Enter, 32 = space).
-	 * config.autolink_commitKeystrokes = [ 9, 13 ];
+	 * // Default configuration (13 = Enter, 32 = space).
+	 * config.autolink_commitKeystrokes = [ 13, 32 ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* // Default configuration (13 = Enter, 32 = space).
* config.autolink_commitKeystrokes = [ 9, 13 ];
* ```
* // Default configuration (13 = Enter, 32 = space).
* config.autolink_commitKeystrokes = [ 13, 32 ];
🤖 Prompt for AI Agents
In static/ckeditor/ckeditor/plugins/autolink/plugin.js around lines 133 to 135,
the documentation example shows the wrong default keystroke array ([9, 13]);
update the example to reflect the real default ([13, 32]) so the snippet and
comment match the actual default configuration; replace the incorrect values in
the doc string with the correct ones and run a quick search to ensure no other
examples still show [9, 13].

Comment on lines +1 to +4
/*
Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

❓ Verification inconclusive

License header references LICENSE.md—confirm vendored license presence

Ensure the CKEditor license file is present in the vendored subtree to satisfy attribution/compliance.

Quick check:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
fd -HI 'LICENSE*' static/ckeditor | sed -n '1,200p'

Length of output: 71


🏁 Script executed:

#!/bin/bash
set -euo pipefail
find static/ckeditor -type f -iname 'license*' -print

Length of output: 75


Add missing CKEditor LICENSE.md to vendored subtree

The vendored CKEditor directory (static/ckeditor/) contains source files with a header referencing LICENSE.md, but no such file was found. Without the license file, attribution and compliance requirements aren’t satisfied.

Please add the CKEditor license file into the vendored subtree:

  • static/ckeditor/LICENSE.md (or the original CKEditor COPYING/GPL/MIT file as appropriate)
🤖 Prompt for AI Agents
In static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/lt.js lines 1-4,
the file header references a CKEditor LICENSE.md but the vendored subtree is
missing that license; add the appropriate CKEditor license file into the
vendored subtree at static/ckeditor/LICENSE.md (or the original CKEditor
COPYING/GPL/MIT file as applicable), copy the exact license text from the
CKEditor distribution, ensure the filename and path match the header reference,
and commit the new license file alongside the vendored files so
attribution/compliance is satisfied.

Comment on lines +5 to +7
CKEDITOR.plugins.setLang( 'selectall', 'mk', {
toolbar: 'Select All' // MISSING
} );
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Plugin key mismatch: setLang should use 'selectallcontextmenu'.

Otherwise the locale won’t load for this plugin.

Apply:

-CKEDITOR.plugins.setLang( 'selectall', 'mk', {
+CKEDITOR.plugins.setLang( 'selectallcontextmenu', 'mk', {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CKEDITOR.plugins.setLang( 'selectall', 'mk', {
toolbar: 'Select All' // MISSING
} );
CKEDITOR.plugins.setLang( 'selectallcontextmenu', 'mk', {
toolbar: 'Select All' // MISSING
} );
🤖 Prompt for AI Agents
In static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/mk.js around lines
5 to 7, the CKEDITOR.plugins.setLang call uses the wrong plugin key 'selectall';
change that key to 'selectallcontextmenu' so the Macedonian locale loads for
this plugin, leaving the locale code 'mk' and the toolbar string as-is.

For licensing, see LICENSE.md or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang( 'selectall', 'mk', {
toolbar: 'Select All' // MISSING
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the label key expected by the plugin.

Confirm whether the plugin reads editor.lang.selectallcontextmenu.toolbar (vs. another key like label). If different, adjust accordingly.

Run:


🏁 Script executed:

#!/bin/bash
# Inspect plugin code and all locale files for consistency
rg -nP "plugins\\.add\\('(selectallcontextmenu)'" -C2 static | cat
rg -nP "editor\\.lang\\.selectallcontextmenu\\.(\\w+)" -C2 static | cat
rg -nP "CKEDITOR\\.plugins\\.setLang\\('\\K[^']+" static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang -o | sort -u
rg -nP "\\b(toolbar)\\s*:" static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang -n

Length of output: 7277


🏁 Script executed:

#!/bin/bash
# Verify which lang key the plugin uses for its menu item label
rg -nP "addMenuItem" -C3 static/ckeditor/ckeditor/plugins/selectallcontextmenu/plugin.js
rg -nP "editor\.lang" -C3 static/ckeditor/ckeditor/plugins/selectallcontextmenu/plugin.js

Length of output: 821


🏁 Script executed:

#!/bin/bash
# List all top-level CKEditor plugin directories
find static/ckeditor/ckeditor/plugins -maxdepth 1 -mindepth 1 -type d | sed 's#.*/plugins/##'

echo
# Check for mk.js in selectall plugin and show snippet
echo "=== selectall/lang/mk.js snippet ==="
if [ -f static/ckeditor/ckeditor/plugins/selectall/lang/mk.js ]; then
  sed -n '1,20p' static/ckeditor/ckeditor/plugins/selectall/lang/mk.js
else
  echo "selectall plugin mk.js not found"
fi

Length of output: 457


Use the correct language key for the context-menu label

The plugin’s locale files live under selectallcontextmenu and define the toolbar string there, but in plugin.js we’re currently pulling from editor.lang.selectall.toolbar, which doesn’t exist. We need to update the menu-item to use the selectallcontextmenu namespace instead.

– File: static/ckeditor/ckeditor/plugins/selectallcontextmenu/plugin.js
– Line: 59

-    label: editor.lang.selectall.toolbar,
+    label: editor.lang.selectallcontextmenu.toolbar,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
toolbar: 'Select All' // MISSING
// … other menu‐item properties …
label: editor.lang.selectallcontextmenu.toolbar,
// … remaining properties …
🤖 Prompt for AI Agents
In static/ckeditor/ckeditor/plugins/selectallcontextmenu/plugin.js around line
59, the menu-item is currently reading editor.lang.selectall.toolbar which does
not exist; change it to use the selectallcontextmenu namespace
(editor.lang.selectallcontextmenu.toolbar) so it pulls the defined toolbar
string from static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/* (e.g.,
mk.js line 6). Update the reference, run a quick smoke test of the context menu
in the editor, and ensure no other references use the wrong namespace.

Comment on lines +1 to +4
/*
Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Confirm CKEditor license presence for vendored code.

Header points to LICENSE.md; ensure static/ckeditor/ckeditor/LICENSE.md exists in the repo.


🏁 Script executed:

#!/bin/bash
test -f static/ckeditor/ckeditor/LICENSE.md && echo "OK: LICENSE.md present" || { echo "MISSING: CKEditor LICENSE.md"; exit 1; }

Length of output: 121


Add the missing CKEditor LICENSE.md file

The vendored CKEditor plugin includes a header that references static/ckeditor/ckeditor/LICENSE.md, but that file is not present in the repository. You must include CKEditor’s license to comply with its terms.

• Path missing: static/ckeditor/ckeditor/LICENSE.md
• Action: Add the official CKEditor LICENSE.md (from the same version you’re vendoring) under static/ckeditor/ckeditor/ so the header’s reference is valid.
• Verification: After adding, rerun:

test -f static/ckeditor/ckeditor/LICENSE.md && echo "OK: LICENSE.md present"
🤖 Prompt for AI Agents
In static/ckeditor/ckeditor (referenced by
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/mn.js lines 1-4), the
CKEditor header references a LICENSE.md that is not present; add the official
CKEditor LICENSE.md from the same CKEditor version you vendored into
static/ckeditor/ckeditor/LICENSE.md (copy the exact license text from the
corresponding CKEditor release), commit it alongside the vendored plugin, and
verify presence with: test -f static/ckeditor/ckeditor/LICENSE.md && echo "OK:
LICENSE.md present".

Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md or http://ckeditor.com/license
*/
CKEDITOR.plugins.setLang( 'selectall', 'no', {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Confirm plugin key: 'selectall' vs folder 'selectallcontextmenu'.

The path suggests the context-menu plugin, but setLang targets 'selectall'. If this plugin intentionally reuses the SelectAll labels, fine; otherwise the locale may not load for the intended plugin.

Run to compare keys used by sibling locale files:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the lang dir for selectallcontextmenu and show plugin keys used in setLang
dir="$(fd -a -t d 'plugins/selectallcontextmenu/lang' | head -n1 || true)"
test -n "${dir:-}" || { echo "selectallcontextmenu/lang not found"; exit 0; }

echo "Plugin keys used in ${dir}:"
rg -nP "CKEDITOR\\.plugins\\.setLang\\(\\s*'([^']+)'\\s*,\\s*'([^']+)'\\s*," -o --replace '$1 $2' "$dir" | sort -u

Length of output: 189


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Plugin directories under static/ckeditor/ckeditor/plugins:"
find static/ckeditor/ckeditor/plugins -maxdepth 1 -mindepth 1 -type d | sed 's|.*/||' | sort

Length of output: 370


Mismatch between plugin directory and locale key needs correction

The locale file lives under plugins/selectallcontextmenu/lang/no.js but is registering its labels for the selectall plugin. Since there is no selectall directory in our build, CKEditor will never load these translations for the Select All Context-Menu plugin. Please update the plugin key so it matches its folder name:

• In static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/no.js

- CKEDITOR.plugins.setLang( 'selectall', 'no', {
+ CKEDITOR.plugins.setLang( 'selectallcontextmenu', 'no', {

Make the same change in every language file under
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/
so that all translations load correctly.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CKEDITOR.plugins.setLang( 'selectall', 'no', {
// File: static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/no.js
CKEDITOR.plugins.setLang( 'selectallcontextmenu', 'no', {
// …existing translations…
});
🤖 Prompt for AI Agents
In static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/no.js around line
5, the locale file registers translations under the wrong plugin key
('selectall'); change that key to 'selectallcontextmenu' so it matches the
folder/plugin name. Apply the same change to every file in
static/ckeditor/ckeditor/plugins/selectallcontextmenu/lang/ (replace 'selectall'
with 'selectallcontextmenu') so CKEditor will load the translations for the
Select All Context-Menu plugin.

@mlv-dev mlv-dev force-pushed the posting-4.plugins branch from 131a9d4 to d36a8f6 Compare August 27, 2025 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant