diff --git a/.babelrc.js b/.babelrc.js
new file mode 100644
index 0000000..def46d0
--- /dev/null
+++ b/.babelrc.js
@@ -0,0 +1,19 @@
+module.exports = function(api) {
+ return {
+ presets: [
+ [
+ "@babel/preset-env",
+ {
+ targets: {
+ chrome: 59,
+ edge: 13,
+ firefox: 50,
+ ie: 11
+ },
+ // for uglifyjs...
+ forceAllTransforms: api.env("production"),
+ },
+ ],
+ ],
+ };
+};
diff --git a/.gitignore b/.gitignore
index 35a04f3..519d3c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
/lib
mergely-*.tgz
package-lock.json
+*.log
diff --git a/CHANGES.md b/CHANGES.md
index f5069e5..3e7f5e5 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,8 @@
# Changes
+## 4.0.8
+* chore: updated webpack
+
## 4.0.7
* chore: updated documentation
diff --git a/examples/app.html b/examples/app.html
new file mode 100644
index 0000000..053c404
--- /dev/null
+++ b/examples/app.html
@@ -0,0 +1,21 @@
+
+
+
+
+ Mergely - Simple Example
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/app.js b/examples/app.js
new file mode 100644
index 0000000..0437acc
--- /dev/null
+++ b/examples/app.js
@@ -0,0 +1,18 @@
+require('codemirror/lib/codemirror.css');
+require('../src/mergely.css');
+
+$(document).ready(function () {
+ $('#mergely').mergely({
+ license: 'lgpl',
+ cmsettings: {
+ readOnly: false
+ },
+ _debug: '',
+ lhs: function(setValue) {
+ setValue('the quick red fox\njumped over the hairy dog');
+ },
+ rhs: function(setValue) {
+ setValue('the quick brown fox\njumped over the lazy dog');
+ }
+ });
+});
diff --git a/karma.conf.js b/karma.conf.js
index 947d6ce..c820dbf 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -1,6 +1,5 @@
const path = require('path');
-const webpackCfg = require('./webpack.config');
-const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = function(config) {
config.set({
@@ -40,9 +39,11 @@ module.exports = function(config) {
webpack: {
entry: './src/mergely.js',
module: {
- loaders: [
- { test: /\.css$/, loader: ExtractTextPlugin.extract('css-loader') }
- ]
+ rules: [{
+ test: /\.(js)$/,
+ exclude: /node_modules/,
+ use: ['babel-loader']
+ }]
},
resolve: {
extensions: ['.js'],
@@ -52,7 +53,11 @@ module.exports = function(config) {
}
},
plugins: [
- new ExtractTextPlugin('mergely.css')
+ new CopyWebpackPlugin([{
+ from: 'src/mergely.css',
+ to: 'mergely.css',
+ toType: 'file'
+ }])
]
},
webpackServer: {
diff --git a/package.json b/package.json
old mode 100755
new mode 100644
index 6533602..d005e77
--- a/package.json
+++ b/package.json
@@ -1,17 +1,12 @@
{
"name": "mergely",
- "version": "4.0.7",
+ "version": "4.0.8",
"description": "A javascript UI for diff/merge",
"directories": {
"doc": "doc",
"example": "examples",
"test": "test"
},
- "scripts": {
- "build": "rm -rf lib && webpack",
- "test": "karma start",
- "test:chrome": "karma start --browsers Chrome --singleRun=false"
- },
"repository": {
"type": "git",
"url": "git+https://github.com/wickedest/Mergely.git"
@@ -20,7 +15,8 @@
"files": [
"lib",
"examples",
- "README.md"
+ "README.md",
+ "LICENSE"
],
"keywords": [
"merge",
@@ -38,14 +34,20 @@
},
"homepage": "https://github.com/wickedest/Mergely#readme",
"devDependencies": {
+ "@babel/core": "^7.1.6",
+ "@babel/preset-env": "^7.1.6",
+ "@webpack-cli/init": "^0.1.2",
+ "babel-loader": "^8.0.4",
+ "babel-plugin-syntax-dynamic-import": "^6.18.0",
"chai": "^4.1.2",
"codemirror": "^5.32.0",
- "css-loader": "^0.28.7",
- "extract-text-webpack-plugin": "^3.0.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": "^2.0.0",
+ "karma": "^3.1.1",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage-istanbul-reporter": "^1.3.0",
@@ -53,6 +55,16 @@
"karma-mocha-reporter": "^2.2.5",
"karma-webpack": "^2.0.9",
"mocha": "^4.0.1",
- "webpack": "^3.8.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"
+ },
+ "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",
+ "test": "karma start",
+ "test:chrome": "karma start --browsers Chrome --singleRun=false"
}
}
diff --git a/src/Timer.js b/src/Timer.js
new file mode 100644
index 0000000..ea7dbd3
--- /dev/null
+++ b/src/Timer.js
@@ -0,0 +1,16 @@
+class Timer {
+ static start() {
+ Timer.t0 = Date.now();
+ }
+
+ static stop() {
+ var t1 = Date.now();
+ var td = t1 - Timer.t0;
+ Timer.t0 = t1;
+ return td;
+ }
+}
+
+Timer.t0 = 0;
+
+exports = module.exports = Timer;
diff --git a/src/mergely.js b/src/mergely.js
index bb9d00f..bf7d7b8 100644
--- a/src/mergely.js
+++ b/src/mergely.js
@@ -1,25 +1,13 @@
"use strict";
-require('./mergely.css');
-
(function(jQuery, CodeMirror) {
var Mgly = {};
-Mgly.Timer = function(){
- var self = this;
- self.start = function() { self.t0 = new Date().getTime(); };
- self.stop = function() {
- var t1 = new Date().getTime();
- var d = t1 - self.t0;
- self.t0 = t1;
- return d;
- };
- self.start();
-};
-
Mgly.ChangeExpression = new RegExp(/(^(?![><\-])*\d+(?:,\d+)?)([acd])(\d+(?:,\d+)?)/);
+const Timer = require('./Timer');
+
Mgly.DiffParser = function(diff) {
var changes = [];
var change_id = 0;
@@ -751,7 +739,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
}).append('
This software is a Combined Work using Mergely and is covered by the ' + lic + ' license. For the full license, see http://www.mergely.com/license.
');
jQuery('body').one('click', function () {
jQuery('#mergely-splash').fadeOut(100, 'linear', function () {
- this.remove();
+ jQuery('#mergely-splash').remove();
});
});
}
@@ -950,13 +938,13 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
else this.trace('scroll', 'not scrolling other side');
if (this.settings.autoupdate) {
- var timer = new Mgly.Timer();
+ Timer.start();
this._calculate_offsets(editor_name1, editor_name2, this.changes);
- this.trace('change', 'offsets time', timer.stop());
+ this.trace('change', 'offsets time', Timer.stop());
this._markup_changes(editor_name1, editor_name2, this.changes);
- this.trace('change', 'markup time', timer.stop());
+ this.trace('change', 'markup time', Timer.stop());
this._draw_diff(editor_name1, editor_name2, this.changes);
- this.trace('change', 'draw time', timer.stop());
+ this.trace('change', 'draw time', Timer.stop());
}
this.trace('scroll', 'scrolled');
}
@@ -966,9 +954,9 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var self = this;
if (this.changed_timeout != null) clearTimeout(this.changed_timeout);
this.changed_timeout = setTimeout(function(){
- var timer = new Mgly.Timer();
+ Timer.start();
self._changed(editor_name1, editor_name2);
- self.trace('change', 'total time', timer.stop());
+ self.trace('change', 'total time', Timer.stop());
}, this.settings.change_timeout);
},
_changed: function(editor_name1, editor_name2) {
@@ -979,7 +967,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var self = this, name, editor, fns, timer, i, change, l;
var clear_changes = function() {
- timer = new Mgly.Timer();
+ Timer.start();
for (i = 0, l = editor.lineCount(); i < l; ++i) {
editor.removeLineClass(i, 'background');
}
@@ -993,7 +981,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
change.clear();
}
editor.clearGutter('merge');
- self.trace('change', 'clear time', timer.stop());
+ self.trace('change', 'clear time', Timer.stop());
};
for (name in this.editor) {
@@ -1029,23 +1017,23 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
_diff: function(editor_name1, editor_name2) {
var lhs = this.editor[editor_name1].getValue();
var rhs = this.editor[editor_name2].getValue();
- var timer = new Mgly.Timer();
+ Timer.start();
var d = new Mgly.diff(lhs, rhs, this.settings);
- this.trace('change', 'diff time', timer.stop());
+ this.trace('change', 'diff time', Timer.stop());
this.changes = Mgly.DiffParser(d.normal_form());
- this.trace('change', 'parse time', timer.stop());
+ this.trace('change', 'parse time', Timer.stop());
if (this._current_diff === undefined && this.changes.length) {
// go to first difference on start-up
this._current_diff = 0;
this._scroll_to_change(this.changes[0]);
}
- this.trace('change', 'scroll_to_change time', timer.stop());
+ this.trace('change', 'scroll_to_change time', Timer.stop());
this._calculate_offsets(editor_name1, editor_name2, this.changes);
- this.trace('change', 'offsets time', timer.stop());
+ this.trace('change', 'offsets time', Timer.stop());
this._markup_changes(editor_name1, editor_name2, this.changes);
- this.trace('change', 'markup time', timer.stop());
+ this.trace('change', 'markup time', Timer.stop());
this._draw_diff(editor_name1, editor_name2, this.changes);
- this.trace('change', 'draw time', timer.stop());
+ this.trace('change', 'draw time', Timer.stop());
},
_parse_diff: function (editor_name1, editor_name2, diff) {
this.trace('diff', 'diff results:\n', diff);
@@ -1235,7 +1223,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var lhsvp = this._get_viewport_side(editor_name1);
var rhsvp = this._get_viewport_side(editor_name2);
- var timer = new Mgly.Timer();
+ Timer.start();
led.operation(function() {
for (var i = 0; i < changes.length; ++i) {
var change = changes[i];
@@ -1288,7 +1276,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
}
}.bind(this));
- this.trace('change', 'markup lhs-editor time', timer.stop());
+ this.trace('change', 'markup lhs-editor time', Timer.stop());
red.operation(function() {
for (var i = 0; i < changes.length; ++i) {
var change = changes[i];
@@ -1340,7 +1328,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
}
}
}.bind(this));
- this.trace('change', 'markup rhs-editor time', timer.stop());
+ this.trace('change', 'markup rhs-editor time', Timer.stop());
// mark text deleted, LCS changes
var marktext = [], i, j, k, p;
@@ -1400,7 +1388,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
}
}
}
- this.trace('change', 'LCS marktext time', timer.stop());
+ this.trace('change', 'LCS marktext time', Timer.stop());
// mark changes outside closure
led.operation(function() {
@@ -1420,7 +1408,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
}
});
- this.trace('change', 'LCS markup time', timer.stop());
+ this.trace('change', 'LCS markup time', Timer.stop());
// merge buttons
var ed = {lhs:led, rhs:red};
@@ -1484,7 +1472,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
}
}
- this.trace('change', 'markup buttons time', timer.stop());
+ this.trace('change', 'markup buttons time', Timer.stop());
},
_merge_change : function(change, side, oside) {
if (!change) return;
diff --git a/webpack.config.js b/webpack.config.js
deleted file mode 100644
index 5c3d433..0000000
--- a/webpack.config.js
+++ /dev/null
@@ -1,38 +0,0 @@
-const webpack = require('webpack');
-const path = require('path');
-const ExtractTextPlugin = require('extract-text-webpack-plugin');
-
-module.exports = {
- entry: {
- mergely: './src/mergely.js',
- // 'mergely.min': './src/mergely.js'
- },
- output: {
- path: path.join(__dirname, 'lib'),
- filename: './[name].js',
- library: 'mergely',
- libraryTarget: 'umd',
- umdNamedDefine: true
- },
- module: {
- loaders: [
- { test: /\.css$/, loader: ExtractTextPlugin.extract('css-loader') }
- ]
- },
- resolve: {
- extensions: ['.js']
- },
- externals: {
- jquery: 'jQuery',
- CodeMirror: 'CodeMirror'
- },
- plugins: [
- // new webpack.optimize.UglifyJsPlugin({
- // sourceMap: true,
- // include: /\.js$/,
- // // include: /\.min\.js$/,
- // exclude: /node_modules/
- // }),
- new ExtractTextPlugin('mergely.css')
- ]
-};
diff --git a/webpack.dev.js b/webpack.dev.js
new file mode 100644
index 0000000..d2ad442
--- /dev/null
+++ b/webpack.dev.js
@@ -0,0 +1,80 @@
+const webpack = require('webpack')
+const path = require('path')
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+
+module.exports = {
+ mode: 'development',
+
+ module: {
+ rules: [{
+ include: [
+ path.resolve(__dirname, 'src'),
+ path.resolve(__dirname, 'examples')
+ ],
+ test: /\.js$/
+ }, {
+ test: /\.(js)$/,
+ exclude: /node_modules/,
+ use: ['babel-loader']
+ }, {
+ test: /\.css$/,
+ use: [{
+ loader: 'style-loader',
+ options: {
+ sourceMap: true
+ }
+ }, {
+ loader: 'css-loader'
+ }]
+ }]
+ },
+
+ resolve: {
+ extensions: ['.js'],
+ alias: {
+ 'CodeMirror': path.join(__dirname, 'node_modules', 'codemirror'),
+ 'jQuery': path.join(__dirname, 'node_modules', 'jquery')
+ }
+ },
+
+ plugins: [
+ new HtmlWebpackPlugin({
+ template: 'examples/app.html',
+ filename: 'mergely.html'
+ }),
+ new webpack.ProvidePlugin({
+ $: 'jquery',
+ jQuery: 'jquery'
+ }),
+ new webpack.ProvidePlugin({
+ CodeMirror: 'codemirror'
+ })
+ ],
+
+ entry: {
+ app: [
+ './examples/app',
+ './src/mergely',
+ ]
+ },
+
+ output: {
+ filename: 'mergely.js',
+ },
+
+ optimization: {
+ splitChunks: {
+ cacheGroups: {
+ vendors: {
+ priority: -10,
+ test: /[\\/]node_modules[\\/]/
+ }
+ },
+
+ chunks: 'async',
+ minChunks: 1,
+ minSize: 30000,
+ name: true
+ }
+ }
+}
\ No newline at end of file
diff --git a/webpack.prod.js b/webpack.prod.js
new file mode 100644
index 0000000..644ec3e
--- /dev/null
+++ b/webpack.prod.js
@@ -0,0 +1,38 @@
+const webpack = require('webpack');
+const path = require('path');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+
+module.exports = {
+ mode: 'production',
+ entry: {
+ mergely: './src/mergely.js',
+ },
+ output: {
+ path: path.join(__dirname, 'lib'),
+ filename: './[name].js',
+ library: 'mergely',
+ libraryTarget: 'umd',
+ umdNamedDefine: true
+ },
+ module: {
+ rules: [{
+ test: /\.(js)$/,
+ exclude: /node_modules/,
+ use: ['babel-loader']
+ }]
+ },
+ resolve: {
+ extensions: ['.js']
+ },
+ externals: {
+ jquery: 'jQuery',
+ CodeMirror: 'CodeMirror'
+ },
+ plugins: [
+ new CopyWebpackPlugin([{
+ from: 'src/mergely.css',
+ to: 'mergely.css',
+ toType: 'file'
+ }])
+ ]
+};