mbeditor 0.3.8 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: caf178914c2be95307a23ee24744dabd50f12c8597c69eddf814f63895e17433
4
- data.tar.gz: 0353fc7e791cf1fff4c739fddf59d0a1ba8259353a4147b738824275c4bca55f
3
+ metadata.gz: 3e496861ff75f2bb3c09388afbc609c07230ad8a914de28040b867ccb922a04d
4
+ data.tar.gz: f5825193b830cca72f626a86a15483eb46ccb4cd335388a6ccaed088841ff313
5
5
  SHA512:
6
- metadata.gz: 772a81a73df9b7ca2bd517193ee0178fb9843ea934c7bbc05157e84794596c62b98f34dbfa50004e2c8ee1abeda1e121e8936350826b1a213031952c1ef10563
7
- data.tar.gz: 705bc59cb210934c909b35819d41c98ecd3e858a153a25efa6587e530c51faa0821aa39932c155c4860c7335a0c70d7f06302e4c6a5b7cb7f1214911bb1f7fbe
6
+ metadata.gz: dd1ed23cefc9609ca7d99d77410104b63107dc0e72f80e72279adc4a01cba1a6da3fe2d6e0467ec23b7db1166d3ccbdfcf380d4057c5644008ab4a9fa87e5092
7
+ data.tar.gz: 0b6bc8dcec6f206fc3867c19bc7ffe028230b8503109dc8473e10997abe41c56db0fd3970f88c23bbf6fd69873c1d905cc0ce11a2010c6205cccc891ee511982
data/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.9] - 2026-04-21
9
+
10
+ ### Added
11
+ - Search responses now include a total result count; background counting runs for the first page to populate it without blocking.
12
+ - Editor preferences expanded with line height, letter spacing, cursor style, and auto-closing bracket/quote settings.
13
+
14
+ ### Fixed
15
+ - Multi-line tab indentation corrected; added regression test to prevent recurrence.
16
+ - 8 correctness, security, and reliability fixes surfaced by ultrareview.
17
+
8
18
  ## [0.3.8] - 2026-04-16
9
19
 
10
20
  ### Fixed
@@ -1,4 +1,11 @@
1
1
  // Mbeditor app IIFE — React and ReactDOM are injected from window.MbeditorRuntime
2
2
  // so that mbeditor never reads from or writes to window.React / window.ReactDOM,
3
3
  // protecting the host application's globals.
