Skip to content

Commit 8920520

Browse files
authored
Handle JSON files with value 'undefined' (#146)
* Add: Handle JSON files with value 'undefined' * Fix: next id value Add: extend functionality to 'compress', 'validate' and 'treeview dialog' Fix: regex ignores 'undefined' in arrays * changes * Fix: show correct selection if it contains another invalid text Fix: checkbox overlapped Fix: error in original ReportError code
1 parent 5f7fc54 commit 8920520

File tree

8 files changed

+107
-9
lines changed

8 files changed

+107
-9
lines changed

NppJSONViewer/NppJsonViewer/Define.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,13 @@ const TCHAR STR_INI_FORMATTING_LINE[] = TEXT("LINE_FORMATTING");
5959
const TCHAR STR_INI_FORMATTING_INDENT[] = TEXT("INDENTATION");
6060
const TCHAR STR_INI_FORMATTING_INDENTCOUNT[] = TEXT("INDENTATION_COUNT");
6161

62-
const TCHAR STR_INI_OTHER_SEC[] = TEXT("Others");
63-
const TCHAR STR_INI_OTHER_FOLLOW_TAB[] = TEXT("FOLLOW_TAB");
64-
const TCHAR STR_INI_OTHER_AUTO_FORMAT[] = TEXT("AUTO_FORMAT");
65-
const TCHAR STR_INI_OTHER_USE_HIGHLIGHT[] = TEXT("USE_JSON_HIGHLIGHT");
66-
const TCHAR STR_INI_OTHER_IGNORE_COMMENT[] = TEXT("IGNORE_COMMENT");
67-
const TCHAR STR_INI_OTHER_IGNORE_COMMA[] = TEXT("IGNORE_TRAILLING_COMMA");
62+
const TCHAR STR_INI_OTHER_SEC[] = TEXT("Others");
63+
const TCHAR STR_INI_OTHER_FOLLOW_TAB[] = TEXT("FOLLOW_TAB");
64+
const TCHAR STR_INI_OTHER_AUTO_FORMAT[] = TEXT("AUTO_FORMAT");
65+
const TCHAR STR_INI_OTHER_USE_HIGHLIGHT[] = TEXT("USE_JSON_HIGHLIGHT");
66+
const TCHAR STR_INI_OTHER_IGNORE_COMMENT[] = TEXT("IGNORE_COMMENT");
67+
const TCHAR STR_INI_OTHER_IGNORE_COMMA[] = TEXT("IGNORE_TRAILLING_COMMA");
68+
const TCHAR STR_INI_OTHER_REPLACE_UNDEFINED[] = TEXT("REPLACE_VALUE_UNDEFINED");
6869

6970
const TCHAR STR_SRCH_SEARCHING[] = TEXT("Searching for: ");
7071
const TCHAR STR_SRCH_NOTFOUND[] = TEXT("Not found: ");
@@ -101,6 +102,7 @@ struct ParseOptions
101102
{
102103
bool bIgnoreComment = true;
103104
bool bIgnoreTraillingComma = true;
105+
bool bReplaceUndefined = false;
104106
};
105107

106108
struct Setting

NppJSONViewer/NppJsonViewer/JsonViewDlg.cpp

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "ScintillaEditor.h"
77
#include "Profile.h"
88
#include <format>
9+
#include <regex>
910

1011

1112
JsonViewDlg::JsonViewDlg(HINSTANCE hIntance, const NppData &nppData, const bool &isReady, int nCmdId, std::shared_ptr<Setting> &pSetting)
@@ -80,6 +81,9 @@ void JsonViewDlg::FormatJson()
8081
}
8182
else
8283
{
84+
if (CheckForTokenUndefined(JsonViewDlg::eMethod::FormatJson, selectedText, res, NULL))
85+
return;
86+
8387
ReportError(res);
8488
}
8589
}
@@ -94,13 +98,78 @@ void JsonViewDlg::CompressJson()
9498
if (res.success)
9599
{
96100
m_Editor->ReplaceSelection(res.response);
101+
HightlightAsJson();
97102
}
98103
else
99104
{
105+
if (CheckForTokenUndefined(JsonViewDlg::eMethod::GetCompressedJson, selectedText, res, NULL))
106+
return;
107+
100108
ReportError(res);
101109
}
102110
}
103111

