GithubHelp home page GithubHelp logo

wickedest / mergely Goto Github PK

View Code? Open in Web Editor NEW
1.2K 48.0 228.0 2.33 MB

Merge and diff documents online

Home Page: http://www.mergely.com

License: Other

CSS 4.23% JavaScript 95.70% Shell 0.07%
hacktoberfest diff

mergely's Introduction

Mergely

mergely logo

https://mergely.com

Mergely is a JavaScript component for differencing and merging files interactively in a browser (diff/merge). It provides a rich API that enables you to easily integrate Mergely into your existing web application. It is suitable for comparing text files online, such as .txt, .html, .xml, .c, .cpp, .java, .js, etc.

Mergely has a JavaScript implementation of the Longest Common Subsequence (LCS) diff algorithm, and a customizable markup engine. It computes the diff within the browser.

This is the latest version 5. The previous version 4 can be found here.

Usage

Usage via React

The easiest and recommended way to use Mergely is with the mergely-react component.

npm install mergely-react

Usage via Angular

There is an Angular component for Mergely mergely-angular, but it is out of date. I will accept MR for anyone willing to do the work.

Usage via webpack

The source repository mergely-webpack contains an example of how to get started with a new project that uses mergely and webpack.

git clone --depth 1 https://github.com/wickedest/mergely-webpack.git my-project
cd my-project
rm -rf .git

Usage via CDN

Add the following to the <head> of your target HTML source file. Note that codemirror is bundled.

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mergely/5.0.0/mergely.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mergely/5.0.0/mergely.css" />

Synchronous initialization

If the editor contents are retrieved asynchronously (recommended), then retrieve the editor contents and set them:

<body>
  <div id="compare"></div>

  <script>
    const doc = new Mergely('#compare', {
      lhs: 'the quick red fox\njumped over the hairy dog',
      rhs: 'the quick brown fox\njumped over the lazy dog'
    });
  </script>
</body>

Asynchronous initialization

Mergely will emit an updated event when the editor is first initialized, and each time one of the editors changes. You can listen for one event to perform one-time initialization.

<body>
  <div id="compare"></div>

  <script>
    const doc = new Mergely('#compare');
    doc.once('updated', () => {
      doc.lhs('the quick red fox\njumped over the hairy dog');
      doc.rhs('the quick brown fox\njumped over the lazy dog');
      // Scroll to first change on next update
      doc.once('updated', () => {
        doc.scrollToDiff('next');
      });
    });
  </script>
</body>

Visualization modes

Mergely supports the following CodeMirror visualizations for mode:

  • go
  • javascript
  • htmlmixed
  • markdown
  • python

Options

Option Type Default value Description
autoupdate boolean true Controls whether or not the changed event will trigger a diff.
bgcolor string #eeeeee The background color for the left-hand and right-hand margins.
change_timeout number 150 The timeout, after a text change, before Mergely calculates a diff. Only used when readonly is enabled.
cmsettings object {mode: 'text/plain', readOnly: false} CodeMirror settings (see CodeMirror) that are combined with lhs_cmsettings and rhs_cmsettings.
ignorews boolean false Ignores white-space.
ignorecase boolean false Ignores case.
ignoreaccents boolean false Ignores accented characters.
lcs boolean true Enables/disables LCS computation for paragraphs (char-by-char changes). Disabling can give a performance gain for large documents.
lhs boolean,function handler(setValue) null Sets the value of the editor on the left-hand side.
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).
line_numbers boolean true Enables/disables line numbers. Enabling line numbers will toggle the visibility of the line number margins.
lhs_cmsettings object {} The CodeMirror settings (see CodeMirror) for the left-hand side editor.
resize_timeout number 500 The timeout, after a resize, before Mergely auto-resizes. Only used when autoresize enabled.
rhs boolean,function handler(setValue) null Sets the value of the editor on the right-hand side.
rhs_cmsettings object {} The CodeMirror settings (see CodeMirror) for the right-hand side editor.
rhs_margin string right Location for the rhs markup margin. Possible values: right, left.
sidebar boolean true Enables/disables sidebar markers. Disabling can give a performance gain for large documents.
vpcolor string rgba(0, 0, 200, 0.5) The margin/viewport indicator color.
viewport boolean false Enables/disables the viewport. Enabling the viewport can give a performance gain for large documents.
wrap_lines boolean false Enables/disables line wrapping. Enabling wrapping will wrap text to fit the editors.

