json-diff-kit
Advanced tools
Comparing version 1.0.15 to 1.0.16
@@ -25,2 +25,16 @@ 'use strict'; | ||
function _extends$1() { | ||
_extends$1 = Object.assign || function(target) { | ||
for(var i = 1; i < arguments.length; i++){ | ||
var source = arguments[i]; | ||
for(var key in source){ | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends$1.apply(this, arguments); | ||
} | ||
const isExpandLine = (segment)=>{ | ||
@@ -32,2 +46,48 @@ return 'hasLinesBefore' in segment || 'hasLinesAfter' in segment; | ||
}; | ||
/** | ||
* Merge two segments array into one, divide the segment if necessary. | ||
*/ const mergeSegments = (tokens, diffs)=>{ | ||
const result = []; | ||
let token; | ||
let diff; | ||
if (tokens.length && diffs.length) { | ||
tokens = [ | ||
...tokens | ||
]; | ||
diffs = [ | ||
...diffs | ||
]; | ||
token = _extends$1({}, tokens.shift()); | ||
diff = _extends$1({}, diffs.shift()); | ||
while(1){ | ||
if (token.start === diff.start) { | ||
const end = Math.min(token.end, diff.end); | ||
result.push(_extends$1({}, token, diff, { | ||
end | ||
})); | ||
token.start = diff.start = end; | ||
} else if (token.start < diff.start) { | ||
const end = Math.min(token.end, diff.start); | ||
result.push(_extends$1({}, diff, token, { | ||
end | ||
})); | ||
token.start = end; | ||
} else { | ||
const end = Math.min(token.start, diff.end); | ||
result.push(_extends$1({}, token, diff, { | ||
end | ||
})); | ||
diff.start = end; | ||
} | ||
if (!tokens.length || !diffs.length) break; | ||
if (token.start === token.end) token = _extends$1({}, tokens.shift()); | ||
if (diff.start === diff.end) diff = _extends$1({}, diffs.shift()); | ||
} | ||
} | ||
if (!tokens.length) result.push(...diffs.map((d)=>_extends$1({}, d, { | ||
token: token.token || 'plain' | ||
}))); | ||
if (!diffs.length) result.push(...tokens); | ||
return result; | ||
}; | ||
@@ -399,50 +459,35 @@ const calculatePlaceholderHeight = (segments, accTop, startSegment, startLine, endSegment, endLine, itemHeight, expandLineHeight, totalHeight)=>{ | ||
function _extends$1() { | ||
_extends$1 = Object.assign || function(target) { | ||
for(var i = 1; i < arguments.length; i++){ | ||
var source = arguments[i]; | ||
for(var key in source){ | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends$1.apply(this, arguments); | ||
} | ||
const filterEmptyParts = (arr)=>{ | ||
return arr.filter((item)=>item.text.length); | ||
}; | ||
const joinBySeparator = (arr, separator)=>{ | ||
if (!arr.length) { | ||
return arr; | ||
} | ||
const getOriginalIndices = (arr, separatorLength)=>{ | ||
const result = []; | ||
for(let i = 0; i < arr.length; i++){ | ||
if (result.length && arr[i].text.length) { | ||
if (result[result.length - 1].type === 'equal') { | ||
result[result.length - 1] = _extends$1({}, result[result.length - 1], { | ||
text: result[result.length - 1].text + separator | ||
}); | ||
} else { | ||
result.push({ | ||
type: 'equal', | ||
text: separator | ||
}); | ||
} | ||
} | ||
result.push(arr[i]); | ||
let index = 0; | ||
for (const item of arr){ | ||
result.push(index); | ||
index += item.length + separatorLength; | ||
} | ||
result.push(index - separatorLength); | ||
return result; | ||
}; | ||
const filterEmptyParts = (arr)=>{ | ||
return arr.filter((item)=>item.end > item.start); | ||
}; | ||
const getInlineDiff = (l, r, options)=>{ | ||
let resultL = []; | ||
let resultR = []; | ||
let lastL = 0; | ||
let lastR = 0; | ||
if (options.mode === 'word') { | ||
const lArr = l.split(options.wordSeparator); | ||
const rArr = r.split(options.wordSeparator); | ||
const iter = lcs_1(lArr, rArr); | ||
let resultL = []; | ||
let resultR = []; | ||
let lastL = 0; | ||
let lastR = 0; | ||
const wordSeparator = options.wordSeparator || ' '; | ||
const lArr = l.split(wordSeparator); | ||
const rArr = r.split(wordSeparator); | ||
/** | ||
* The iter array contains the information about replacement, which is an array of | ||
* tuple `[startL, startR, length]`. | ||
* | ||
* e.g. `[1, 2, 3]` means replace `lArr[1...1+3]` to `rArr[2...2+3]` (include the end). | ||
*/ const iter = [ | ||
...lcs_1(lArr, rArr) | ||
]; | ||
const separatorLength = wordSeparator.length; | ||
const indicesL = getOriginalIndices(lArr, separatorLength); | ||
const indicesR = getOriginalIndices(rArr, separatorLength); | ||
for (const [sl, sr, length] of iter){ | ||
@@ -452,3 +497,4 @@ if (sl > lastL) { | ||
type: 'remove', | ||
text: lArr.slice(lastL, sl).join(options.wordSeparator) | ||
start: indicesL[lastL], | ||
end: indicesL[sl] | ||
}); | ||
@@ -459,3 +505,4 @@ } | ||
type: 'add', | ||
text: rArr.slice(lastR, sr).join(options.wordSeparator) | ||
start: indicesR[lastR], | ||
end: indicesR[sr] | ||
}); | ||
@@ -466,8 +513,8 @@ } | ||
resultL.push({ | ||
type: 'equal', | ||
text: lArr.slice(sl, lastL).join(options.wordSeparator) | ||
start: indicesL[sl], | ||
end: indicesL[lastL] | ||
}); | ||
resultR.push({ | ||
type: 'equal', | ||
text: rArr.slice(sr, lastR).join(options.wordSeparator) | ||
start: indicesR[sr], | ||
end: indicesR[lastR] | ||
}); | ||
@@ -478,3 +525,4 @@ } | ||
type: 'remove', | ||
text: lArr.slice(lastL).join(options.wordSeparator) | ||
start: indicesL[lastL], | ||
end: l.length | ||
}); | ||
@@ -485,7 +533,8 @@ } | ||
type: 'add', | ||
text: rArr.slice(lastR).join(options.wordSeparator) | ||
start: indicesR[lastR], | ||
end: r.length | ||
}); | ||
} | ||
resultL = joinBySeparator(filterEmptyParts(resultL), options.wordSeparator); | ||
resultR = joinBySeparator(filterEmptyParts(resultR), options.wordSeparator); | ||
resultL = filterEmptyParts(resultL); | ||
resultR = filterEmptyParts(resultR); | ||
return [ | ||
@@ -497,6 +546,2 @@ resultL, | ||
const iter = lcs_1(l, r); | ||
let resultL = []; | ||
let resultR = []; | ||
let lastL = 0; | ||
let lastR = 0; | ||
for (const [sl, sr, length] of iter){ | ||
@@ -506,3 +551,4 @@ if (sl > lastL) { | ||
type: 'remove', | ||
text: l.substring(lastL, sl) | ||
start: lastL, | ||
end: sl | ||
}); | ||
@@ -513,3 +559,4 @@ } | ||
type: 'add', | ||
text: r.substring(lastR, sr) | ||
start: lastR, | ||
end: sr | ||
}); | ||
@@ -520,8 +567,8 @@ } | ||
resultL.push({ | ||
type: 'equal', | ||
text: l.substring(sl, lastL) | ||
start: sl, | ||
end: lastL | ||
}); | ||
resultR.push({ | ||
type: 'equal', | ||
text: r.substring(sr, lastR) | ||
start: sr, | ||
end: lastR | ||
}); | ||
@@ -532,3 +579,4 @@ } | ||
type: 'remove', | ||
text: l.substring(lastL) | ||
start: lastL, | ||
end: l.length | ||
}); | ||
@@ -539,3 +587,4 @@ } | ||
type: 'add', | ||
text: r.substring(lastR) | ||
start: lastR, | ||
end: r.length | ||
}); | ||
@@ -551,2 +600,117 @@ } | ||
const syntaxHighlightLine = (enabled, text, offset)=>{ | ||
if (!enabled) { | ||
return [ | ||
{ | ||
token: 'plain', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
if (!Number.isNaN(Number(text))) { | ||
return [ | ||
{ | ||
token: 'number', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
if (text === 'true' || text === 'false') { | ||
return [ | ||
{ | ||
token: 'boolean', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
if (text === 'null') { | ||
return [ | ||
{ | ||
token: 'null', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
if (text.startsWith('"')) { | ||
if (text.endsWith(': [') || text.endsWith(': {')) { | ||
return [ | ||
{ | ||
token: 'key', | ||
start: offset, | ||
end: text.length - 3 + offset | ||
}, | ||
{ | ||
token: 'punctuation', | ||
start: text.length - 3, | ||
end: text.length - 2 + offset | ||
}, | ||
{ | ||
token: 'plain', | ||
start: text.length - 2, | ||
end: text.length - 1 + offset | ||
}, | ||
{ | ||
token: 'punctuation', | ||
start: text.length - 1, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
let pairedQuoteIndex = 1; | ||
while(pairedQuoteIndex < text.length){ | ||
if (text[pairedQuoteIndex] === '"') break; | ||
if (text[pairedQuoteIndex] === '\\') ++pairedQuoteIndex; | ||
++pairedQuoteIndex; | ||
} | ||
if (pairedQuoteIndex === text.length - 1) { | ||
return [ | ||
{ | ||
token: 'string', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
return [ | ||
{ | ||
token: 'key', | ||
start: offset, | ||
end: pairedQuoteIndex + 1 + offset | ||
}, | ||
{ | ||
token: 'punctuation', | ||
start: pairedQuoteIndex + 1, | ||
end: pairedQuoteIndex + 2 + offset | ||
}, | ||
{ | ||
token: 'plain', | ||
start: pairedQuoteIndex + 2, | ||
end: pairedQuoteIndex + 3 + offset | ||
}, | ||
...syntaxHighlightLine(enabled, text.substring(pairedQuoteIndex + 3), offset + pairedQuoteIndex + 3) | ||
]; | ||
} | ||
if (text === '{' || text === '}' || text === '[' || text === ']') { | ||
return [ | ||
{ | ||
token: 'punctuation', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
// should this be expected? | ||
return [ | ||
{ | ||
token: 'plain', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
}; | ||
const defaultOptions = { | ||
@@ -791,27 +955,34 @@ threshold: 8, | ||
}; | ||
const renderInlineDiffResult = (arr)=>{ | ||
return arr.map((result)=>result.map((item, index)=>{ | ||
if (item.type === 'equal') { | ||
return /*#__PURE__*/ React__namespace.createElement("span", { | ||
key: `${index}-${item.type}-${item.text}` | ||
}, item.text); | ||
} | ||
return /*#__PURE__*/ React__namespace.createElement("span", { | ||
key: `${index}-${item.type}-${item.text}`, | ||
className: `inline-diff-${item.type}` | ||
}, item.text); | ||
})); | ||
}; | ||
const renderLine = (index)=>{ | ||
const renderInlineResult = (text, info = [], comma = false, syntaxHighlightEnabled = false)=>/*#__PURE__*/ React__namespace.createElement(React__namespace.Fragment, null, info.map((item, index)=>{ | ||
const frag = text.slice(item.start, item.end); | ||
if (!item.type && !item.token) { | ||
return frag; | ||
} | ||
const className = [ | ||
item.type ? `inline-diff-${item.type}` : '', | ||
item.token ? `token ${item.token}` : '' | ||
].filter(Boolean).join(' '); | ||
return /*#__PURE__*/ React__namespace.createElement("span", { | ||
key: `${index}-${item.type}-${frag}`, | ||
className: className | ||
}, frag); | ||
}), comma && (syntaxHighlightEnabled ? /*#__PURE__*/ React__namespace.createElement("span", { | ||
className: "token punctuation" | ||
}, ",") : ',')); | ||
const renderLine = (index, syntaxHighlightEnabled)=>{ | ||
var _props_bgColour, _props_bgColour1; | ||
const l = linesLeftRef.current[index]; | ||
const r = linesRightRef.current[index]; | ||
const [lText, rText] = props.highlightInlineDiff && l.type === 'modify' && r.type === 'modify' ? renderInlineDiffResult(getInlineDiff(l.text, r.text, inlineDiffOptions)) : [ | ||
l.text, | ||
r.text | ||
const [lDiff, rDiff] = props.highlightInlineDiff && l.type === 'modify' && r.type === 'modify' ? getInlineDiff(l.text, r.text, inlineDiffOptions) : [ | ||
[], | ||
[] | ||
]; | ||
const lTokens = syntaxHighlightLine(syntaxHighlightEnabled, l.text, 0); | ||
const rTokens = syntaxHighlightLine(syntaxHighlightEnabled, r.text, 0); | ||
const lResult = mergeSegments(lTokens, lDiff); | ||
const rResult = mergeSegments(rTokens, rDiff); | ||
var _props_bgColour_l_type; | ||
const bgColourL = l.type !== 'equal' ? (_props_bgColour_l_type = (_props_bgColour = props.bgColour) == null ? void 0 : _props_bgColour[l.type]) != null ? _props_bgColour_l_type : '' : ''; | ||
const bgLeft = l.type !== 'equal' ? (_props_bgColour_l_type = (_props_bgColour = props.bgColour) == null ? void 0 : _props_bgColour[l.type]) != null ? _props_bgColour_l_type : '' : ''; | ||
var _props_bgColour_r_type; | ||
const bgColourR = r.type !== 'equal' ? (_props_bgColour_r_type = (_props_bgColour1 = props.bgColour) == null ? void 0 : _props_bgColour1[r.type]) != null ? _props_bgColour_r_type : '' : ''; | ||
const bgRight = r.type !== 'equal' ? (_props_bgColour_r_type = (_props_bgColour1 = props.bgColour) == null ? void 0 : _props_bgColour1[r.type]) != null ? _props_bgColour_r_type : '' : ''; | ||
return(// eslint-disable-next-line react/no-array-index-key | ||
@@ -823,3 +994,3 @@ /*#__PURE__*/ React__namespace.createElement("tr", { | ||
style: { | ||
backgroundColor: bgColourL | ||
backgroundColor: bgLeft | ||
} | ||
@@ -829,8 +1000,8 @@ }, l.lineNumber), /*#__PURE__*/ React__namespace.createElement("td", { | ||
style: { | ||
backgroundColor: bgColourL | ||
backgroundColor: bgLeft | ||
} | ||
}, /*#__PURE__*/ React__namespace.createElement("pre", null, l.text && indentChar.repeat(l.level * indentSize), lText, l.comma && ',')), props.lineNumbers && /*#__PURE__*/ React__namespace.createElement("td", { | ||
}, /*#__PURE__*/ React__namespace.createElement("pre", null, l.text && indentChar.repeat(l.level * indentSize), renderInlineResult(l.text, lResult, l.comma, syntaxHighlightEnabled))), props.lineNumbers && /*#__PURE__*/ React__namespace.createElement("td", { | ||
className: `line-${r.type} line-number`, | ||
style: { | ||
backgroundColor: bgColourR | ||
backgroundColor: bgRight | ||
} | ||
@@ -840,5 +1011,5 @@ }, r.lineNumber), /*#__PURE__*/ React__namespace.createElement("td", { | ||
style: { | ||
backgroundColor: bgColourR | ||
backgroundColor: bgRight | ||
} | ||
}, /*#__PURE__*/ React__namespace.createElement("pre", null, r.text && indentChar.repeat(r.level * indentSize), rText, r.comma && ',')))); | ||
}, /*#__PURE__*/ React__namespace.createElement("pre", null, r.text && indentChar.repeat(r.level * indentSize), renderInlineResult(r.text, rResult, r.comma, syntaxHighlightEnabled))))); | ||
}; | ||
@@ -854,3 +1025,3 @@ const renderExpandLine = (hasLinesBefore, hasLinesAfter, expandMoreLinesLimit, index)=>{ | ||
}; | ||
const renderSegment = (segment, index, renderStart, renderEnd)=>{ | ||
const renderSegment = (segment, index, renderStart, renderEnd, syntaxHighlightEnabled)=>{ | ||
let { start , end } = segment; | ||
@@ -863,6 +1034,6 @@ start = Math.max(start, renderStart); | ||
if (!isExpandLine(segment)) { | ||
return Array(end - start).fill(0).map((_, index)=>renderLine(start + index)); | ||
return Array(end - start).fill(0).map((_, index)=>renderLine(start + index, syntaxHighlightEnabled)); | ||
} | ||
const { hasLinesBefore , hasLinesAfter } = segment; | ||
const expandMoreLinesLimit = typeof hideUnchangedLines === 'boolean' ? DEFAULT_EXPAND_MORE_LINES_LIMIT : hideUnchangedLines.expandMoreLinesLimit; | ||
const expandMoreLinesLimit = typeof hideUnchangedLines === 'boolean' ? DEFAULT_EXPAND_MORE_LINES_LIMIT : hideUnchangedLines.expandMoreLinesLimit || DEFAULT_EXPAND_MORE_LINES_LIMIT; | ||
return [ | ||
@@ -884,5 +1055,5 @@ /*#__PURE__*/ React__namespace.createElement("tr", { | ||
}; | ||
const renderTbody = ()=>{ | ||
const renderTbody = (syntaxHighlightEnabled)=>{ | ||
if (!props.virtual) { | ||
return segmentsRef.current.map((item, index)=>renderSegment(item, index, 0, linesLeftRef.current.length)); | ||
return segmentsRef.current.map((item, index)=>renderSegment(item, index, 0, linesLeftRef.current.length, syntaxHighlightEnabled)); | ||
} | ||
@@ -920,3 +1091,3 @@ var _scrollContainer_clientHeight; | ||
} | ||
})), visibleSegments.map((segment, index)=>renderSegment(segment, index, startLine, endLine)), /*#__PURE__*/ React__namespace.createElement("tr", null, /*#__PURE__*/ React__namespace.createElement("td", { | ||
})), visibleSegments.map((segment, index)=>renderSegment(segment, index, startLine, endLine, syntaxHighlightEnabled)), /*#__PURE__*/ React__namespace.createElement("tr", null, /*#__PURE__*/ React__namespace.createElement("td", { | ||
colSpan: 4, | ||
@@ -945,8 +1116,15 @@ style: { | ||
}), /*#__PURE__*/ React__namespace.createElement("col", null)); | ||
const classes = [ | ||
'json-diff-viewer', | ||
props.virtual && 'json-diff-viewer-virtual', | ||
props.syntaxHighlight && `json-diff-viewer-theme-${props.syntaxHighlight.theme || 'monokai'}`, | ||
props.className | ||
].filter(Boolean).join(' '); | ||
const syntaxHighlightEnabled = !!props.syntaxHighlight; | ||
return /*#__PURE__*/ React__namespace.createElement("table", { | ||
className: `json-diff-viewer ${props.virtual ? 'json-diff-viewer-virtual' : ''} ${props.className || ''}`, | ||
className: classes, | ||
style: props.style | ||
}, renderMeasureLine(), /*#__PURE__*/ React__namespace.createElement("tbody", { | ||
ref: tbodyRef | ||
}, renderTbody())); | ||
}, renderTbody(syntaxHighlightEnabled))); | ||
}; | ||
@@ -953,0 +1131,0 @@ Viewer.displayName = 'Viewer'; |
import * as React from 'react'; | ||
function _extends$1() { | ||
_extends$1 = Object.assign || function(target) { | ||
for(var i = 1; i < arguments.length; i++){ | ||
var source = arguments[i]; | ||
for(var key in source){ | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends$1.apply(this, arguments); | ||
} | ||
const isExpandLine = (segment)=>{ | ||
@@ -9,2 +23,48 @@ return 'hasLinesBefore' in segment || 'hasLinesAfter' in segment; | ||
}; | ||
/** | ||
* Merge two segments array into one, divide the segment if necessary. | ||
*/ const mergeSegments = (tokens, diffs)=>{ | ||
const result = []; | ||
let token; | ||
let diff; | ||
if (tokens.length && diffs.length) { | ||
tokens = [ | ||
...tokens | ||
]; | ||
diffs = [ | ||
...diffs | ||
]; | ||
token = _extends$1({}, tokens.shift()); | ||
diff = _extends$1({}, diffs.shift()); | ||
while(1){ | ||
if (token.start === diff.start) { | ||
const end = Math.min(token.end, diff.end); | ||
result.push(_extends$1({}, token, diff, { | ||
end | ||
})); | ||
token.start = diff.start = end; | ||
} else if (token.start < diff.start) { | ||
const end = Math.min(token.end, diff.start); | ||
result.push(_extends$1({}, diff, token, { | ||
end | ||
})); | ||
token.start = end; | ||
} else { | ||
const end = Math.min(token.start, diff.end); | ||
result.push(_extends$1({}, token, diff, { | ||
end | ||
})); | ||
diff.start = end; | ||
} | ||
if (!tokens.length || !diffs.length) break; | ||
if (token.start === token.end) token = _extends$1({}, tokens.shift()); | ||
if (diff.start === diff.end) diff = _extends$1({}, diffs.shift()); | ||
} | ||
} | ||
if (!tokens.length) result.push(...diffs.map((d)=>_extends$1({}, d, { | ||
token: token.token || 'plain' | ||
}))); | ||
if (!diffs.length) result.push(...tokens); | ||
return result; | ||
}; | ||
@@ -376,50 +436,35 @@ const calculatePlaceholderHeight = (segments, accTop, startSegment, startLine, endSegment, endLine, itemHeight, expandLineHeight, totalHeight)=>{ | ||
function _extends$1() { | ||
_extends$1 = Object.assign || function(target) { | ||
for(var i = 1; i < arguments.length; i++){ | ||
var source = arguments[i]; | ||
for(var key in source){ | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends$1.apply(this, arguments); | ||
} | ||
const filterEmptyParts = (arr)=>{ | ||
return arr.filter((item)=>item.text.length); | ||
}; | ||
const joinBySeparator = (arr, separator)=>{ | ||
if (!arr.length) { | ||
return arr; | ||
} | ||
const getOriginalIndices = (arr, separatorLength)=>{ | ||
const result = []; | ||
for(let i = 0; i < arr.length; i++){ | ||
if (result.length && arr[i].text.length) { | ||
if (result[result.length - 1].type === 'equal') { | ||
result[result.length - 1] = _extends$1({}, result[result.length - 1], { | ||
text: result[result.length - 1].text + separator | ||
}); | ||
} else { | ||
result.push({ | ||
type: 'equal', | ||
text: separator | ||
}); | ||
} | ||
} | ||
result.push(arr[i]); | ||
let index = 0; | ||
for (const item of arr){ | ||
result.push(index); | ||
index += item.length + separatorLength; | ||
} | ||
result.push(index - separatorLength); | ||
return result; | ||
}; | ||
const filterEmptyParts = (arr)=>{ | ||
return arr.filter((item)=>item.end > item.start); | ||
}; | ||
const getInlineDiff = (l, r, options)=>{ | ||
let resultL = []; | ||
let resultR = []; | ||
let lastL = 0; | ||
let lastR = 0; | ||
if (options.mode === 'word') { | ||
const lArr = l.split(options.wordSeparator); | ||
const rArr = r.split(options.wordSeparator); | ||
const iter = lcs_1(lArr, rArr); | ||
let resultL = []; | ||
let resultR = []; | ||
let lastL = 0; | ||
let lastR = 0; | ||
const wordSeparator = options.wordSeparator || ' '; | ||
const lArr = l.split(wordSeparator); | ||
const rArr = r.split(wordSeparator); | ||
/** | ||
* The iter array contains the information about replacement, which is an array of | ||
* tuple `[startL, startR, length]`. | ||
* | ||
* e.g. `[1, 2, 3]` means replace `lArr[1...1+3]` to `rArr[2...2+3]` (include the end). | ||
*/ const iter = [ | ||
...lcs_1(lArr, rArr) | ||
]; | ||
const separatorLength = wordSeparator.length; | ||
const indicesL = getOriginalIndices(lArr, separatorLength); | ||
const indicesR = getOriginalIndices(rArr, separatorLength); | ||
for (const [sl, sr, length] of iter){ | ||
@@ -429,3 +474,4 @@ if (sl > lastL) { | ||
type: 'remove', | ||
text: lArr.slice(lastL, sl).join(options.wordSeparator) | ||
start: indicesL[lastL], | ||
end: indicesL[sl] | ||
}); | ||
@@ -436,3 +482,4 @@ } | ||
type: 'add', | ||
text: rArr.slice(lastR, sr).join(options.wordSeparator) | ||
start: indicesR[lastR], | ||
end: indicesR[sr] | ||
}); | ||
@@ -443,8 +490,8 @@ } | ||
resultL.push({ | ||
type: 'equal', | ||
text: lArr.slice(sl, lastL).join(options.wordSeparator) | ||
start: indicesL[sl], | ||
end: indicesL[lastL] | ||
}); | ||
resultR.push({ | ||
type: 'equal', | ||
text: rArr.slice(sr, lastR).join(options.wordSeparator) | ||
start: indicesR[sr], | ||
end: indicesR[lastR] | ||
}); | ||
@@ -455,3 +502,4 @@ } | ||
type: 'remove', | ||
text: lArr.slice(lastL).join(options.wordSeparator) | ||
start: indicesL[lastL], | ||
end: l.length | ||
}); | ||
@@ -462,7 +510,8 @@ } | ||
type: 'add', | ||
text: rArr.slice(lastR).join(options.wordSeparator) | ||
start: indicesR[lastR], | ||
end: r.length | ||
}); | ||
} | ||
resultL = joinBySeparator(filterEmptyParts(resultL), options.wordSeparator); | ||
resultR = joinBySeparator(filterEmptyParts(resultR), options.wordSeparator); | ||
resultL = filterEmptyParts(resultL); | ||
resultR = filterEmptyParts(resultR); | ||
return [ | ||
@@ -474,6 +523,2 @@ resultL, | ||
const iter = lcs_1(l, r); | ||
let resultL = []; | ||
let resultR = []; | ||
let lastL = 0; | ||
let lastR = 0; | ||
for (const [sl, sr, length] of iter){ | ||
@@ -483,3 +528,4 @@ if (sl > lastL) { | ||
type: 'remove', | ||
text: l.substring(lastL, sl) | ||
start: lastL, | ||
end: sl | ||
}); | ||
@@ -490,3 +536,4 @@ } | ||
type: 'add', | ||
text: r.substring(lastR, sr) | ||
start: lastR, | ||
end: sr | ||
}); | ||
@@ -497,8 +544,8 @@ } | ||
resultL.push({ | ||
type: 'equal', | ||
text: l.substring(sl, lastL) | ||
start: sl, | ||
end: lastL | ||
}); | ||
resultR.push({ | ||
type: 'equal', | ||
text: r.substring(sr, lastR) | ||
start: sr, | ||
end: lastR | ||
}); | ||
@@ -509,3 +556,4 @@ } | ||
type: 'remove', | ||
text: l.substring(lastL) | ||
start: lastL, | ||
end: l.length | ||
}); | ||
@@ -516,3 +564,4 @@ } | ||
type: 'add', | ||
text: r.substring(lastR) | ||
start: lastR, | ||
end: r.length | ||
}); | ||
@@ -528,2 +577,117 @@ } | ||
const syntaxHighlightLine = (enabled, text, offset)=>{ | ||
if (!enabled) { | ||
return [ | ||
{ | ||
token: 'plain', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
if (!Number.isNaN(Number(text))) { | ||
return [ | ||
{ | ||
token: 'number', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
if (text === 'true' || text === 'false') { | ||
return [ | ||
{ | ||
token: 'boolean', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
if (text === 'null') { | ||
return [ | ||
{ | ||
token: 'null', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
if (text.startsWith('"')) { | ||
if (text.endsWith(': [') || text.endsWith(': {')) { | ||
return [ | ||
{ | ||
token: 'key', | ||
start: offset, | ||
end: text.length - 3 + offset | ||
}, | ||
{ | ||
token: 'punctuation', | ||
start: text.length - 3, | ||
end: text.length - 2 + offset | ||
}, | ||
{ | ||
token: 'plain', | ||
start: text.length - 2, | ||
end: text.length - 1 + offset | ||
}, | ||
{ | ||
token: 'punctuation', | ||
start: text.length - 1, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
let pairedQuoteIndex = 1; | ||
while(pairedQuoteIndex < text.length){ | ||
if (text[pairedQuoteIndex] === '"') break; | ||
if (text[pairedQuoteIndex] === '\\') ++pairedQuoteIndex; | ||
++pairedQuoteIndex; | ||
} | ||
if (pairedQuoteIndex === text.length - 1) { | ||
return [ | ||
{ | ||
token: 'string', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
return [ | ||
{ | ||
token: 'key', | ||
start: offset, | ||
end: pairedQuoteIndex + 1 + offset | ||
}, | ||
{ | ||
token: 'punctuation', | ||
start: pairedQuoteIndex + 1, | ||
end: pairedQuoteIndex + 2 + offset | ||
}, | ||
{ | ||
token: 'plain', | ||
start: pairedQuoteIndex + 2, | ||
end: pairedQuoteIndex + 3 + offset | ||
}, | ||
...syntaxHighlightLine(enabled, text.substring(pairedQuoteIndex + 3), offset + pairedQuoteIndex + 3) | ||
]; | ||
} | ||
if (text === '{' || text === '}' || text === '[' || text === ']') { | ||
return [ | ||
{ | ||
token: 'punctuation', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
} | ||
// should this be expected? | ||
return [ | ||
{ | ||
token: 'plain', | ||
start: offset, | ||
end: text.length + offset | ||
} | ||
]; | ||
}; | ||
const defaultOptions = { | ||
@@ -768,27 +932,34 @@ threshold: 8, | ||
}; | ||
const renderInlineDiffResult = (arr)=>{ | ||
return arr.map((result)=>result.map((item, index)=>{ | ||
if (item.type === 'equal') { | ||
return /*#__PURE__*/ React.createElement("span", { | ||
key: `${index}-${item.type}-${item.text}` | ||
}, item.text); | ||
} | ||
return /*#__PURE__*/ React.createElement("span", { | ||
key: `${index}-${item.type}-${item.text}`, | ||
className: `inline-diff-${item.type}` | ||
}, item.text); | ||
})); | ||
}; | ||
const renderLine = (index)=>{ | ||
const renderInlineResult = (text, info = [], comma = false, syntaxHighlightEnabled = false)=>/*#__PURE__*/ React.createElement(React.Fragment, null, info.map((item, index)=>{ | ||
const frag = text.slice(item.start, item.end); | ||
if (!item.type && !item.token) { | ||
return frag; | ||
} | ||
const className = [ | ||
item.type ? `inline-diff-${item.type}` : '', | ||
item.token ? `token ${item.token}` : '' | ||
].filter(Boolean).join(' '); | ||
return /*#__PURE__*/ React.createElement("span", { | ||
key: `${index}-${item.type}-${frag}`, | ||
className: className | ||
}, frag); | ||
}), comma && (syntaxHighlightEnabled ? /*#__PURE__*/ React.createElement("span", { | ||
className: "token punctuation" | ||
}, ",") : ',')); | ||
const renderLine = (index, syntaxHighlightEnabled)=>{ | ||
var _props_bgColour, _props_bgColour1; | ||
const l = linesLeftRef.current[index]; | ||
const r = linesRightRef.current[index]; | ||
const [lText, rText] = props.highlightInlineDiff && l.type === 'modify' && r.type === 'modify' ? renderInlineDiffResult(getInlineDiff(l.text, r.text, inlineDiffOptions)) : [ | ||
l.text, | ||
r.text | ||
const [lDiff, rDiff] = props.highlightInlineDiff && l.type === 'modify' && r.type === 'modify' ? getInlineDiff(l.text, r.text, inlineDiffOptions) : [ | ||
[], | ||
[] | ||
]; | ||
const lTokens = syntaxHighlightLine(syntaxHighlightEnabled, l.text, 0); | ||
const rTokens = syntaxHighlightLine(syntaxHighlightEnabled, r.text, 0); | ||
const lResult = mergeSegments(lTokens, lDiff); | ||
const rResult = mergeSegments(rTokens, rDiff); | ||
var _props_bgColour_l_type; | ||
const bgColourL = l.type !== 'equal' ? (_props_bgColour_l_type = (_props_bgColour = props.bgColour) == null ? void 0 : _props_bgColour[l.type]) != null ? _props_bgColour_l_type : '' : ''; | ||
const bgLeft = l.type !== 'equal' ? (_props_bgColour_l_type = (_props_bgColour = props.bgColour) == null ? void 0 : _props_bgColour[l.type]) != null ? _props_bgColour_l_type : '' : ''; | ||
var _props_bgColour_r_type; | ||
const bgColourR = r.type !== 'equal' ? (_props_bgColour_r_type = (_props_bgColour1 = props.bgColour) == null ? void 0 : _props_bgColour1[r.type]) != null ? _props_bgColour_r_type : '' : ''; | ||
const bgRight = r.type !== 'equal' ? (_props_bgColour_r_type = (_props_bgColour1 = props.bgColour) == null ? void 0 : _props_bgColour1[r.type]) != null ? _props_bgColour_r_type : '' : ''; | ||
return(// eslint-disable-next-line react/no-array-index-key | ||
@@ -800,3 +971,3 @@ /*#__PURE__*/ React.createElement("tr", { | ||
style: { | ||
backgroundColor: bgColourL | ||
backgroundColor: bgLeft | ||
} | ||
@@ -806,8 +977,8 @@ }, l.lineNumber), /*#__PURE__*/ React.createElement("td", { | ||
style: { | ||
backgroundColor: bgColourL | ||
backgroundColor: bgLeft | ||
} | ||
}, /*#__PURE__*/ React.createElement("pre", null, l.text && indentChar.repeat(l.level * indentSize), lText, l.comma && ',')), props.lineNumbers && /*#__PURE__*/ React.createElement("td", { | ||
}, /*#__PURE__*/ React.createElement("pre", null, l.text && indentChar.repeat(l.level * indentSize), renderInlineResult(l.text, lResult, l.comma, syntaxHighlightEnabled))), props.lineNumbers && /*#__PURE__*/ React.createElement("td", { | ||
className: `line-${r.type} line-number`, | ||
style: { | ||
backgroundColor: bgColourR | ||
backgroundColor: bgRight | ||
} | ||
@@ -817,5 +988,5 @@ }, r.lineNumber), /*#__PURE__*/ React.createElement("td", { | ||
style: { | ||
backgroundColor: bgColourR | ||
backgroundColor: bgRight | ||
} | ||
}, /*#__PURE__*/ React.createElement("pre", null, r.text && indentChar.repeat(r.level * indentSize), rText, r.comma && ',')))); | ||
}, /*#__PURE__*/ React.createElement("pre", null, r.text && indentChar.repeat(r.level * indentSize), renderInlineResult(r.text, rResult, r.comma, syntaxHighlightEnabled))))); | ||
}; | ||
@@ -831,3 +1002,3 @@ const renderExpandLine = (hasLinesBefore, hasLinesAfter, expandMoreLinesLimit, index)=>{ | ||
}; | ||
const renderSegment = (segment, index, renderStart, renderEnd)=>{ | ||
const renderSegment = (segment, index, renderStart, renderEnd, syntaxHighlightEnabled)=>{ | ||
let { start , end } = segment; | ||
@@ -840,6 +1011,6 @@ start = Math.max(start, renderStart); | ||
if (!isExpandLine(segment)) { | ||
return Array(end - start).fill(0).map((_, index)=>renderLine(start + index)); | ||
return Array(end - start).fill(0).map((_, index)=>renderLine(start + index, syntaxHighlightEnabled)); | ||
} | ||
const { hasLinesBefore , hasLinesAfter } = segment; | ||
const expandMoreLinesLimit = typeof hideUnchangedLines === 'boolean' ? DEFAULT_EXPAND_MORE_LINES_LIMIT : hideUnchangedLines.expandMoreLinesLimit; | ||
const expandMoreLinesLimit = typeof hideUnchangedLines === 'boolean' ? DEFAULT_EXPAND_MORE_LINES_LIMIT : hideUnchangedLines.expandMoreLinesLimit || DEFAULT_EXPAND_MORE_LINES_LIMIT; | ||
return [ | ||
@@ -861,5 +1032,5 @@ /*#__PURE__*/ React.createElement("tr", { | ||
}; | ||
const renderTbody = ()=>{ | ||
const renderTbody = (syntaxHighlightEnabled)=>{ | ||
if (!props.virtual) { | ||
return segmentsRef.current.map((item, index)=>renderSegment(item, index, 0, linesLeftRef.current.length)); | ||
return segmentsRef.current.map((item, index)=>renderSegment(item, index, 0, linesLeftRef.current.length, syntaxHighlightEnabled)); | ||
} | ||
@@ -897,3 +1068,3 @@ var _scrollContainer_clientHeight; | ||
} | ||
})), visibleSegments.map((segment, index)=>renderSegment(segment, index, startLine, endLine)), /*#__PURE__*/ React.createElement("tr", null, /*#__PURE__*/ React.createElement("td", { | ||
})), visibleSegments.map((segment, index)=>renderSegment(segment, index, startLine, endLine, syntaxHighlightEnabled)), /*#__PURE__*/ React.createElement("tr", null, /*#__PURE__*/ React.createElement("td", { | ||
colSpan: 4, | ||
@@ -922,8 +1093,15 @@ style: { | ||
}), /*#__PURE__*/ React.createElement("col", null)); | ||
const classes = [ | ||
'json-diff-viewer', | ||
props.virtual && 'json-diff-viewer-virtual', | ||
props.syntaxHighlight && `json-diff-viewer-theme-${props.syntaxHighlight.theme || 'monokai'}`, | ||
props.className | ||
].filter(Boolean).join(' '); | ||
const syntaxHighlightEnabled = !!props.syntaxHighlight; | ||
return /*#__PURE__*/ React.createElement("table", { | ||
className: `json-diff-viewer ${props.virtual ? 'json-diff-viewer-virtual' : ''} ${props.className || ''}`, | ||
className: classes, | ||
style: props.style | ||
}, renderMeasureLine(), /*#__PURE__*/ React.createElement("tbody", { | ||
ref: tbodyRef | ||
}, renderTbody())); | ||
}, renderTbody(syntaxHighlightEnabled))); | ||
}; | ||
@@ -930,0 +1108,0 @@ Viewer.displayName = 'Viewer'; |
{ | ||
"name": "json-diff-kit", | ||
"version": "1.0.15", | ||
"version": "1.0.16", | ||
"description": "A better JSON differ & viewer.", | ||
@@ -61,3 +61,3 @@ "main": "dist/cjs/index.js", | ||
"build:ts": "cross-env rollup -c", | ||
"build:less": "cross-env lessc src/viewer.less dist/viewer.css", | ||
"build:less": "cross-env lessc src/viewer.less dist/viewer.css && lessc src/viewer-monokai.less dist/viewer-monokai.css", | ||
"build:pages": "cross-env NODE_ENV=production BASEDIR=docs rollup -c rollup.config.pages.ts", | ||
@@ -64,0 +64,0 @@ "prepublish": "cross-env pnpm build" |
@@ -49,3 +49,6 @@ import commonjs from '@rollup/plugin-commonjs'; | ||
}), | ||
swc({ minify: process.env.NODE_ENV === 'production' }), | ||
swc({ | ||
minify: process.env.NODE_ENV === 'production', | ||
sourceMaps: process.env.NODE_ENV !== 'production', | ||
}), | ||
]; | ||
@@ -78,4 +81,5 @@ | ||
}, | ||
sourcemap: process.env.NODE_ENV !== 'production', | ||
}, | ||
plugins, | ||
}; |
@@ -14,2 +14,3 @@ { | ||
"sourceMap": true, | ||
"strictNullChecks": true, | ||
"target": "esnext", | ||
@@ -16,0 +17,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
781096
63
11094
0