Skip to content

Commit 1c05a88

Browse files
feat: replace manual config textarea with CodeMirror JSON editor (#1280)
Initialize CodeMirror on the manual configuration textarea with syntax highlighting, line numbers, bracket matching, and auto-close brackets Closes #509
1 parent 10f4d39 commit 1c05a88

5 files changed

Lines changed: 93 additions & 4 deletions

File tree

classes/Visualizer/Module/Chart.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ private function _handleDataAndSettingsPage() {
853853
wp_enqueue_script( 'visualizer-preview' );
854854
wp_enqueue_script( 'visualizer-chosen' );
855855
wp_enqueue_script( 'visualizer-render' );
856+
wp_enqueue_code_editor( array( 'type' => 'application/json' ) );
856857

857858
if ( Visualizer_Module::can_show_feature( 'simple-editor' ) ) {
858859
wp_enqueue_script( 'visualizer-editor-simple' );

classes/Visualizer/Render/Sidebar.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ protected function _renderManualConfigDescription() {
142142
self::_renderSectionDescription(
143143
'<span class="viz-gvlink">' . sprintf(
144144
// translators: %1$s - HTML link tag, %2$s - HTML closing link tag, %3$s - HTML link tag, %4$s - HTML closing link tag.
145-
__( 'Configure the graph by providing configuration variables right from the %1$sGoogle Visualization API%2$s. You can refer to to some examples %3$shere%4$s.', 'visualizer' ), '<a href="https://developers.google.com/chart/interactive/docs/gallery/?#configuration-options" target="_blank">',
145+
__( 'Configure the graph by providing configuration variables right from the %1$sGoogle Visualization API%2$s. You can refer to %3$sCommon Snippets%4$s for examples.', 'visualizer' ), '<a href="https://developers.google.com/chart/interactive/docs/gallery/?#configuration-options" target="_blank">',
146146
'</a>',
147147
'<a href="https://docs.themeisle.com/article/728-manual-configuration" target="_blank">',
148148
'</a>'

classes/Visualizer/Render/Sidebar/ChartJS.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ protected function _renderManualConfigDescription() {
390390
self::_renderSectionDescription(
391391
'<span class="viz-gvlink">' . sprintf(
392392
// translators: %1$s - HTML link tag, %2$s - HTML closing link tag, %3$s - HTML link tag, %4$s - HTML closing link tag.
393-
__( 'Configure the graph by providing configuration variables right from the %1$sChartJS API%2$s. You can refer to to some examples %3$shere%4$s.', 'visualizer' ),
393+
__( 'Configure the graph by providing configuration variables right from the %1$sChartJS API%2$s. You can refer to %3$sCommon Snippets%4$s for examples.', 'visualizer' ),
394394
'<a href="https://www.chartjs.org/docs/latest/configuration/" target="_blank">',
395395
'</a>',
396396
'<a href="https://docs.themeisle.com/article/728-manual-configuration" target="_blank">',

css/frame.css

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,61 @@ span.viz-section-error {
14791479
}
14801480

14811481

1482+
/******************************************************************************/
1483+
/************************ manual config JSON editor *************************/
1484+
/******************************************************************************/
1485+
textarea[name="manual"] + .CodeMirror {
1486+
background: #282923;
1487+
color: #f8f8f2;
1488+
border-radius: 4px;
1489+
height: 200px;
1490+
font-size: 13px;
1491+
}
1492+
1493+
textarea[name="manual"] + .CodeMirror .CodeMirror-scroll {
1494+
min-height: 200px;
1495+
}
1496+
1497+
textarea[name="manual"] + .CodeMirror .CodeMirror-gutters {
1498+
background: #1e1f1c;
1499+
border-right: 1px solid #404040;
1500+
color: #75715e;
1501+
}
1502+
1503+
textarea[name="manual"] + .CodeMirror .CodeMirror-linenumber {
1504+
color: #75715e;
1505+
}
1506+
1507+
textarea[name="manual"] + .CodeMirror .CodeMirror-cursor {
1508+
border-left: 1px solid #f8f8f0;
1509+
}
1510+
1511+
textarea[name="manual"] + .CodeMirror .CodeMirror-selected {
1512+
background: #49483e;
1513+
}
1514+
1515+
textarea[name="manual"] + .CodeMirror pre.CodeMirror-line,
1516+
textarea[name="manual"] + .CodeMirror pre.CodeMirror-line-like {
1517+
color: #f8f8f2;
1518+
}
1519+
1520+
textarea[name="manual"] + .CodeMirror .cm-string {
1521+
color: #A9DC76;
1522+
}
1523+
1524+
textarea[name="manual"] + .CodeMirror .cm-number {
1525+
color: #AB9DF2;
1526+
}
1527+
1528+
textarea[name="manual"] + .CodeMirror .cm-atom {
1529+
color: #78DCE8;
1530+
}
1531+
1532+
textarea[name="manual"] + .CodeMirror .cm-punctuation,
1533+
textarea[name="manual"] + .CodeMirror .cm-bracket {
1534+
color: #f8f8f2;
1535+
}
1536+
14821537
/******************************************************************************/
14831538
/******************************** data tables *******************************/
14841539
/******************************************************************************/

js/preview.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* global console */
33
/* global vizSettingsHaveChanged */
44
/* global vizHaveSettingsChanged */
5+
/* global wp */
56

67
(function($, v) {
78
var timeout;
@@ -22,6 +23,7 @@
2223
clear: updateChart
2324
});
2425
$('#settings-form textarea[name="manual"]').change(validateJSON).keyup(validateJSON);
26+
initManualConfigEditor();
2527
vizSettingsHaveChanged(false);
2628
};
2729

@@ -173,19 +175,50 @@
173175
function validateJSON() {
174176
$('#visualizer-error-manual').remove();
175177
try{
176-
var options = JSON.parse($(this).val());
178+
JSON.parse($(this).val());
177179
}catch(error){
178-
$('<div class="visualizer-error" id="visualizer-error-manual">Invalid JSON: ' + error + '</div>').insertAfter($(this));
180+
var $after = $(this).next('.CodeMirror').length ? $(this).next('.CodeMirror') : $(this);
181+
$('<div class="visualizer-error" id="visualizer-error-manual">Invalid JSON: ' + error + '</div>').insertAfter($after);
179182
}
180183
}
181184

185+
function initManualConfigEditor() {
186+
var $textarea = $('textarea[name="manual"]');
187+
if (!$textarea.length || $textarea.data('cm-initialized')) return;
188+
189+
var CodeMirrorLib = (typeof wp !== 'undefined' && wp.CodeMirror) ? wp.CodeMirror : null;
190+
if (!CodeMirrorLib) return;
191+
192+
$textarea.data('cm-initialized', true);
193+
194+
var cm = CodeMirrorLib.fromTextArea($textarea.get(0), {
195+
mode: 'application/json',
196+
lineNumbers: true,
197+
lineWrapping: true,
198+
matchBrackets: true,
199+
autoCloseBrackets: true
200+
});
201+
202+
// Refresh when any sidebar group is expanded so line numbers render correctly
203+
// (CodeMirror can't measure gutter width while the container is hidden).
204+
$(document).on('click.vizManualConfig', '.viz-group-title', function() {
205+
setTimeout(function() { cm.refresh(); }, 50);
206+
});
207+
208+
cm.on('change', function() {
209+
cm.save();
210+
$textarea.trigger('change');
211+
});
212+
}
213+
182214
$('.control-text').change(updateChart).keyup(updateChart);
183215
$('.control-select, .control-checkbox, .control-check').change(updateChart);
184216
$('.color-picker-hex').wpColorPicker({
185217
change: updateChart,
186218
clear: updateChart
187219
});
188220
$('textarea[name="manual"]').change(validateJSON).keyup(validateJSON);
221+
initManualConfigEditor();
189222

190223
$(document).on('change', 'input[name="paging_bool"], input[name="pagination"]', function() {
191224
$('.viz-pagination-options').toggle($(this).is(':checked'));

0 commit comments

Comments
 (0)