4
+
5
+ // Shared helper — returns the engine mount path with no trailing slash.
6
+ // All service modules and components use this instead of inlining the lookup.
7
+ window.mbeditorBasePath = function() {
8
+ return (window.MBEDITOR_BASE_PATH || '/mbeditor').replace(/\/$/, '');
9
+ };
10
+
4
11
  (function(React, ReactDOM) {
@@ -27,7 +27,7 @@ var CodeReviewPanel = function CodeReviewPanel(_ref) {
27
27
  setIsRedmineLoading(true);
28
28
 
29
29
  // Call the redmine endpoint. It will 503 if disabled via config.
30
- axios.get((window.MBEDITOR_BASE_PATH || '/mbeditor' ) + '/redmine/issue/' + issueId)
30
+ axios.get(window.mbeditorBasePath() + '/redmine/issue/' + issueId)
31
31
  .then(function (res) {
32
32
  setRedmineIssue(res.data);
33
33
  setIsRedmineLoading(false);
@@ -480,24 +480,34 @@ var EditorPanel = function EditorPanel(_ref) {
480
480
  theme: editorPrefs.theme || 'vs-dark',
481
481
  automaticLayout: true,
482
482
  minimap: { enabled: !!(editorPrefs.minimap) },
483
- renderLineHighlight: 'none',
483
+ renderLineHighlight: editorPrefs.renderLineHighlight || 'none',
484
484
  bracketPairColorization: { enabled: editorPrefs.bracketPairColorization !== false },
485
485
  fontFamily: editorPrefs.fontFamily || "'JetBrains Mono', 'Fira Code', Consolas, 'Courier New', monospace",
486
486
  fontSize: editorPrefs.fontSize || 13,
487
+ lineHeight: editorPrefs.lineHeight || 0,
488
+ letterSpacing: editorPrefs.letterSpacing || 0,
487
489
  tabSize: editorPrefs.tabSize || 4,
488
490
  insertSpaces: typeof editorPrefs.insertSpaces === 'boolean' ? editorPrefs.insertSpaces : false,
489
491
  wordWrap: editorPrefs.wordWrap || 'off',
490
492
  lineNumbers: editorPrefs.lineNumbers || 'on',
491
493
  renderWhitespace: editorPrefs.renderWhitespace || 'none',
492
494
  scrollBeyondLastLine: !!(editorPrefs.scrollBeyondLastLine),
493
- linkedEditing: true, // Enables Auto-Rename Tag natively!
495
+ cursorStyle: editorPrefs.cursorStyle || 'line',
496
+ cursorBlinking: editorPrefs.cursorBlinking || 'blink',
497
+ folding: editorPrefs.folding !== false,
498
+ smoothScrolling: !!(editorPrefs.smoothScrolling),
499
+ mouseWheelZoom: !!(editorPrefs.mouseWheelZoom),
500
+ autoClosingBrackets: editorPrefs.autoClosingBrackets || 'always',
501
+ autoClosingQuotes: editorPrefs.autoClosingQuotes || 'always',
502
+ autoIndent: editorPrefs.autoIndent || 'full',
503
+ formatOnPaste: editorPrefs.formatOnPaste !== false,
504
+ formatOnType: editorPrefs.formatOnType !== false,
505
+ quickSuggestions: editorPrefs.quickSuggestions !== false,
506
+ wordBasedSuggestions: editorPrefs.wordBasedSuggestions || 'matchingDocuments',
507
+ acceptSuggestionOnEnter: editorPrefs.acceptSuggestionOnEnter || 'on',
508
+ linkedEditing: true,
494
509
  fixedOverflowWidgets: true,
495
- hover: { above: false },
496
- autoClosingBrackets: 'always',
497
- autoClosingQuotes: 'always',
498
- autoIndent: 'full',
499
- formatOnPaste: true,
500
- formatOnType: true
510
+ hover: { above: false }
501
511
  });
502
512
 
503
513
  if (tab.viewState) {
@@ -700,6 +710,8 @@ var EditorPanel = function EditorPanel(_ref) {
700
710
  monacoRef.current.updateOptions({
701
711
  fontSize: editorPrefs.fontSize || 13,
702
712
  fontFamily: editorPrefs.fontFamily || "'JetBrains Mono', 'Fira Code', Consolas, 'Courier New', monospace",
713
+ lineHeight: editorPrefs.lineHeight || 0,
714
+ letterSpacing: editorPrefs.letterSpacing || 0,
703
715
  tabSize: editorPrefs.tabSize || 4,
704
716
  insertSpaces: typeof editorPrefs.insertSpaces === 'boolean' ? editorPrefs.insertSpaces : false,
705
717
  wordWrap: editorPrefs.wordWrap || 'off',
@@ -707,7 +719,21 @@ var EditorPanel = function EditorPanel(_ref) {
707
719
  renderWhitespace: editorPrefs.renderWhitespace || 'none',
708
720
  minimap: { enabled: !!(editorPrefs.minimap) },
709
721
  scrollBeyondLastLine: !!(editorPrefs.scrollBeyondLastLine),
710
- bracketPairColorization: { enabled: editorPrefs.bracketPairColorization !== false }
722
+ bracketPairColorization: { enabled: editorPrefs.bracketPairColorization !== false },
723
+ renderLineHighlight: editorPrefs.renderLineHighlight || 'none',
724
+ cursorStyle: editorPrefs.cursorStyle || 'line',
725
+ cursorBlinking: editorPrefs.cursorBlinking || 'blink',
726
+ folding: editorPrefs.folding !== false,
727
+ smoothScrolling: !!(editorPrefs.smoothScrolling),
728
+ mouseWheelZoom: !!(editorPrefs.mouseWheelZoom),
729
+ autoClosingBrackets: editorPrefs.autoClosingBrackets || 'always',
730
+ autoClosingQuotes: editorPrefs.autoClosingQuotes || 'always',
731
+ autoIndent: editorPrefs.autoIndent || 'full',
732
+ formatOnPaste: editorPrefs.formatOnPaste !== false,
733
+ formatOnType: editorPrefs.formatOnType !== false,
734
+ quickSuggestions: editorPrefs.quickSuggestions !== false,
735
+ wordBasedSuggestions: editorPrefs.wordBasedSuggestions || 'matchingDocuments',
736
+ acceptSuggestionOnEnter: editorPrefs.acceptSuggestionOnEnter || 'on'
711
737
  });
712
738
  }
713
739
  }, [editorPrefs]);
@@ -1157,6 +1183,22 @@ var EditorPanel = function EditorPanel(_ref) {
1157
1183
  renderer.html = function (token) {
1158
1184
  return '<pre>' + escapeHtml(typeof token === 'object' ? token.text : token) + '</pre>';
1159
1185
  };
1186
+ // Sanitize link/image hrefs to block javascript: and data: schemes.
1187
+ var _origLink = renderer.link.bind(renderer);
1188
+ var _origImage = renderer.image.bind(renderer);
1189
+ var SAFE_HREF_SCHEME = /^(https?:|mailto:|#|\/)/i;
1190
+ var safeHref = function(href) {
1191
+ if (!href) return href;
1192
+ return SAFE_HREF_SCHEME.test(href.trim()) ? href : '#';
1193
+ };
1194
+ renderer.link = function(token) {
1195
+ if (token && typeof token === 'object') { token = Object.assign({}, token, { href: safeHref(token.href) }); }
1196
+ return _origLink(token);
1197
+ };
1198
+ renderer.image = function(token) {
1199
+ if (token && typeof token === 'object') { token = Object.assign({}, token, { href: safeHref(token.href) }); }
1200
+ return _origImage(token);
1201
+ };
1160
1202
  setMarkup(window.marked.parse(markdownContent, { renderer: renderer }));
1161
1203
  })();
1162
1204
  }
@@ -1192,11 +1234,10 @@ var EditorPanel = function EditorPanel(_ref) {
1192
1234
  }
1193
1235
 
1194
1236
  if (isImage) {
1195
- var basePath = (window.MBEDITOR_BASE_PATH || '/mbeditor').replace(/\/$/, '');
1196
1237
  return React.createElement(
1197
1238
  'div',
1198
1239
  { className: 'monaco-container', style: { display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#1e1e1e' } },
1199
- React.createElement('img', { src: basePath + '/raw?path=' + encodeURIComponent(tab.path), style: { maxWidth: '90%', maxHeight: '90%', objectFit: 'contain' }, alt: tab.name })
1240
+ React.createElement('img', { src: window.mbeditorBasePath() + '/raw?path=' + encodeURIComponent(tab.path), style: { maxWidth: '90%', maxHeight: '90%', objectFit: 'contain' }, alt: tab.name })
1200
1241
  );
1201
1242
  }
1202
1243
 
@@ -14,8 +14,19 @@ var GitPanel = function GitPanel(_ref) {
14
14
  var _s1 = useState(true); var localExpanded = _s1[0]; var setLocalExpanded = _s1[1];
15
15
  var _s2 = useState(true); var branchExpanded = _s2[0]; var setBranchExpanded = _s2[1];
16
16
  var _s3 = useState(true); var historyExpanded= _s3[0]; var setHistoryExpanded= _s3[1];
17
- // { [hash]: true|false }
18
- var _s4 = useState({}); var expandedCommits = _s4[0]; var setExpandedCommits = _s4[1];
17
+
18
+ // { [hash]: true|false } persisted to localStorage keyed by root path so
19
+ // users don't need to re-expand commits on every page load.
20
+ var _lsKey = 'mbeditor_expanded_commits_' + (window.MBEDITOR_BASE_PATH || '');
21
+ var _lsInitial = (function() {
22
+ try { return JSON.parse(localStorage.getItem(_lsKey)) || {}; } catch(e) { return {}; }
23
+ })();
24
+ var _s4 = useState(_lsInitial); var expandedCommits = _s4[0]; var setExpandedCommits = _s4[1];
25
+
26
+ // Persist expandedCommits whenever it changes.
27
+ useEffect(function() {
28
+ try { localStorage.setItem(_lsKey, JSON.stringify(expandedCommits)); } catch(e) {}
29
+ }, [expandedCommits]);
19
30
  // { [hash]: { loading, files: [{status,path}], error } }
20
31
  var _s5 = useState({}); var commitFiles = _s5[0]; var setCommitFiles = _s5[1];
21
32
  var _s6 = useState(false); var refreshing = _s6[0]; var setRefreshing = _s6[1];
@@ -55,8 +66,7 @@ var GitPanel = function GitPanel(_ref) {
55
66
  setRedmineLoading(true);
56
67
  setRedmineIssue(null);
57
68
  setRedmineError(null);
58
- var basePath = (window.MBEDITOR_BASE_PATH || '/mbeditor').replace(/\/$/, '');
59
- axios.get(basePath + '/redmine/issue/' + redmineTicketId)
69
+ axios.get(window.mbeditorBasePath() + '/redmine/issue/' + redmineTicketId)
60
70
  .then(function (res) {
61
71
  setRedmineIssue(res.data);
62
72
  setRedmineLoading(false);