Constructor

constructor(selector: string, options?: object)

Parameters

Name Type Description
selector string A CSS selector used to uniquely identify the DOM element that should be used to bind the instance of Mergely.
options object Configuration options for the instance.

Example

new Mergely('#editor', { ignorews: true });

Methods

clear(side: string)

Clears the editor contents for the specified side.

Parameters

Name Type Description
side string The editor side, either lhs or rhs.

Example

doc.clear('lhs');

cm(side: string)

Gets the CodeMirror editor for the specified side.

Parameters

Name Type Description
side string The editor side, either lhs or rhs.

Example

doc.cm('lhs');

diff()

Calculates and returns the current .diff file.

Parameters

None.

Example

doc.diff();

get(side: string)

Gets the text editor contents for the specified side.

Parameters

Name Type Description
side string The editor side, either lhs or rhs.

Example

doc.get('lhs');

lhs(value: string)

Sets the value of the left-hand editor.

Parameters

Name Type Description
value string The editor text.

Example

doc.lhs('This is text');

merge(side: string)

Merges whole file from the specified side to the opposite side.

Parameters

Name Type Description
side string The editor side, either lhs or rhs.

Example

doc.merge('lhs');

mergeCurrentChange(side: string)

Merges the current change from the specified side to the opposite side.

Parameters

Name Type Description
side string The editor side, either lhs or rhs.

Example

doc.mergeCurrentChange('lhs');

on(event: string, handler: function)

Sets up a function to be called when the specified event is emitted. The event handler will be automatically deregistered on unbind.

Parameters

None.

Example

doc.on('updated', () => console.log('updated!'));

once(event: string, handler: function)

Sets up a function to be called when the specified event is emitted. The event handler will be automatically deregistered after the handler is called.

Parameters

None.

Example

doc.unbind();

options(options?: object)

Gets or sets the editor Options. With no arguments, the function will return the currenty configured options. When supplied options to change, the editor will automatically update with the new settings.

Parameters

Name Type Description
options object The options to set.

Example

const currentOptions = doc.options();
doc.options({ line_numbers: true });

resize()

Resizes the editor. It must be called explicitly if autoresize is disabled.

Parameters

None.

Example

doc.resize();

rhs(value: string)

Sets the value of the right-hand editor.

Parameters

Name Type Description
value string The editor text.

Example

doc.rhs('This is text');

scrollTo(side: string, lineNum: integer)

Scrolls the editor side to line number specified by lineNum.

Parameters

Name Type Description
side string The editor side, either lhs or rhs.
lineNum number The line number.

Example

doc.scrollTo('lhs', 100);

scrollToDiff(direction: string)

Scrolls to the next change specified by direction.

Parameters

Name Type Description
direction string The direction to scroll, either prev or next.

Example

doc.scrollToDiff('next');

search(side: string, needle: string)

Search the editor for needle, scrolling to the next available match. Repeating the call will find the next available token.

Parameters

Name Type Description
side string The editor side, either lhs or rhs.
needle string The text for which to search.

Example

doc.search('lhs', 'banana');

summary()

Gets a summary of the editors. Returns an object with summarized properties:

Name Description
a The number of added lines.
c The number of changed lines.
d The number of deleted lines.
lhsLength The number of characters in the lhs text.
rhsLength The number of characters in the rhs text.
numChanges The total number of changed lines.

Parameters

None.

Example

console.log(doc.summary());
// { a: 0, c: 1, d: 0, lhsLength: 44, rhsLength: 45, numChanges: 1 }

swap()

Swaps the content of the left and right editors. The content cannot be swapped if either editor is read-only.

Parameters

None.

Example

doc.swap();

unmarkup()

Clears the editor markup.

Parameters

None.

Example

doc.unmarkup();

unbind()

Unbinds and destroys the editor DOM.

Parameters

None.

Example

doc.unbind();

Events

Event handlers are automatically unregistered when unbind is called.

changed

Triggered when one of the editors change, e.g. text was altered. The change_timeout controls how much time should pass after the changed event (e.g. keypress) before the updated event is triggered.

Example

