Compare commits
1 Commits
fix-non-le
...
feat-permi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
116b014c55 |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,17 +1,3 @@
|
||||
# [5.3.0](https://github.com/wickedest/Mergely/compare/v5.2.0...v5.3.0) (2024-06-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Supports unicode diacritical marks when rendering line diff (fixes [#169](https://github.com/wickedest/Mergely/issues/169)) ([#197](https://github.com/wickedest/Mergely/issues/197)) ([a469a65](https://github.com/wickedest/Mergely/commit/a469a6510122356a7cae3fb1259e999e6cc34c94))
|
||||
|
||||
# [5.2.0](https://github.com/wickedest/Mergely/compare/v5.1.4...v5.2.0) (2024-06-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Allows height to be not explicit height, e.g. 'inherit' or '100%' ([#196](https://github.com/wickedest/Mergely/issues/196)) ([b9e3641](https://github.com/wickedest/Mergely/commit/b9e3641c852a8926db5efdf33e65a607d5f2df5e))
|
||||
|
||||
## [5.1.4](https://github.com/wickedest/Mergely/compare/v5.1.3...v5.1.4) (2024-05-17)
|
||||
|
||||
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "mergely",
|
||||
"version": "5.3.0",
|
||||
"version": "5.1.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mergely",
|
||||
"version": "5.3.0",
|
||||
"version": "5.1.4",
|
||||
"license": "(GPL-3.0 OR LGPL-3.0 OR MPL-1.1 OR SEE LICENSE IN LICENSE)",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.1.6",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mergely",
|
||||
"version": "5.3.0",
|
||||
"version": "5.1.4",
|
||||
"description": "A javascript UI for diff/merge",
|
||||
"license": "(GPL-3.0 OR LGPL-3.0 OR MPL-1.1 OR SEE LICENSE IN LICENSE)",
|
||||
"author": {
|
||||
|
||||
10
src/diff.js
10
src/diff.js
@@ -241,14 +241,10 @@ function CodeifyText(lhs, rhs, options) {
|
||||
this.ctxs = {};
|
||||
this.options = options;
|
||||
this.options.split = this.options.split || 'lines';
|
||||
const exp = /\p{Letter}\p{Mark}*|\p{Number}\p{Mark}*|\p{Punctuation}\p{Mark}*|\p{Symbol}\p{Mark}*|\p{White_Space}/gu;
|
||||
|
||||
if (typeof lhs === 'string') {
|
||||
if (this.options.split === 'chars') {
|
||||
console.log('HERE')
|
||||
// split characters and include their diacritical marks
|
||||
this.lhs = lhs.match(exp) || [];
|
||||
// this.lhs = [...lhs];
|
||||
this.lhs = lhs.split('');
|
||||
} else if (this.options.split === 'words') {
|
||||
this.lhs = lhs.split(/\s/);
|
||||
} else if (this.options.split === 'lines') {
|
||||
@@ -259,9 +255,7 @@ function CodeifyText(lhs, rhs, options) {
|
||||
}
|
||||
if (typeof rhs === 'string') {
|
||||
if (this.options.split === 'chars') {
|
||||
// split characters and include their diacritical marks
|
||||
this.rhs = rhs.match(exp) || [];
|
||||
// this.rhs = [...rhs];
|
||||
this.rhs = rhs.split('');
|
||||
} else if (this.options.split === 'words') {
|
||||
this.rhs = rhs.split(/\s/);
|
||||
} else if (this.options.split === 'lines') {
|
||||
|
||||
22
src/vdoc.js
22
src/vdoc.js
@@ -2,10 +2,6 @@ const diff = require('./diff');
|
||||
|
||||
const trace = console.log;
|
||||
|
||||
const expLetters = new RegExp(
|
||||
/\p{Letter}\p{Mark}*|\p{Number}\p{Mark}*|\p{Punctuation}\p{Mark}*|\p{Symbol}\p{Mark}*|\p{White_Space}/gu
|
||||
);
|
||||
|
||||
class VDoc {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
@@ -279,18 +275,15 @@ class VLine {
|
||||
editor.setGutterMarker(this.id, name, item);
|
||||
}
|
||||
if (this.markup.length) {
|
||||
// while Mergely diffs unicode chars (letters+mark), CM is by character,
|
||||
// so diffs need to be mapped.
|
||||
const mapped = mapLettersToChars(editor.getValue());
|
||||
for (const markup of this.markup) {
|
||||
const [ charFrom, charTo, className ] = markup;
|
||||
const fromPos = { line: this.id };
|
||||
const toPos = { line: this.id };
|
||||
if (charFrom >= 0) {
|
||||
fromPos.ch = mapped[charFrom];
|
||||
fromPos.ch = charFrom;
|
||||
}
|
||||
if (charTo >= 0) {
|
||||
toPos.ch = mapped[charTo];
|
||||
toPos.ch = charTo;
|
||||
}
|
||||
this._clearMarkup.push(
|
||||
editor.markText(fromPos, toPos, { className }));
|
||||
@@ -341,15 +334,4 @@ function getExtents(side, change) {
|
||||
};
|
||||
}
|
||||
|
||||
function mapLettersToChars(text) {
|
||||
let match;
|
||||
let mapped = {};
|
||||
let index = 0;
|
||||
expLetters.lastIndex = 0;
|
||||
while ((match = expLetters.exec(text)) !== null) {
|
||||
mapped[index++] = match.index;
|
||||
}
|
||||
return mapped;
|
||||
}
|
||||
|
||||
module.exports = VDoc;
|
||||
|
||||
@@ -42,7 +42,6 @@ describe('markup', () => {
|
||||
|
||||
const LHS_CHANGE_START = '.mergely.lhs.c.CodeMirror-linebackground.start';
|
||||
const LHS_CHANGE_END = '.mergely.lhs.c.CodeMirror-linebackground.end';
|
||||
const LHS_CHANGE_START_AND_END = '.mergely.lhs.c.CodeMirror-linebackground.start.end';
|
||||
const RHS_CHANGE_START = '.mergely.rhs.c.CodeMirror-linebackground.start';
|
||||
const RHS_CHANGE_END = '.mergely.rhs.c.CodeMirror-linebackground.end';
|
||||
|
||||
@@ -234,133 +233,7 @@ describe('markup', () => {
|
||||
expect(rhs_spans[1].innerText).to.equal('h');
|
||||
expect(rhs_spans[2].innerText).to.equal('ir');
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'single word single diacritic non-spacing marks',
|
||||
lhs: 'كلمة',
|
||||
rhs: 'كَلمة',
|
||||
check: (editor) => {
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
const lhs_spans = editor.querySelectorAll(LHS_INLINE_TEXT + '.cid-0');
|
||||
expect(lhs_spans).to.have.length(1);
|
||||
expect(lhs_spans[0].innerText).to.equal('ك');
|
||||
const rhs_spans = editor.querySelectorAll(RHS_INLINE_TEXT + '.cid-0');
|
||||
expect(rhs_spans).to.have.length(1);
|
||||
expect(rhs_spans[0].innerText).to.equal('كَ');
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'single word multiple diacritic non-spacing marks',
|
||||
lhs: ['\u006E', '\u0061', '\u0314', '\u0065'].join(''), // na̔e
|
||||
rhs: ['\u006E', '\u0061', '\u0314', '\u034A', '\u0065'].join(''), // na̔͊e
|
||||
check: (editor) => {
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
const lhs_spans = editor.querySelectorAll(LHS_INLINE_TEXT + '.cid-0');
|
||||
expect(lhs_spans).to.have.length(1);
|
||||
expect(lhs_spans[0].innerText).to.equal(['\u0061', '\u0314'].join(''));
|
||||
const rhs_spans = editor.querySelectorAll(RHS_INLINE_TEXT + '.cid-0');
|
||||
expect(rhs_spans).to.have.length(1);
|
||||
expect(rhs_spans[0].innerText).to.equal('a̔͊');
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'multiple words diacritic non-spacing marks',
|
||||
lhs: 'كلمة اخرى',
|
||||
rhs: 'كْلمة اخرى',
|
||||
check: (editor) => {
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
const lhs_spans = editor.querySelectorAll(LHS_INLINE_TEXT + '.cid-0');
|
||||
expect(lhs_spans).to.have.length(1);
|
||||
expect(lhs_spans[0].innerText).to.equal('ك');
|
||||
const rhs_spans = editor.querySelectorAll(RHS_INLINE_TEXT + '.cid-0');
|
||||
expect(rhs_spans).to.have.length(1);
|
||||
expect(rhs_spans[0].innerText).to.equal('كْ');
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'nonnormalizable diacritic non-spacing marks',
|
||||
lhs: 'naeg',
|
||||
// there are 2 marks on 'e', tilde (0303) and x (0353)
|
||||
rhs: ['\u006E', '\u0061', '\u0353', '\u0065', '\u0353', '\u0303', '\u0067'].join(''),
|
||||
check: (editor) => {
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
const lhs_spans = editor.querySelectorAll(LHS_INLINE_TEXT + '.cid-0');
|
||||
expect(lhs_spans).to.have.length(1);
|
||||
expect(lhs_spans[0].innerText).to.equal('ae');
|
||||
const rhs_spans = editor.querySelectorAll(RHS_INLINE_TEXT + '.cid-0');
|
||||
expect(rhs_spans).to.have.length(1);
|
||||
expect(rhs_spans[0].innerText).to.equal(
|
||||
['\u0061', '\u0353', '\u0065', '\u0353', '\u0303'].join('')
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'nonnormalizable diacritic non-spacing marks',
|
||||
lhs: [
|
||||
'\u0065', '\u0353', '\u0303',
|
||||
'\u0065', '\u0353', '\u0303',
|
||||
'\u0065', '\u0353', '\u0303',
|
||||
'x',
|
||||
'\u0065', '\u0353', '\u0303',
|
||||
].join(''),
|
||||
// there are 2 marks on 'e', tilde (0303) and x (0353)
|
||||
rhs: [
|
||||
'\u0065', '\u0353', '\u0303',
|
||||
'\u0065', '\u0353', '\u0303',
|
||||
'\u0065', '\u0353', '\u0303',
|
||||
'y',
|
||||
'\u0065', '\u0353', '\u0303',
|
||||
].join(''),
|
||||
check: (editor) => {
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_START + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(RHS_CHANGE_END + '.cid-0')).to.have.length(1);
|
||||
const lhs_spans = editor.querySelectorAll(LHS_INLINE_TEXT + '.cid-0');
|
||||
expect(lhs_spans).to.have.length(1);
|
||||
expect(lhs_spans[0].innerText).to.equal('x');
|
||||
const rhs_spans = editor.querySelectorAll(RHS_INLINE_TEXT + '.cid-0');
|
||||
expect(rhs_spans).to.have.length(1);
|
||||
expect(rhs_spans[0].innerText).to.equal('y');
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Changes with non-letter chars',
|
||||
lhs: '~# 00 == ! (dog) \n',
|
||||
rhs: '~? 11 ++ ] (fox) .\n',
|
||||
only: true,
|
||||
check: (editor) => {
|
||||
expect(editor.querySelectorAll(LHS_CHANGE_START_AND_END + '.cid-0')).to.have.length(1);
|
||||
expect(editor.querySelectorAll(LHS_INLINE_TEXT + '.cid-0')).to.have.length(6);
|
||||
expect(editor.querySelectorAll(RHS_INLINE_TEXT + '.cid-0')).to.have.length(7);
|
||||
const lhs_changes = editor.querySelectorAll(LHS_INLINE_TEXT + '.cid-0');
|
||||
const rhs_changes = editor.querySelectorAll(RHS_INLINE_TEXT + '.cid-0');
|
||||
const lhs_values = [];
|
||||
for (const value of lhs_changes.values()) {
|
||||
lhs_values.push(value.innerText);
|
||||
}
|
||||
const rhs_values = [];
|
||||
for (const value of rhs_changes.values()) {
|
||||
rhs_values.push(value.innerText);
|
||||
}
|
||||
console.log(lhs_values);
|
||||
console.log(rhs_values);
|
||||
expect(lhs_values).to.deep.equal(['#', '00', '==', '!', 'd', 'g']);
|
||||
expect(rhs_values).to.deep.equal(['?', '11', '++', ']', 'f', 'x', '.']);
|
||||
}
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
// to debug, add `only: true` to the test `opts` above, and run `npm run debug`
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const path = require('path')
|
||||
const chalk = require('chalk');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
@@ -51,8 +50,8 @@ module.exports = {
|
||||
compiler.hooks.entryOption.tap('MyPlugin', (context, entry) => {
|
||||
console.log('-'.repeat(78));
|
||||
console.log('Applications:');
|
||||
console.log(chalk.bold(chalk.underline(chalk.cyan('http://localhost:8080/app.html'))));
|
||||
console.log(chalk.bold(chalk.underline(chalk.cyan('http://localhost:8080/app-styles.html'))));
|
||||
console.log('http://localhost:8080/app.html');
|
||||
console.log('http://localhost:8080/app-styles.html');
|
||||
console.log('-'.repeat(78));
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user