WYSIWYG (Summernote) editor fails to load on Tiki-syntax pages: "a.lastIndexOf is not a function"
- Status
- Open
- Subject
- WYSIWYG (Summernote) editor fails to load on Tiki-syntax pages: "a.lastIndexOf is not a function"
- Version
- 30.x
Regression from 29.x to 30.x - Category
- Regression
- Feature
- WYSIWYG (What You See is What You Get)
- Resolution status
- New
- Submitted by
- Doug Higby
- Lastmod by
- Doug Higby
- Rating
- Description
- Affected versions:** 30.0, 30.1, and current `master` (verified against the raw files on GitLab).
Not present in 29.2.
- Severity:** The WYSIWYG editor never renders on affected pages, so those pages cannot be edited
in WYSIWYG mode at all. On our site this hit 194 of 249 wiki pages, because Tiki remembers the
last-used editor per page in `tiki_pages.wysiwyg`.- Environment:** Tiki 30.1, PHP 8.3.33, MySQL 8.0.46. `markdown_enabled = y`,
`markdown_default = markdown`, `feature_wysiwyg = y`.
-Symptom
Opening a wiki page whose last-used editor was WYSIWYG loads the page (HTTP 200, nothing in the
PHP error log), but the editor never appears. The browser console shows:```
Uncaught TypeError: a.lastIndexOf is not a function
at formatTikiToolbars.js:31:11
at Array.forEach (<anonymous>)
at P (formatTikiToolbars.js:28:26)
```Root cause
Tiki 30 renamed `TextArea`'s `syntax` parameter to `_syntax`, but did not update the toolbars
handler that consumes it.The rename itself looks deliberate and correct: `TextArea.php` emits every parameter whose name
does **not** start with `_` as an HTML attribute on the `<textarea>`:```php
// lib/smarty_tiki/BlockHandler/TextArea.php:213-216
foreach ($params as $k => $v) {
if ($k0 != '_' && ! in_array($k, 'comments', 'switcheditor', 'section', 'area_id', 'autosave')) {
$textarea_attributes .= ' ' . $k . '="' . $v . '"';
}
}
```so under 29.2 a bogus `syntax="tiki"` attribute was being written into the markup. The fix was to
prefix it. What was missed is that the same `$params` array is handed straight to the toolbars
handler, which still keys on the old name:1. `TextArea.php:91,93` — sets `$params'_syntax'` from `guess_syntax()` (e.g. `'tiki'`).
2. `TextArea.php:203` — `$wysiwyglib->setUpEditor($as_id, $params);` passes the **whole array**.
3. `wysiwyglib.php:87` — `json_encode(smarty_function_toolbars($params, ...))` forwards it.
4. `FunctionHandler/Toolbars.php:26` — still reads `syntax`, so with the key gone its default wins:```php
$default = [
'comments' => 'n',
'is_html' => $is_html,
'section' => $section,
'syntax' => $prefs'markdown_default', // <-- takes over; no '_syntax' fallback
];
$params = array_merge($default, $params);
```Every Tiki-syntax page is therefore reported as `markdown`. That takes the markdown branch of
`ToolbarsList` (`lib/core/Lib/core/Toolbar/ToolbarsList.php:227-251`), which flattens the toolbar
by one level and `json_decode`s each token into an object — a shape built for the Toast editor
("need to flatten the icons for toast which only has one toolbar it seems").Summernote's formatter then receives that Toast-shaped structure:
```js
// src/js/wysiwyg/summernote/formatTikiToolbars.js:29,33
const flattenDepth1 = toolbar.flat(1);
flattenDepth1.forEach((item, index) => {
const lastSeparator = item.lastIndexOf("-"); // objects have no .lastIndexOf -> TypeError
```With the correct syntax the non-markdown path returns `$lines[] = $lineOut` (one level deeper),
so `flat(1)` yields arrays and `lastIndexOf` resolves. With the markdown path it yields objects,
and the editor dies before rendering.Reproduction
1. Set `markdown_enabled = y` and `markdown_default = markdown`.
2. Create/edit a wiki page whose content is Tiki syntax (so `guess_syntax()` returns `tiki`).
3. Set the page to use the WYSIWYG editor and reload the edit page.
4. The editor does not render; the console shows the TypeError above.Evidence
Building the toolbar directly from CLI on 30.1, varying only the parameter name:| params passed to `smarty_function_toolbars()` | result of `toolbar.flat(1)` |
|-|-|
| `'syntax' => 'tiki'` (pre-30 behaviour) | 2 blocks -> 2 arrays — works |
| `'_syntax' => 'tiki'` (30.x behaviour) | 3 blocks -> 23 objects — throws |
| `'syntax' => 'markdown'` (genuinely markdown) | 3 blocks -> 23 objects — Toast shape, as intended |Worth noting for triage: stock 29.2 and 30.1 produce the same toolbar structure for a given
syntax value, and ship byte-identical built JS for formatTikiToolbars (I diffed the minified
public/generated/js/wysiwyg-summernote.js in both releases). The regression is purely the
dropped parameter name — not the toolbar structure and not the editor bundle.Suggested fix
Honour the new name in the handler, falling back to the preference as before:
a/lib/smarty_tiki/FunctionHandler/Toolbars.php +++ b/lib/smarty_tiki/FunctionHandler/Toolbars.php@@
+ 'syntax' => $params'_syntax' ?? $prefs'markdown_default',
$default = [
'comments' => 'n',
'is_html' => $is_html,
'section' => $section,
- 'syntax' => $prefs'markdown_default',];
This is behaviour-preserving: array_merge($default, $params) still lets an explicit syntax
parameter win (as templates/wiki_edit.tpl passes via syntax=$textarea_syntax), and when
neither key is present nothing changes. It only affects the case where _syntax is set and
syntax is not — exactly the broken path.Applied to a production 30.1 install, this restores the 29.2 structure (2 blocks -> 2 arrays)
and the WYSIWYG editor loads correctly again.An alternative, if you would rather keep the handler's public API as syntax, is to translate at
the call site in wysiwyglib::setUpEditor() — but the handler-side fix covers every caller that
forwards a TextArea params array, of which there are several
(wysiwyglib.php:51, :87, :267).Possibly related
WysiwygLib::setUpEditor() in 30.x issues an outbound HTTP request to the LanguageTool server
(Services_LanguageCheck_Controller::getLanguageToolUrl(), default http://localhost:8081
) on
every editor setup, unconditionally — the "always check if language is supported" block runs
even when feature_language_check is n. On a host with no LanguageTool server this is a wasted
request per edit-page load, and against a slow/filtered remote host it would add up to the 5s
timeout. Reported separately here only as an observation; it did not cause the failure above.- Solution
Suggested fix
Honour the new name in the handler, falling back to the preference as before:
a/lib/smarty_tiki/FunctionHandler/Toolbars.php +++ b/lib/smarty_tiki/FunctionHandler/Toolbars.php@@
+ 'syntax' => $params'_syntax' ?? $prefs'markdown_default',
$default = [
'comments' => 'n',
'is_html' => $is_html,
'section' => $section,
- 'syntax' => $prefs'markdown_default',];
This is behaviour-preserving: array_merge($default, $params) still lets an explicit syntax
parameter win (as templates/wiki_edit.tpl passes via syntax=$textarea_syntax), and when
neither key is present nothing changes. It only affects the case where _syntax is set and
syntax is not — exactly the broken path.Applied to a production 30.1 install, this restores the 29.2 structure (2 blocks -> 2 arrays)
and the WYSIWYG editor loads correctly again.An alternative, if you would rather keep the handler's public API as syntax, is to translate at
the call site in wysiwyglib::setUpEditor() — but the handler-side fix covers every caller that
forwards a TextArea params array, of which there are several
(wysiwyglib.php:51, :87, :267).- Workaround
- Importance
- 8
- Easy to solve?
- 9
- Priority
- 72
- Demonstrate Bug on Tiki 19+
-
This bug has been demonstrated on show2.tiki.org
Please demonstrate your bug on show2.tiki.org
Show.tiki.org is not configured properlyThe public/private keys configured to connect to show2.tiki.org were not accepted. Please make sure you are using RSA keys. Thanks.
- Demonstrate Bug (older Tiki versions)
-
This bug has been demonstrated on show.tikiwiki.org
Please demonstrate your bug on show.tikiwiki.org
Show.tiki.org is not configured properlyThe public/private keys configured to connect to show.tikiwiki.org were not accepted. Please make sure you are using RSA keys. Thanks.
- Ticket ID
- 9025
- Created
- Tuesday 08 September, 2026 17:24:40 UTC
by Doug Higby - LastModif
- Tuesday 08 September, 2026 17:31:47 UTC