112+
bool JsonViewDlg::CheckForTokenUndefined(eMethod method, std::string selectedText, Result &res, HTREEITEM tree_root)
113+
{
114+
const auto [le, lf, indentChar, indentLen] = GetFormatSetting();
115+
116+
if (m_pSetting->parseOptions.bReplaceUndefined)
117+
{
118+
auto text = selectedText.substr(res.error_pos, 9);
119+
std::transform(
120+
text.begin(),
121+
text.end(),
122+
text.begin(),
123+
[](unsigned char c)
124+
{
125+
return (unsigned char)std::tolower(c);
126+
});
127+
if (text == "undefined")
128+
{
129+
try
130+
{
131+
std::regex regex("([:\\[,])([\\s]*?)undefined([\\s,}]*?)", std::regex_constants::icase);
132+
text = std::regex_replace(selectedText, regex, "$1$2null");
133+
switch (method)
134+
{
135+
case eMethod::FormatJson:
136+
res = JsonHandler(m_pSetting->parseOptions).FormatJson(text, le, lf, indentChar, indentLen);
137+
break;
138+
case eMethod::GetCompressedJson:
139+
res = JsonHandler(m_pSetting->parseOptions).GetCompressedJson(text);
140+
break;
141+
case eMethod::ParseJson:
142+
{
143+
RapidJsonHandler handler(this, tree_root);
144+
rapidjson::StringBuffer sb;
145+
res = JsonHandler(m_pSetting->parseOptions).ParseJson<flgBaseReader>(text, sb, handler);
146+
break;
147+
}
148+
case eMethod::ValidateJson:
149+
res = JsonHandler(m_pSetting->parseOptions).ValidateJson(text);
150+
break;
151+
}
152+
if (res.success)
153+
{
154+
m_Editor->ReplaceSelection((method == eMethod::ParseJson || method == eMethod::ValidateJson) ? text : res.response);
155+
HightlightAsJson();
156+
return true;
157+
}
158+
else
159+
{
160+
m_Editor->ReplaceSelection(text);
161+
m_Editor->MakeSelection(m_Editor->GetSelectionStart(), static_cast<int>(text.length()));
162+
m_Editor->RefreshSelectionPos();
163+
}
164+
}
165+
catch (const std::exception&)
166+
{
167+
}
168+
}
169+
}
170+
return false;
171+
}
172+
104173
void JsonViewDlg::HandleTabActivated()
105174
{
106175
const bool bIsVisible = isCreated() && isVisible();
@@ -135,6 +204,12 @@ void JsonViewDlg::ValidateJson()
135204
}
136205
else
137206
{
207+
if (CheckForTokenUndefined(JsonViewDlg::eMethod::ValidateJson, selectedText, res, NULL))
208+
{
209+
ShowMessage(JSON_INFO_TITLE, JSON_ERR_VALIDATE_SUCCESS, MB_OK | MB_ICONINFORMATION);
210+
return;
211+
}
212+
138213
ReportError(res);
139214
}
140215
}
@@ -197,6 +272,9 @@ auto JsonViewDlg::PopulateTreeUsingSax(HTREEITEM tree_root, const std::string &j
197272
Result res = JsonHandler(m_pSetting->parseOptions).ParseJson<flgBaseReader>(jsonText, sb, handler);
198273
if (!res.success)
199274
{
275+
if (CheckForTokenUndefined(JsonViewDlg::eMethod::ParseJson, jsonText, res, tree_root))
276+
return retVal;
277+
200278
// Intimate user
201279
if (jsonText.empty())
202280
{
@@ -603,7 +681,7 @@ void JsonViewDlg::ReportError(const Result &result)
603681
{
604682
// Mark the error position
605683
size_t start = m_Editor->GetSelectionStart() + result.error_pos;
606-
size_t end = start + m_Editor->GetSelectionEnd();
684+
size_t end = m_Editor->GetSelectionEnd();
607685
m_Editor->MakeSelection(start, end);
608686

609687
// Intimate user

NppJSONViewer/NppJsonViewer/JsonViewDlg.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ class JsonViewDlg : public DockingDlgInterface
2020
eSearch
2121
};
2222

23+
enum class eMethod
24+
{
25+
FormatJson,
26+
GetCompressedJson,
27+
ParseJson,
28+
ValidateJson
29+
};
30+
2331
public:
2432
JsonViewDlg(HINSTANCE hIntance, const NppData &nppData, const bool &isReady, int nCmdId, std::shared_ptr<Setting> &pSetting);
2533
virtual ~JsonViewDlg();
@@ -70,6 +78,8 @@ class JsonViewDlg : public DockingDlgInterface
7078

7179
auto GetFormatSetting() const -> std::tuple<LE, LF, char, unsigned>;
7280

81+
bool CheckForTokenUndefined(eMethod method, std::string selectedText, Result &res, HTREEITEM tree_root);
82+
7383
protected:
7484
virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
7585

NppJSONViewer/NppJsonViewer/Profile.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ bool ProfileSetting::GetSettings(Setting &info) const
110110
if (bRetVal)
111111
info.parseOptions.bIgnoreTraillingComma = static_cast<bool>(nVal);
112112

113+
bRetVal &= ReadValue(STR_INI_OTHER_SEC, STR_INI_OTHER_REPLACE_UNDEFINED, nVal, info.parseOptions.bReplaceUndefined);
114+
if (bRetVal)
115+
info.parseOptions.bReplaceUndefined = static_cast<bool>(nVal);
116+
113117
return bRetVal;
114118
}
115119

@@ -127,6 +131,7 @@ bool ProfileSetting::SetSettings(const Setting &info) const
127131
bRetVal &= WriteValue(STR_INI_OTHER_SEC, STR_INI_OTHER_USE_HIGHLIGHT, info.bUseJsonHighlight);
128132
bRetVal &= WriteValue(STR_INI_OTHER_SEC, STR_INI_OTHER_IGNORE_COMMENT, info.parseOptions.bIgnoreComment);
129133
bRetVal &= WriteValue(STR_INI_OTHER_SEC, STR_INI_OTHER_IGNORE_COMMA, info.parseOptions.bIgnoreTraillingComma);
134+
bRetVal &= WriteValue(STR_INI_OTHER_SEC, STR_INI_OTHER_REPLACE_UNDEFINED, info.parseOptions.bReplaceUndefined);
130135

131136
return bRetVal;
132137
}

NppJSONViewer/NppJsonViewer/ScintillaEditor.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ class ScintillaEditor
2929
auto GetEOL() const -> unsigned;
3030
auto GetIndent() const -> std::tuple<char, unsigned>;
3131

32-
private:
3332
void RefreshSelectionPos();
3433

3534
private:

NppJSONViewer/NppJsonViewer/SettingsDlg.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ bool SettingsDlg::Apply()
127127
m_pSetting->bUseJsonHighlight = CUtility::GetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_JSON_HIGHLIGHT));
128128
m_pSetting->parseOptions.bIgnoreTraillingComma = CUtility::GetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_IGNORE_COMMA));
129129
m_pSetting->parseOptions.bIgnoreComment = CUtility::GetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_IGNORE_COMMENT));
130+
m_pSetting->parseOptions.bReplaceUndefined = CUtility::GetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_REPLACE_UNDEFINED));
130131