mergely.once('changed', () => { console.log('changed!'); }

mergely.on('changed', () => { console.log('changed!'); }

resized

Triggered after the editor is resized.

Example

mergely.once('resized', () => { console.log('resized!'); }

mergely.on('resized', () => { console.log('resized!'); }

updated

Triggered after the editor finishes rendering. For example, text updates, options, or scroll events may trigger renders. This event is useful for handling a once-off initialization that should occur after the editor's first render.

Example

mergely.once('updated', () => { console.log('updated!'); }

mergely.on('updated', () => { console.log('updated!'); }

mergely's People

Contributors

alibitek avatar andreamussap avatar controlboy38 avatar cvara avatar dbluestein avatar dependabot[bot] avatar ecksters avatar edgarcosta avatar huangyq23 avatar johan456789 avatar kljh avatar nahakiole avatar semantic-release-bot avatar sphinxxxx avatar tenuki avatar twostone avatar wickedest avatar zhudock avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mergely's Issues

Readonly but merge?

How to make the edit panes "read-only" for user edits (with the keyboard), but allow the merge operations.
If I set:

...
cmsettings: {
    readOnly: true,
    lineNumbers: true 
},
...

the merging buttons/actions on each side disappear too, so the merging operations are not possible anymore.

Thank you.

XML Compare Is Misleading

The about page says It can be embedded within your own Web application to compare files, text, C, C++, Java, HTML, XML, CSS, and javascript.
http://www.mergely.com/about

When I compare 2 xml files with attributes in different order or tags in different order mergely marks these as differences when in fact they are identical in terms of xml.

Is it in fact only doing a basic text diff?

Are there plans for proper xml diff?

'autoresize:false' ignored for window resizes

It seems that the only effect of setting autoresize to true is that we get some style applied to the element, the background window-resize event listener is always applied even when autoresize is false.

Is that the expected behaviour? I had hoped to control resizing myself (as resizing also fires a 'changing' event, and I do not neccessarily wish this to fire)

Inline changes broken

If the changed word within a line has different length on both side, the right side is displayed incorrectly. E.g. see http://www.mergely.com/lKGcLOqu/

Changing 'lhs' to 'rhs" in the second part of
jQuery.extend(Mgly.LCS.prototype, { ...
seems to correct the problem.

Using jQuery instead of $ for jQuery.

It would be probably better if you used the full spelled out "jQuery" in mergely library for those using other libraries that take over the $ symbol and when using jQuery.noConflict(). Again I can submit a patch for the last 2.x branch if you want; it was a two second change to do quick search & replace of all $ -> jQuery in the mergly.js file.

Where are PHP files accessed with AJAX from editor/editor.js ?

Hello,

I cannot find where is the source code for the following PHP files access from:

editor/editor.js
168:                            url: '/ajax/handle_get.php',
178:                            url: '/ajax/handle_get.php',
427:                            url: '/ajax/handle_file.php',
432:                                            var url = '/ajax/handle_save.php?key=' + key;
476:                    url: '/ajax/handle_crossdomain.php',

The menu options do not work without them.

Any ideas?

Live JSFiddle example.

Please add a JSFiddle example of Mergely.

This would allow users to try it right away, but would be also much easier
this way to send bug test cases by just forking and modifying that example.

Thank you.

[Suggestion, UX] make the diff indicators filled in with color.

Hi,

I want to make a small suggestion, could it be possible to fill in the diff inidicators with a solid color ?

On large screens very thin lines are hard to see. When the diff block indicators would be filled in it would make the visibility much better.

Please see screenshot.

screen shot 2015-11-09 at 12 31 54

Lots of FOR( x in y) missing hasOwnProperty

I pulled your last version of mergely (pre-3.0) SHA: b5e669d and when used with some other libraries that extend some of the prototypes (like Array); mergely will break because it doesn't check to verify that the property it is trying to use is its own.

I can submit a patch for this version if you want; but I realize this is now a "obsolete" version as you are working on the 3.0 branch. I do NOT know if the 3.0 has the same issue; but it was only a couple minutes of work to change doing a search for all "for" and then on any of the "in" for's, adding a "if (!y.hasOwnProperty(x)) continue; " as the first line in the loop.

Online Diff Tool Pane Label

Love this tool, it would be great if you could label each pane.

Example. When you are comparing dev and production code, you could easily identify which one is which.

Question

Does Mergely require anything but a webserver to run? (eg: node, frameworks, etc)

ed[oside].removeLine is not a function

To delete the new changes made on left side by pressing Merge button on the right side, it is throwing the 'ed[oside].removeLine is not a function' error in the console.

The is happened by using upgraded version of codemirror.

After viewing the upgrade notes of codemirror, it is identified that removeLine function is removed from the codemirror library which is why this error is happening now in codemirror version 4.

The refactoring is required to replace the old method with the new method called 'replaceRange'.

Feature Request

is it possible to get a summary of diff result?

like number of modification, number of add, number of deletion

Thank you

Mergely with Bootstrap?

How to combine Mergely with Twitter Bootstrap?

I have a editor_width: '500px' setting for mergely but how can I make it to take the entire width available by Bootstrap?
e.g.

<div id="compare" class="col-sm-12"><div>

seems to ignore the width exposed by the '.col-sm-12'
IMHO there should be more a "min_editor_width" setting.

scrolling one side before changes are computed

Hi,

Thanks for this great tool.
I'm loading one side and I disable the difference calculation. I only enable the difference calculation after loading the second text, because it does not make sense to show the difference between a text and an empty one.
There is only a small problem, because if the user tries to scroll down the first text, before loading the second one, there is a Javascript error.

I fixed it (just a hack), in _scrolling, by adding:

if (!this.hasOwnProperty('changes')) return;

before the cycle where the property changes is used.

If this hack makes sense, I can submit a pull request.

Install from bower

I think it would be nice to be able to easily install mergely as a bower dependency. There is a repo, erahhal/bower-mergely, that provides that functionality but it is quite out of date as of now. I would suggest a bower.json in this repo, as it would assure that it remains up to date in the future. I could draw one up if there is no opposition.

Way to call callback when diff rendering finished

I'm looking for a way to scroll to first change once editor is loaded, and both lhs and rhs sides loaded as well. The problem is that i think there's no callback once the diff calculation is done.

In case of large files generating diffs takes some time, and there's no nice way to call the scrollToDiff function then.

Am i missing something ?

Examples don't prepopulate the .txt files

The included /examples/ include some .txt files which I assume the browser is supposed to read and pre-populate the lhs/rhs diff panes, but they don't seem to load in any of my browsers: Chrome, Firefox, IE

Restrict merging in only one direction?

Hi,

Is it possible to restrict merging to happen in only one direction? e.g. left to right or right to left only?
I couldn't find any settings for this.

Thank you.

Can I Use This As A Viewer With A Different Back End?

I have quite complex requirements for what constitutes a diff or not in XML.
For this purpose I am using xmlunit as it gives me a lot of flexibility.

Is it possible to take the output of my xmlunit result and tell mergely what constitutes a diff?
i.e. just use the mergely viewer and not the mergely difference engine

Insert diff above or below

Hi,
is it possible to merge/insert a diff line above or below the opposite reference line?
Like in Meld with pressing the Ctrl-key?

Regards,
Stefan

"Ignore white space" does not ignore newlines

Even when the "Ignore white space" menu option is selected, extra and/or missing newlines are marked as differences in the editor, which is not the behavior that I would expect.

editor_height - documentation

sorry to say this, but the documentation is severely lacking. I have no idea how exactly to set the height. I tried setting editor_height as presented in documentation, but all it does is make the boxes taller. The content inside it is still confined to the original height. Can you please include examples in documentation?

interested in a challenge? :-)

First, this is awesome. Impressive job.

I'm working on a proof-of-concept node.js tool that will "deconstruct" HTML pages into components and sections. So, for example, you could use it to reverse engineer all of Bootstrap's built pages back into components and partials/includes.

I actually have everything working, but it would be awesome to automatically:

  • have the tool perform diffs on each file,
  • then "extract" out text that differs from one file to the next
  • push those differences into an array
  • write the resulting array to the disk as valid JSON

For example, given these two files:

image

The tool would automatically merge the two files into one, and create the following JSON file (using the basename of each file as the property name):

{
  "css": "CSS &middot; Upstage",
  "components": "Components  &middot; Upstage"
}

The only thing I need help with is the extraction of differences, e.g. where in the code is the actual diff'ed text being highlighted, etc. and possible a strategy for merging files like those in the examples.

If you could even just point me in the right direction in the code, that would be great.

Support for 'clearing out differences/overlays/gutters/canvas lines'

I couldn't see from the current API how I would 'remove' the differencing overlays, say I have 'autoupdate' turned off, and want explicit control over when the differences are applied (or more accurately _un_applied!).

To achieve this I added the following external code :

var d= jQuery.data(this._comparerElement, "mergely");
        for (var name in d.editor) {
            if (!d.editor.hasOwnProperty(name)) continue;
            var editor = d.editor[name];
            // clear editor changes
            editor.operation(function() {
                var timer = new Mgly.Timer();
                for (var i = 0, l = editor.lineCount(); i < l; ++i) {
                    editor.removeLineClass(i, 'background');
                }
                for (var i = 0; i < d.change_funcs.length; ++i) {
                    var edid = editor.getDoc().id;
                    var change =d.change_funcs[i];
                    if (change.doc.id != edid) continue;
                    if (change.lines.length) {
                        d.trace('change', 'clear text', edid, change.lines[0].text);
                    }
                    change.clear();
                }
                editor.clearGutter('merge');
                d.trace('change', 'clear time', timer.stop());
            });
        }
        d.change_funcs = [];
        d._draw_diff(d.id + '-lhs', d.id + '-rhs', []);

(Taken from the mergely#_changed method with a minor difference in the last line.) Is there a correct way to achieve what I'm doing here without exposing the internals of mergely to the consuming code ?

Alternatively would you accept a pull request adding support for this to the mergely interface, if so what form would you like that call to take ?

Thank you :)

mergely too eager to find common text

Mergely sometimes it a little too eager when trying to find common text. Here's a silly, made up example:

http://www.mergely.com/HA4vHsTS/

Line 5 (on the left, or line 4 on the right), the content is pretty much entirely different. However, mergely highlights it to show that "ar and "o" are in common between both lines. This in practice, is useless, since these are letters in the middle of works that happen to be common. I'd prefer it if mergely simply marked these entire lines as different (like is does for line 4left, 3right)

Is this a reasonable tweak to make?

Make mergely work inside shadow-dom elements (stop referencing by global ID)

It should be possible to use mergely within a polymer element. Polymer elements use shadow dom (i.e. ids are unique within a "dom-module", but not guaranteed to be unique for the whole doc, or even queryable from the main document.

For all invocations of $() or jQuery() search beneath the main mergely element.

Change tracking

I appreciate developing this really handy project.

Instead of merging I need to use Megely for change tracking. In the same way that it works in MS word or Google Docs.

I need to present the user a single text editor pre-filled with some paragraphs and once user start typing he sees changes real-time and in-line.

Can you please advise how can I achieve this result please?

The default resize function uses a mix of parent element and window size components

Hi, I'm not sure if this is by design, but the default resize function ( https://github.com/wickedest/Mergely/blob/master/lib/mergely.js#L374 ) uses element's parent to get the 'width' (non-auto case) but to get the hieght, the window's height is used.

Is this deliberate? (it seems to break embedding mergely into a page part way down the sccreen)

It is work-aroundable, by setting both width + height to 'auto' and by providing the following settings methods:

        _auto_height: function(h) { 
            return $(that._comparerElement).parent().height() - 20;
        },
        _auto_width: function(h) { 
            return $(that._comparerElement).parent().width();
        },

but is this the correct thing for me to be doing ?

Feature request: Git diff

I noticed there's already Save .diff option available, but it has some kind of unknown syntax to me. Would it be possible to implement more export options for saving diffs, for example git diff? Yes, I know I can just use git, or if I'm online I can go play with github's diff, but Mergely provides a very nice split diff where you can merge stuff in both directions. For github, or real code editor I'd need to:

  • edit the line
  • save
  • git diff again
  • check if it's actually the diff I want and then export to file

and there's only one-side merge option if I don't want to copy the exact lines of code.

With this feature available I could just dump what I edit in Mergely right to the .patch file and send away.

Can it sign diff only?

I paste some words that may have '/t' in a word, then '/t' will be convert a label of span, so if it has a diff, The whole sentence will be signed, how can l t solve this ##problem?

How to keep the cursor position unchanged

When you enter a character, the cursor always returns to the beginning of the line.
So I have to undo and redo, so that the characters can be entered normally.
Is there a more effective way??

Merged Output

I love this library. Really well done ! It is the first I found that comes close to Apple's FileMerge.

FileMerge also shows an (editable) bottom area of the merge results, which is extremely helpful for understanding the final result and even allows to edit that merge block (basically overriding that sections output). Is this something that will be added sometime ?

Please tag the releases

Please Tag the releases with the versions so that tools can automatically reference them.
Right now they seem to be missing completely an exist only on your site in the download section.

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.