1
0
mirror of synced 2025-12-25 00:54:36 +08:00

Compare commits

...

5 Commits
4.1.2 ... 4.2.3

Author SHA1 Message Date
Jamie Peabody
747bcacf2c patch(#147): fixes selected change style issue (#148)
Co-authored-by: Jamie Peabody <jpeabody@axway.com>
2021-04-29 20:09:10 +01:00
Jamie Peabody
3830cff687 fixes initial change issue 2020-11-23 20:06:09 +00:00
Jamie Peabody
e38cd50037 bump 2020-10-15 20:47:22 +01:00
Jamie Peabody
85b02add89 chore: updated dependencies 2020-10-15 20:46:11 +01:00
Jamie Peabody
5a0cd15ddd feat(#132): added option to ignore accented characters (#136)
* feat(#132): added  option to ignore accented characters

* fixed lf

Co-authored-by: Jamie Peabody <jpeabody@axway.com>
2020-10-15 15:13:41 +01:00
8 changed files with 114 additions and 68 deletions

View File

@@ -1,5 +1,17 @@
# Changes
## 4.2.3
* patch: fixes [#147](https://github.com/wickedest/Mergely/issues/147). Fixes the css style for the currently selected change.
## 4.2.2:
* patch: fixes issue where initial change was not being set causing next/prev and merge actions to not work as expected.
## 4.2.1:
* chore: updated dependencies, cleared security issues
## 4.2.0:
* minor: added new option `ignoreaccents` to ignore accented characters.
## 4.1.2:
* patch: fixes issue #134 where the readme had broken links.

View File

@@ -99,7 +99,8 @@ $(document).ready(function () {
|<a name="fadein"></a>fadein|string|`fast`|A jQuery [fadein](http://api.jquery.com/fadein) value to enable the editor to fade in. Set to empty string to disable.|
|<a name="fgcolor"></a>fgcolor|string\|number\|object|`{a:'#4ba3fa', c:'#a3a3a3', d:'#ff7f7f', ca:'#4b73ff', cc:'#434343', cd:'#ff4f4f'}`|The foreground color that mergely marks changes with on the canvas. The value **a** is additions, **c** changes, **d** deletions, and the prefix *c* indicates current/active change (e.g. **cd** current delection).|
|<a name="ignorews"></a>ignorews|boolean|`false`|Ignores white-space.|
|<a name="ignorecase"></a>ignorecase|boolean|`false`|Ignores case when differientiating.
|<a name="ignorecase"></a>ignorecase|boolean|`false`|Ignores case when differientiating.|
|<a name="ignoreaccents"></a>ignorews|boolean|`false`|Ignores accented characters.|
|<a name="lcs"></a>lcs|boolean|`true`|Enables/disables LCS computation for paragraphs (word-by-word changes). Disabling can give a performance gain for large documents.|
|<a name="license"></a>license|string|`lgpl`|The choice of license to use with Mergely. Valid values are: `lgpl`, `gpl`, `mpl` or `lgpl-separate-notice`, `gpl-separate-notice`, `mpl-separate-notice` (the license requirements are met in a separate notice file).|
|<a name="line_numbers"></a>line_numbers|boolean|`true`|Enables/disables line numbers. Enabling line numbers will toggle the visibility of the line number margins.|

View File

@@ -53,11 +53,13 @@ module.exports = function(config) {
}
},
plugins: [
new CopyWebpackPlugin([{
from: 'src/mergely.css',
to: 'mergely.css',
toType: 'file'
}])
new CopyWebpackPlugin({
patterns: [{
from: 'src/mergely.css',
to: 'mergely.css',
toType: 'file'
}]
})
]
},
webpackServer: {

View File

@@ -1,6 +1,6 @@
{
"name": "mergely",
"version": "4.1.2",
"version": "4.2.3",
"description": "A javascript UI for diff/merge",
"directories": {
"doc": "doc",
@@ -36,34 +36,33 @@
"devDependencies": {
"@babel/core": "^7.1.6",
"@babel/preset-env": "^7.1.6",
"@webpack-cli/init": "^0.1.2",
"@webpack-cli/init": "^1.0.1",
"babel-loader": "^8.0.4",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"chai": "^4.1.2",
"codemirror": "^5.50.2",
"copy-webpack-plugin": "^4.6.0",
"css-loader": "^0.28.11",
"file-loader": "^1.1.5",
"html-webpack-plugin": "^3.2.0",
"image-webpack-loader": "^3.4.2",
"jquery": "^3.2.1",
"karma": "^3.1.1",
"copy-webpack-plugin": "^6.2.1",
"css-loader": "^5.0.0",
"file-loader": "^6.1.1",
"html-webpack-plugin": "^4.5.0",
"image-webpack-loader": "^7.0.1",
"jquery": "^3.5.1",
"karma": "^5.2.3",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-reporter": "^1.3.0",
"karma-mocha": "^1.3.0",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"karma-webpack": "^2.0.9",
"mocha": "^4.0.1",
"style-loader": "^0.23.0",
"uglifyjs-webpack-plugin": "^2.0.1",
"webpack": "^4.20.2",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.9"
"karma-webpack": "^4.0.2",
"mocha": "^8.1.3",
"style-loader": "^2.0.0",
"webpack": "^4.44.2",
"webpack-cli": "^4.0.0",
"webpack-dev-server": "^3.11.0"
},
"scripts": {
"build": "rm -rf lib && webpack --config ./webpack.prod.js",
"start": "webpack-dev-server -w --debug --progress --colors --config ./webpack.dev.js --content-base ./dist --inline --hot --host 0.0.0.0",
"start": "webpack serve --config webpack.dev.js",
"test": "karma start",
"test:chrome": "karma start --browsers Chrome --singleRun=false"
}

View File

@@ -41,15 +41,19 @@ Mgly.sizeOf = function(obj) {
return size;
};
Mgly.LCS = function(x, y) {
Mgly.LCS = function(x, y, options) {
this.x = (x && x.replace(/[ ]{1}/g, '\n')) || '';
this.y = (y && y.replace(/[ ]{1}/g, '\n')) || '';
this.options = options;
};
jQuery.extend(Mgly.LCS.prototype, {
clear: function() { this.ready = 0; },
diff: function(added, removed) {
var d = new Mgly.diff(this.x, this.y, {ignorews: false});
var d = new Mgly.diff(this.x, this.y, {
ignorews: false,
ignoreaccents: !!this.options.ignoreaccents
});
var changes = Mgly.DiffParser(d.normal_form());
var li = 0, lj = 0;
for (var i = 0; i < changes.length; ++i) {
@@ -86,7 +90,6 @@ Mgly.CodeifyText = function(settings) {
this._max_code = 0;
this._diff_codes = {};
this.ctxs = {};
this.options = {ignorews: false};
jQuery.extend(this, settings);
this.lhs = settings.lhs.split('\n');
this.rhs = settings.rhs.split('\n');
@@ -119,6 +122,9 @@ jQuery.extend(Mgly.CodeifyText.prototype, {
if (this.options.ignorecase) {
line = line.toLowerCase();
}
if (this.options.ignoreaccents) {
line = line.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
var aCode = this._diff_codes[line];
if (aCode != undefined) {
ctx.codes[i] = aCode;
@@ -133,7 +139,7 @@ jQuery.extend(Mgly.CodeifyText.prototype, {
});
Mgly.diff = function(lhs, rhs, options) {
var opts = jQuery.extend({ignorews: false}, options);
var opts = jQuery.extend({ignorews: false, ignoreaccents: false}, options);
this.codeify = new Mgly.CodeifyText({
lhs: lhs,
rhs: rhs,
@@ -385,6 +391,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
viewport: false,
ignorews: false,
ignorecase: false,
ignoreaccents: false,
fadein: 'fast',
resize_timeout: 500,
change_timeout: 150,
@@ -438,7 +445,6 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
_debug: '', //scroll,draw,calc,diff,markup,change,init
resized: function() { }
}, options);
// save this element for faster queries
this.element = jQuery(el);
@@ -499,7 +505,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
scrollToDiff: function(direction) {
if (!this.changes.length) return;
if (direction == 'next') {
if (this._current_diff == this.changes.length -1) {
if (this._current_diff == this.changes.length - 1) {
this._current_diff = 0;
} else {
this._current_diff = Math.min(++this._current_diff, this.changes.length - 1);
@@ -887,6 +893,11 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
this._skipscroll[editor_name] = false;
return;
}
if (!this.changes) {
// pasting a wide line can trigger scroll before changes
// are calculated
return;
}
var scroller = jQuery(this.editor[editor_name].getScrollerElement());
if (this.midway == undefined) {
this.midway = (scroller.height() / 2.0 + scroller.offset().top).toFixed(2);
@@ -1039,11 +1050,13 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
this.trace('change', 'diff time', Timer.stop());
this.changes = Mgly.DiffParser(d.normal_form());
this.trace('change', 'parse time', Timer.stop());
if (this._current_diff === undefined && this.changes.length && this._initializing) {
if (this._current_diff === undefined && this.changes.length) {
// go to first difference on start-up where values are provided in
// settings.
this._current_diff = 0;
this._scroll_to_change(this.changes[0]);
if (this._initializing) {
this._scroll_to_change(this.changes[0]);
}
}
this.trace('change', 'scroll_to_change time', Timer.stop());
this._calculate_offsets(editor_name1, editor_name2, this.changes);
@@ -1391,7 +1404,9 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
}
lhs_line = led.getLine( j );
rhs_line = red.getLine( k );
var lcs = new Mgly.LCS(lhs_line, rhs_line);
var lcs = new Mgly.LCS(lhs_line, rhs_line, {
ignoreaccents: !!this.settings.ignoreaccents
});
lcs.diff(
function added (from, to) {
if (self._is_change_in_view('rhs', rhsvp, change)) {
@@ -1458,8 +1473,8 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
// gutter markup that highlights all gutter line numbers for the current change.
// cm doesn't give us the ability to style the line numbers directly.
var lhsLineNumbers = jQuery('#mergely-lhs ~ .CodeMirror .CodeMirror-code .CodeMirror-linenumber.CodeMirror-gutter-elt');
var rhsLineNumbers = jQuery('#mergely-rhs ~ .CodeMirror .CodeMirror-code .CodeMirror-linenumber.CodeMirror-gutter-elt');
var lhsLineNumbers = jQuery('#' + this.id + '-lhs ~ .CodeMirror .CodeMirror-code .CodeMirror-linenumber.CodeMirror-gutter-elt');
var rhsLineNumbers = jQuery('#' + this.id + '-rhs ~ .CodeMirror .CodeMirror-code .CodeMirror-linenumber.CodeMirror-gutter-elt');
var jf, jt, i, j;
rhsLineNumbers.removeClass('mergely current');
lhsLineNumbers.removeClass('mergely current');

View File

@@ -586,28 +586,48 @@ describe('mergely', function () {
done();
});
});
});
it('should not be vulnerable to XSS', function (done) {
function initXSS(options) {
$('body').get(0).innerHTML = "<!DOCTYPE html><html lang=\"en\"><body><div id='mergely<script id=\"injected\">alert(123)</script>'></div></body></html>";
const divs = document.getElementsByTagName('div');
editor = $(divs[0]);
editor.mergely(options);
return editor;
};
it('should not be vulnerable to XSS', function (done) {
function initXSS(options) {
$('body').get(0).innerHTML = "<!DOCTYPE html><html lang=\"en\"><body><div id='mergely<script id=\"injected\">alert(123)</script>'></div></body></html>";
const divs = document.getElementsByTagName('div');
editor = $(divs[0]);
editor.mergely(options);
return editor;
};
$(document).ready(() => {
const editor = initXSS({
height: 100,
viewport: true,
license: 'lgpl-separate-notice',
lhs: (setValue) => setValue(macbeth),
rhs: (setValue) => setValue(macbeth)
});
expect($('body').find('#injected')).to.have.length(0, 'expected no div with id injected');
const divs = document.getElementsByTagName('div');
expect(divs).to.have.length(1);
expect(divs[0].id).to.equal('mergely<script id="injected">alert(123)</script>');
$(document).ready(() => {
const editor = initXSS({
height: 100,
viewport: true,
license: 'lgpl-separate-notice',
lhs: (setValue) => setValue(macbeth),
rhs: (setValue) => setValue(macbeth)
});
expect($('body').find('#injected')).to.have.length(0, 'expected no div with id injected');
const divs = document.getElementsByTagName('div');
expect(divs).to.have.length(1);
expect(divs[0].id).to.equal('mergely<script id="injected">alert(123)</script>');
done();
});
});
it('should ignore accented characters', function (done) {
$(document).ready(() => {
const editor = init({
height: 100,
license: 'lgpl-separate-notice',
ignoreaccents: true,
lhs: (setValue) => setValue('comunicação'),
rhs: (setValue) => setValue('comunicacao')
});
const { mergely } = $('#mergely');
$('#mergely').on('updated', () => {
console.log('updated');
const diff = $('#mergely').mergely('diff');;
expect(diff).to.equal('');
done();
});
});

View File

@@ -19,10 +19,7 @@ module.exports = {
}, {
test: /\.css$/,
use: [{
loader: 'style-loader',
options: {
sourceMap: true
}
loader: 'style-loader'
}, {
loader: 'css-loader'
}]
@@ -69,11 +66,9 @@ module.exports = {
test: /[\\/]node_modules[\\/]/
}
},
chunks: 'async',
minChunks: 1,
minSize: 30000,
name: true
minSize: 30000
}
}
}

View File

@@ -29,10 +29,12 @@ module.exports = {
CodeMirror: 'CodeMirror'
},
plugins: [
new CopyWebpackPlugin([{
from: 'src/mergely.css',
to: 'mergely.css',
toType: 'file'
}])
new CopyWebpackPlugin({
patterns: [{
from: 'src/mergely.css',
to: 'mergely.css',
toType: 'file'
}]
})
]
};