131132
return WriteINI();
132133
}
@@ -208,6 +209,7 @@ void SettingsDlg::InitDlg()
208209
CUtility::SetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_JSON_HIGHLIGHT), m_pSetting->bUseJsonHighlight);
209210
CUtility::SetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_IGNORE_COMMA), m_pSetting->parseOptions.bIgnoreTraillingComma);
210211
CUtility::SetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_IGNORE_COMMENT), m_pSetting->parseOptions.bIgnoreComment);
212+
CUtility::SetCheckboxStatus(::GetDlgItem(_hSelf, IDC_CHK_REPLACE_UNDEFINED), m_pSetting->parseOptions.bReplaceUndefined);
211213
}
212214

213215
void SettingsDlg::ShowSpaceCountCtrls(bool bShow)

NppJSONViewer/NppJsonViewer/resource.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#define IDC_CHK_IGNORE_COMMA 1030
4242
#define IDC_CHK_IGNORE_COMMENT 1031
4343
#define IDC_CHK_JSON_HIGHLIGHT 1032
44+
#define IDC_CHK_REPLACE_UNDEFINED 1033
4445
#define IDM_COPY_TREEITEM 40001
4546
#define IDM_COPY_NODENAME 40002
4647
#define IDM_COPY_NODEVALUE 40003
@@ -54,7 +55,7 @@
5455
#ifndef APSTUDIO_READONLY_SYMBOLS
5556
#define _APS_NEXT_RESOURCE_VALUE 110
5657
#define _APS_NEXT_COMMAND_VALUE 40007
57-
#define _APS_NEXT_CONTROL_VALUE 1033
58+
#define _APS_NEXT_CONTROL_VALUE 1034
5859
#define _APS_NEXT_SYMED_VALUE 101
5960
#endif
6061
#endif

NppJSONViewer/NppJsonViewer/resource.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ BEGIN
105105
CONTROL "Ignore trailing comma",IDC_CHK_IGNORE_COMMA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,33,140,10
106106
CONTROL "Ignore comments in json",IDC_CHK_IGNORE_COMMENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,46,140,10
107107
CONTROL "Use json highlighting",IDC_CHK_JSON_HIGHLIGHT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,59,140,10
108+
CONTROL "Replace value 'undefined' with 'null'",IDC_CHK_REPLACE_UNDEFINED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,72,140,10
108109
GROUPBOX " Indentation: ",IDC_STATIC,153,7,140,43
109110
CONTROL "Auto detect",IDC_RADIO_INDENT_AUTO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,160,21,50,10
110111
CONTROL "Use tab",IDC_RADIO_INDENT_TAB,"Button",BS_AUTORADIOBUTTON,240,21,50,10

0 commit comments

Comments
 (0)