Skip to content

Commit dc2c21a

Browse files
committed
feat: replace manual config textarea with CodeMirror JSON editor
Initialize CodeMirror on the manual configuration textarea with syntax highlighting, line numbers, bracket matching, and auto-close brackets Closes #509
1 parent 94f9316 commit dc2c21a

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
@@ -1481,6 +1481,61 @@ span.viz-section-error {
14811481
}
14821482

14831483

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

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
});
191224
})(jQuery, visualizer);

0 commit comments

Comments
 (0)