1
0
mirror of synced 2025-12-12 09:23:21 +08:00

Compare commits

..

20 Commits
3.3.9 ... 3.4.1

Author SHA1 Message Date
Jamie Peabody
266e0c7818 Updated 3.4.1 2016-05-25 22:34:26 +01:00
Jamie Peabody
4bbc6c597f Fix for merge-button and optimize 2016-05-25 22:22:04 +01:00
Jamie Peabody
c3093d7b8f Merge branch 'Sphinxxxx-Sphinxxxx-patch-1' 2016-05-24 23:10:01 +01:00
Jamie Peabody
5445d5a703 Fixes merge and gutter-click 2016-05-24 23:09:26 +01:00
Jamie Peabody
d8f91e740d Merge branch 'Sphinxxxx-patch-1' of https://github.com/Sphinxxxx/Mergely into Sphinxxxx-Sphinxxxx-patch-1 2016-05-24 22:53:31 +01:00
Jamie Peabody
bec45a41a3 Fixed optimize 2016-05-24 22:45:26 +01:00
Sphinxxxx
ea1571e0aa Fixes #41: "Scroll to diff" vs "Merge left/right" 2016-05-24 14:36:56 +02:00
Jamie Peabody
c4776b1359 Improved UX for reading; added gutter-click; Updated CM 5.11.0 2016-02-07 14:43:43 +00:00
wickedest
9875d58f15 Merge pull request #38 from scr/polymer
Fixes #37: Enable use within shadow-dom by searching beneath this.element.
2015-12-24 08:25:23 +00:00
Sheridan C Rawlins
ddfe77719e Fixes #37: Enable use within shadow-dom by searching beneath this.element. 2015-12-23 23:51:05 -08:00
wickedest
24b75d26dd Merge pull request #33 from nahakiole/fix-xss-issue
Fixing XSS security issue.
2015-11-10 08:49:04 +00:00
Jamie Peabody
21bd63961b Fixed initialization problem where scroll to first change did not work 2015-11-09 09:21:38 +00:00
Nahakiole
36eb076648 Fixing XSS security issue. 2015-11-07 10:44:44 +01:00
Jamie Peabody
8883235daa Updated to 3.3.10 2015-06-28 13:54:46 +01:00
Jamie Peabody
370375d35e Updated to use friendly URL and fixes updateHistory params 2015-06-28 12:59:43 +01:00
Jamie Peabody
d525f8d05d Updated to 3.3.10 2015-06-28 12:13:12 +01:00
Jamie Peabody
6ef8d2428c Updated documentation for line_numbers and wrap_lines 2015-06-28 12:07:26 +01:00
Jamie Peabody
398720ed41 Updated to 3.3.10 2015-06-28 12:06:35 +01:00
Jamie Peabody
e25acfe3b5 Added query params settings to editor 2015-06-28 12:06:06 +01:00
Jamie Peabody
aa9c9eaad4 Updated bower to use tag 2015-04-21 21:34:15 +01:00
12 changed files with 2508 additions and 1175 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "Mergely",
"version": "3.3.9",
"version": "3.4.1",
"homepage": "https://github.com/wickedest/Mergely",
"description": "Merge and diff documents online",
"main": [
@@ -29,7 +29,8 @@
"url": "git://github.com/wickedest/Mergely"
},
"dependencies": {
"mergely": "https://github.com/wickedest/Mergely.git#3.4.1",
"jquery": "<=2.1.3",
"codemirror": "<=4.6.0"
"codemirror": "<=5.11.0"
}
}

View File

@@ -110,6 +110,8 @@ $(document).ready(function () {
<dd>Ignore white-space. Defaults to <span class="code">false</span>.</dd>
<dt id="lcs">lcs</dt>
<dd>Enables/disables LCS computation for paragraphs (word-by-word changes). Disabling can give a performance gain for large documents. Defaults to <span class="code">true</span>.</dd>
<dt id="line_numbers">line_numbers</dt>
<dd>Enables/disables line numbers. Enabling line numbers will toggle the visibility of the line number margins. Defaults to <span class="code">true</span>.</dd>
<dt id="resize_timeout">resize_timeout</dt>
<dd>The timeout, after a resize, before Mergely auto-resizes. Only used when autoresize enabled. Defaults to <span class="code">500</span>.</dd>
<dt id="rhs_margin">rhs_margin</dt>
@@ -120,6 +122,8 @@ $(document).ready(function () {
<dd>The margin/viewport indicator color. Defaults to <span class="code">'rgba(0, 0, 200, 0.5)'<span></dd>
<dt id="viewport">viewport</dt>
<dd>Enables/disables the viewport. Enabling the viewport can give a performance gain for large documents. Defaults to <span class="code">false</span>.</dd>
<dt id="wrap_lines">wrap_lines</dt>
<dd>Enables/disables line wrapping. Enabling wrapping will wrap text to fit the editors. Defaults to <span class="code">false</span>.</dd>
</dl>
<h2>Callbacks</h2>

226
editor/editor.js Executable file → Normal file
View File

@@ -4,8 +4,12 @@ $(document).ready(function() {
window.location.search.substr(1).split('&').forEach(function(pair) {
if (pair === '') return;
var parts = pair.split('=');
if (parts[1] == 'true') parameters[parts[0]] = true;
else if (parts[1] == 'false') parameters[parts[0]] = false;
if (parts.length === 2 && parts[1].search(/^(true|1)$/i) >= 0) {
parameters[parts[0]] = true;
}
else if (parts.length === 2 && parts[1].search(/^(false|0)$/i) >= 0) {
parameters[parts[0]] = false;
}
else parameters[parts[0]] = parts[1] && decodeURIComponent(parts[1].replace(/\+/g, ' '));
});
return {
@@ -82,6 +86,9 @@ $(document).ready(function() {
return randomstring;
}
// body is pre-hidden for better rendering
$('body').css("visibility", "");
var ed = $('#mergely');
var menu = $('#main-menu');
var toolbar = $('#toolbar');
@@ -101,6 +108,56 @@ $(document).ready(function() {
var url = parameters.get('rhs');
crossdomainGET(ed, 'rhs', url);
}
// set query string options
var urloptions = {};
var optmap = {
au: 'autoupdate',
ws: 'ignorews',
sb: 'sidebar',
vp: 'viewport',
wl: 'wrap_lines',
ln: 'line_numbers'
};
var doopt = false;
for (var name in optmap) {
if (!optmap.hasOwnProperty(name)) continue;
if (parameters.get(name, null) !== null) {
urloptions[optmap[name]] = parameters.get(name);
doopt = true;
}
}
if (parameters.get('rm', null) !== null) {
// special-case url property
urloptions.rhs_margin = parameters.get('rm') ? 'left' : 'right';
}
if (doopt) {
// apply query-string options
ed.mergely('options', urloptions);
}
// set query string colors
// cb: change border
// cg: change background
// ab: added border
// ag: added background
// db: deleted border
// dg: deleted background
var color_defaults = {
cb: 'cccccc', cg: 'fafafa',
ab: 'a3d1ff', ag: 'ddeeff',
db: 'ff7f7f', dg: 'ffe9e9'
};
applyParameterCss(false);
//history.pushState({}, null, '');
window.addEventListener('popstate', function(ev) {
if (ev.state) {
parameters = getParameters();
applyParameterCss(false);
}
});
// Load
if (key.length == 8) {
@@ -131,7 +188,7 @@ $(document).ready(function() {
// if an anchor has been provided, then parse the anchor in the
// form of: 'lhs' or 'rhs', followed by a line, e.g: lhs100.
var m = anchor.match(/([lr]hs)([0-9]+)/);
if (m.length == 3) {
if (m && m.length == 3) {
console.log(m);
ed.mergely('scrollTo', m[1], parseInt(m[2],10));
}
@@ -150,36 +207,65 @@ $(document).ready(function() {
var iconconf = {
'options-autodiff': {
get: function() { return ed.mergely('options').autoupdate },
set: function(value) { ed.mergely('options', {autoupdate: !ed.mergely('options').autoupdate}); }
set: function(value) {
var au = !ed.mergely('options').autoupdate;
ed.mergely('options', {autoupdate: au});
var params = updateQueryStringParam('au', au ? 1 : 0, 1);
updateHistory(params);
}
},
'options-ignorews': {
get: function() { return ed.mergely('options').ignorews },
set: function(value) { ed.mergely('options', {ignorews: !ed.mergely('options').ignorews}); }
set: function(value) {
var ws = !ed.mergely('options').ignorews;
ed.mergely('options', {ignorews: ws});
var params = updateQueryStringParam('ws', ws ? 1 : 0, 0);
updateHistory(params);
}
},
'options-sidebars': {
get: function() { console.log('sidebar', this); return ed.mergely('options').sidebar },
set: function(value) { ed.mergely('options', {sidebar: !ed.mergely('options').sidebar}); }
set: function(value) {
var sb = !ed.mergely('options').sidebar;
ed.mergely('options', {sidebar: sb});
var params = updateQueryStringParam('sb', sb ? 1 : 0, 1);
updateHistory(params);
}
},
'options-viewport': {
get: function() { console.log('viewport', this); return ed.mergely('options').viewport },
set: function(value) { ed.mergely('options', {viewport: !ed.mergely('options').viewport}); }
set: function(value) {
var vp = !ed.mergely('options').viewport;
ed.mergely('options', {viewport: vp});
var params = updateQueryStringParam('vp', vp ? 1 : 0, 1);
updateHistory(params);
}
},
'options-swapmargin': {
get: function() { return (ed.mergely('options').rhs_margin == 'left'); },
set: function(value) { ed.mergely('options', {rhs_margin: ed.mergely('options').rhs_margin == 'left' ? 'right' : 'left' }); }
set: function(value) {
var rm = ed.mergely('options').rhs_margin == 'left' ? 'right' : 'left';
ed.mergely('options', {rhs_margin: rm });
var params = updateQueryStringParam('rm', rm == 'left' ? 1 : 0, 0);
updateHistory(params);
}
},
'options-linenumbers': {
get: function() { return ed.mergely('cm', 'lhs').getOption('lineNumbers'); },
get: function() { console.log('wrap', this); return ed.mergely('options').line_numbers },
set: function(value) {
ed.mergely('cm', 'lhs').setOption('lineNumbers', value);
ed.mergely('cm', 'rhs').setOption('lineNumbers', value);
var ln = !ed.mergely('options').line_numbers;
ed.mergely('options', {line_numbers: ln});
var params = updateQueryStringParam('ln', ln ? 1 : 0, 1);
updateHistory(params);
}
},
'options-wrap': {
get: function() { return ed.mergely('cm', 'lhs').getOption('lineWrapping'); },
get: function() { console.log('wrap', this); return ed.mergely('options').wrap_lines },
set: function(value) {
ed.mergely('cm', 'lhs').setOption('lineWrapping', value);
ed.mergely('cm', 'rhs').setOption('lineWrapping', value);
var wl = !ed.mergely('options').wrap_lines;
ed.mergely('options', {wrap_lines: wl});
var params = updateQueryStringParam('wl', wl ? 1 : 0, 0);
updateHistory(params);
}
},
'edit-left-readonly': {
@@ -482,21 +568,21 @@ $(document).ready(function() {
}
function colorSettings(ed) {
// get current settings
var sd = $('<span style="display:none" class="mergely ch d lhs">C</span>');
var sd = $('<span style="display:none" class="mergely ch d lhs start end">C</span>');
var sa = $('<span style="display:none" class="mergely bg a rhs start end">C</span>');
var sc = $('<span style="display:none" class="mergely c rhs start end">C</span>');
$('body').append(sd);
$('body').append(sa);
$('body').append(sc);
var conf = {
'c-border': {id: '#c-border', defaultColor: '#cccccc', getColor: function() { return sc.css('border-top-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'c-bg': {id: '#c-bg', defaultColor: '#fafafa', getColor: function() { return sc.css('background-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'a-border': {id: '#a-border', defaultColor: '#a3d1ff', getColor: function() { return sa.css('border-top-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'a-bg': {id: '#a-bg', defaultColor: '#ddeeff', getColor: function() { return sa.css('background-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'd-border': {id: '#d-border', defaultColor: '#ff7f7f', getColor: function() { return sd.css('border-top-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'd-bg': {id: '#d-bg', defaultColor: '#edc0c0', getColor: function() { return sd.css('background-color'); }, setColor: function(color) { $('#'+this.id).val(color) }}
'c-border': {id: '#c-border', getColor: function() { return sc.css('border-top-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'c-bg': {id: '#c-bg', getColor: function() { return sc.css('background-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'a-border': {id: '#a-border', getColor: function() { return sa.css('border-top-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'a-bg': {id: '#a-bg', getColor: function() { return sa.css('background-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'd-border': {id: '#d-border', getColor: function() { return sd.css('border-top-color'); }, setColor: function(color) { $('#'+this.id).val(color) }},
'd-bg': {id: '#d-bg', getColor: function() { return sd.css('background-color'); }, setColor: function(color) { $('#'+this.id).val(color) }}
};
$.each(conf, function(key, item){ $(item.id).val(item.getColor()); });
$.each(conf, function(key, item){$(item.id).val(item.getColor()); });
var f = $.farbtastic('#picker');
$('.colorwell').each(function(){ f.linkTo(this); }).focus(function(){
var tthis = $(this);
@@ -515,28 +601,8 @@ $(document).ready(function() {
var abg = $('#a-bg').val();
var dbg = $('#d-bg').val();
var cbg = $('#c-bg').val();
var text =
'.mergely.a.rhs.start { border-top: 1px solid ' + aborder + '; }\n\
.mergely.a.lhs.start.end,\n\
.mergely.a.rhs.end { border-bottom: 1px solid ' + aborder + '; }\n\
.mergely.a.rhs { background-color: ' + abg + '; }\n\
.mergely.d.lhs { background-color: ' + dbg + '; }\n\
.mergely.d.lhs.end,\n\
.mergely.d.rhs.start.end { border-bottom: 1px solid ' + dborder + '; }\n\
.mergely.d.rhs.start.end.first { border-bottom: 0; border-top: 1px solid ' + dborder + '; }\n\
.mergely.d.lhs.start { border-top: 1px solid ' + dborder + '; }\n\
.mergely.c.lhs,\n\
.mergely.c.rhs { background-color: ' + cbg + '; }\n\
.mergely.c.lhs.start,\n\
.mergely.c.rhs.start { border-top: 1px solid ' + cborder + '; }\n\
.mergely.c.lhs.end,\n\
.mergely.c.rhs.end { border-bottom: 1px solid ' + cborder + '; }\n\
.mergely.ch.a.rhs { background-color: ' + abg + '; }\n\
.mergely.ch.d.lhs { background-color: ' + dbg + '; text-decoration: line-through; color: #888; }';
$('<style type="text/css">' + text + '</style>').appendTo('head');
ed.mergely('options', {
fgcolor:{a:aborder,c:cborder,d:dborder}
});
var textCss = makeColorCss(cborder, cbg, aborder, abg, dborder, dbg);
applyColorCss(textCss, cborder, cbg, aborder, abg, dborder, dbg, true);
},
Reset: function() {
},
@@ -546,4 +612,76 @@ $(document).ready(function() {
}
});
}
function makeColorCss(changeBorder, changeBackground, addedBorder, addedBackground, deletedBorder, deletedBackground) {
var text =
'.mergely.a.rhs.start{border-top-color:' + addedBorder + ';}\n\
.mergely.a.lhs.start.end,\n\
.mergely.a.rhs.end{border-bottom-color:' + addedBorder + ';}\n\
.mergely.a.rhs{background-color:' + addedBackground + ';}\n\
.mergely.d.lhs{background-color:' + deletedBackground + ';}\n\
.mergely.d.lhs.end,\n\
.mergely.d.rhs.start.end{border-bottom-color:' + deletedBorder + ';}\n\
.mergely.d.rhs.start.end.first{border-top-color:' + deletedBorder + ';}\n\
.mergely.d.lhs.start{border-top-color:' + deletedBorder + ';}\n\
.mergely.c.lhs,\n\
.mergely.c.rhs{background-color:' + changeBackground + ';}\n\
.mergely.c.lhs.start,\n\
.mergely.c.rhs.start{border-top-color:' + changeBorder + ';}\n\
.mergely.c.lhs.end,\n\
.mergely.c.rhs.end{border-bottom-color:' + changeBorder + ';}\n\
.mergely.ch.a.rhs{background-color:' + addedBackground + ';}\n\
.mergely.ch.d.lhs{background-color:' + deletedBackground + ';color: #888;}';
return text;
}
function applyParameterCss(saveState) {
var cb = '#' + parameters.get('cb',color_defaults.cb),
cg = '#' + parameters.get('cg',color_defaults.cg),
ab = '#' + parameters.get('ab',color_defaults.ab),
ag = '#' + parameters.get('ag',color_defaults.ag),
db = '#' + parameters.get('db',color_defaults.db),
dg = '#' + parameters.get('dg',color_defaults.dg);
applyColorCss(makeColorCss(cb, cg, ab, ag, db, dg), cb, cg, ab, ag, db, dg, saveState);
}
function applyColorCss(cssText, changeBorder, changeBackground, addedBorder, addedBackground, deletedBorder, deletedBackground, saveState) {
$('<style type="text/css">' + cssText + '</style>').appendTo('head');
ed.mergely('options', {
fgcolor:{a:addedBorder,c:changeBorder,d:deletedBorder}
});
var params = updateQueryStringParam('cb', changeBorder.replace(/#/g, ''), color_defaults.cb);
params = updateQueryStringParam('cg', changeBackground.replace(/#/g, ''), color_defaults.cg, params);
params = updateQueryStringParam('ab', addedBorder.replace(/#/g, ''), color_defaults.ab, params);
params = updateQueryStringParam('ag', addedBackground.replace(/#/g, ''), color_defaults.ag, params);
params = updateQueryStringParam('db', deletedBorder.replace(/#/g, ''), color_defaults.db, params);
params = updateQueryStringParam('dg', deletedBackground.replace(/#/g, ''), color_defaults.dg, params);
if (saveState) {
updateHistory(params);
}
}
function updateHistory(params) {
var baseUrl = [location.protocol, '//', location.host, location.pathname].join('');
window.history.pushState({}, null, baseUrl + params);
}
// Explicitly save/update a url parameter using HTML5's replaceState().
function updateQueryStringParam(key, value, defaultValue, urlQueryString) {
var newParam = key + '=' + value,
params = '?' + newParam;
// If the "search" string exists, then build params from it
if (!urlQueryString) {
urlQueryString = document.location.search;
}
keyRegex = new RegExp('([\?&])' + key + '[^&]*');
if (value === defaultValue) {
params = urlQueryString.replace(keyRegex, '');
}
else if (urlQueryString.match(keyRegex) !== null) {
// update if only if value exists
params = urlQueryString.replace(keyRegex, '$1' + newParam);
}
else { // Otherwise, add it to end of query string
params = urlQueryString + '&' + newParam;
}
return params;
}
});

File diff suppressed because one or more lines are too long

26
editor/editor.php Executable file → Normal file
View File

@@ -4,20 +4,24 @@ $debug = False;
if (isset($_GET['key'])) {
$key = $_GET['key'];
}
if (isset($_GET['debug'])) {
$debug = filter_var($_GET['debug'], FILTER_VALIDATE_BOOLEAN);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" /><title>Mergely - Diff online, merge documents</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta name="description" content="Merge and Diff your documents with diff online and share" />
<meta name="keywords" content="diff,merge,compare,jsdiff,comparison,difference,file,text,unix,patch,algorithm,saas,longest common subsequence,diff online" />
<meta name="author" content="Jamie Peabody" />
<link rel="shortcut icon" href="http://www.mergely.com/favicon.ico" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="canonical" href="http://www.mergely.com" />
<link href='http://fonts.googleapis.com/css?family=Noto+Sans:400,700' rel='stylesheet' type='text/css' />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
<link type="text/css" rel="stylesheet" href="/style/mergely-theme/jquery-ui-1.10.1.custom.css" />
<link type='text/css' rel='stylesheet' href='/Mergely/editor/lib/wicked-ui.css' />
<script type="text/javascript" src="/Mergely/editor/lib/wicked-ui.js"></script>
@@ -48,8 +52,8 @@ if (isset($_GET['key'])) {
<script type="text/javascript" src="/Mergely/lib/searchcursor.js"></script>
<script type="text/javascript">
var key = '<?php echo $key; ?>';
var isSample = key == '4qsmsDyb';
var key = '<?php echo htmlspecialchars($key, ENT_QUOTES, 'UTF-8'); ?>';
var isSample = key == 'usaindep';
</script>
<!-- analytics -->
@@ -67,7 +71,7 @@ if (isset($_GET['key'])) {
<!-- google +1 -->
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
</head>
<body>
<body style="visibility:hidden">
<div id="fb-root"></div><script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
@@ -156,9 +160,12 @@ if (isset($_GET['key'])) {
<li><a class="link" href="/download" target="site">Download</a></li>
<li><a class="link" href="/doc" target="site">Mergely development guide</a></li>
<li class="separator"></li>
<li><a class="link" href="/4qsmsDyb/" target="_blank">United States Declaration of Independence Draft</a></li>
<li><a class="link" href="/united-states-declaration-of-independence?wl=1" target="_blank">United States Declaration of Independence Draft</a></li>
</ul>
</li>
<?php
if (!$debug) {
?>
<li accesskey="s">
Social
<ul>
@@ -185,6 +192,9 @@ if (isset($_GET['key'])) {
</li>
</ul>
</li>
<?php
}
?>
</ul>
<!-- toolbar -->

6
editor/lib/wicked-ui.css Executable file → Normal file
View File

@@ -59,9 +59,9 @@ THE SOFTWARE.
/* top menu */
.wicked-menu > li > a > *, .wicked-menu > li { display: inline-block; }
.wicked-menu li > ul > li > * { padding: 5px; display: inline-block; } /* padding other menu-item */
.wicked-menu > li > a.menu-item > * { padding: 6px 7px; }
.wicked-menu > li > a.menu-item > * { padding: 7px 7px; }
.wicked-menu > li { position: relative; border: 1px solid transparent; }
.wicked-menu > li.hover > a.menu-item > * { padding: 7px 7px 3px 7px; }
.wicked-menu > li.hover > a.menu-item {
/* lose the top-level focus indicator on hover */
outline: none;
@@ -73,7 +73,7 @@ THE SOFTWARE.
/* menu items */
.wicked-menu li.hover > ul,
.wicked-menu ul li:hover > ul { display: block; position: absolute; }
.wicked-menu ul li:hover > ul { margin-top: 5px; }
/* drop menu */
.wicked-menu ul { z-index: 7; min-width: 210px; top: 2.1em; left: -1px; }

View File

@@ -4,10 +4,7 @@
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
}
.CodeMirror-scroll {
/* Set scrolling behaviour here */
overflow: auto;
color: black;
}
/* PADDING */
@@ -36,8 +33,7 @@
min-width: 20px;
text-align: right;
color: #999;
-moz-box-sizing: content-box;
box-sizing: content-box;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
@@ -45,19 +41,21 @@
/* CURSOR */
.CodeMirror div.CodeMirror-cursor {
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0;
background: #7e7;
}
.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursors {
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
@@ -67,27 +65,28 @@
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% { background: #7e7; }
50% { background: none; }
100% { background: #7e7; }
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% { background: #7e7; }
50% { background: none; }
100% { background: #7e7; }
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% { background: #7e7; }
50% { background: none; }
100% { background: #7e7; }
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
div.CodeMirror-overwrite div.CodeMirror-cursor {}
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; }
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-ruler {
border-left: 1px solid #ccc;
@@ -96,6 +95,15 @@ div.CodeMirror-overwrite div.CodeMirror-cursor {}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
@@ -115,20 +123,14 @@ div.CodeMirror-overwrite div.CodeMirror-cursor {}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
@@ -142,14 +144,13 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
the editor. You probably shouldn't touch them. */
.CodeMirror {
line-height: 1;
position: relative;
overflow: hidden;
background: white;
color: black;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
@@ -157,18 +158,14 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actuall scrolling happens, thus preventing shaking and
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
@@ -194,26 +191,38 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
padding-bottom: 30px;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
-moz-box-sizing: content-box;
box-sizing: content-box;
padding-bottom: 30px;
margin-bottom: -32px;
display: inline-block;
margin-bottom: -30px;
/* Hack to make IE7 behave */
*zoom:1;
*display:inline;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.CodeMirror-lines {
cursor: text;
@@ -234,6 +243,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
@@ -255,8 +265,18 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-widget {}
.CodeMirror-wrap .CodeMirror-scroll {
overflow-x: hidden;
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
@@ -266,19 +286,19 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
overflow: hidden;
visibility: hidden;
}
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor {
position: absolute;
border-right: none;
width: 0;
}
.CodeMirror-cursor { position: absolute; }
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
@@ -286,6 +306,8 @@ div.CodeMirror-cursors {
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background: #ffa;
@@ -305,5 +327,8 @@ div.CodeMirror-cursors {
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }

File diff suppressed because it is too large Load Diff

10
lib/codemirror.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -12,17 +12,19 @@
.mergely-column { border: 1px solid #ccc; }
.mergely-active { border: 1px solid #a3d1ff; }
.mergely.a,.mergely.d,.mergely.c { color: #000; }
.mergely.a.rhs.start { border-top: 1px solid #a3d1ff; }
.mergely.a.lhs.start.end,
.mergely.a.rhs.end { border-bottom: 1px solid #a3d1ff; }
.mergely.a.rhs { background-color: #ddeeff; }
.mergely.a.lhs.start.end.first { border-bottom: 0; border-top: 1px solid #a3d1ff; }
.mergely.d.lhs { background-color: #edc0c0; }
.mergely.d.lhs { background-color: #ffe9e9; }
.mergely.d.lhs.end,
.mergely.d.rhs.start.end { border-bottom: 1px solid #ff7f7f; }
.mergely.d.rhs.start.end.first { border-bottom: 0; border-top: 1px solid #ff7f7f; }
.mergely.d.lhs.start { border-top: 1px solid #ff7f7f; }
.mergely.d.rhs.start.end { border-bottom: 1px solid #f8e8e8; }
.mergely.d.rhs.start.end.first { border-bottom: 0; border-top: 1px solid #f8e8e8; }
.mergely.d.lhs.start { border-top: 1px solid #f8e8e8; }
.mergely.c.lhs,
.mergely.c.rhs { background-color: #fafafa; }
@@ -32,4 +34,12 @@
.mergely.c.rhs.end { border-bottom: 1px solid #a3a3a3; }
.mergely.ch.a.rhs { background-color: #ddeeff; }
.mergely.ch.d.lhs { background-color: #edc0c0; text-decoration: line-through; color: #888; }
.mergely.ch.d.lhs { background-color: #ffe9e9; text-decoration: line-through; color: red !important; }
.mergely.current.start { border-top: 1px solid #000 !important; }
.mergely.current.end { border-bottom: 1px solid #000 !important; }
.mergely.current.lhs.a.start.end,
.mergely.current.rhs.d.start.end { border-top: 0 !important; }
.mergely.current.CodeMirror-linenumber { color: #F9F9F9; font-weight: bold; background-color: #777; }
.CodeMirror-linenumber { cursor: pointer; }
.CodeMirror-code { color: #717171; }

View File

@@ -297,15 +297,15 @@ jQuery.extend(Mgly.diff.prototype, {
},
_optimize: function(ctx) {
var start = 0, end = 0;
while (start < ctx.length) {
while ((start < ctx.length) && (ctx.modified[start] == undefined || ctx.modified[start] == false)) {
while (start < ctx.codes.length) {
while ((start < ctx.codes.length) && (ctx.modified[start] == undefined || ctx.modified[start] == false)) {
start++;
}
end = start;
while ((end < ctx.length) && (ctx.modified[end] == true)) {
while ((end < ctx.codes.length) && (ctx.modified[end] == true)) {
end++;
}
if ((end < ctx.length) && (ctx.ctx[start] == ctx.codes[end])) {
if ((end < ctx.codes.length) && (ctx.codes[start] == ctx.codes[end])) {
ctx.modified[start] = false;
ctx.modified[end] = true;
}
@@ -385,6 +385,8 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
autoupdate: true,
autoresize: true,
rhs_margin: 'right',
wrap_lines: false,
line_numbers: true,
lcs: true,
sidebar: true,
viewport: false,
@@ -441,8 +443,8 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var cmsettings = {
mode: 'text/plain',
readOnly: false,
lineWrapping: false,
lineNumbers: true,
lineWrapping: this.settings.wrap_lines,
lineNumbers: this.settings.line_numbers,
gutters: ['merge', 'CodeMirror-linenumbers']
};
this.lhs_cmsettings = {};
@@ -494,7 +496,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
if (direction == 'next') {
this._current_diff = Math.min(++this._current_diff, this.changes.length - 1);
}
else {
else if (direction == 'prev') {
this._current_diff = Math.max(--this._current_diff, 0);
}
this._scroll_to_change(this.changes[this._current_diff]);
@@ -537,10 +539,27 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
if (this.settings.hasOwnProperty('sidebar')) {
// dynamically enable sidebars
if (this.settings.sidebar) {
jQuery(this.element).find('.mergely-margin').css({display: 'block'});
this.element.find('.mergely-margin').css({display: 'block'});
}
else {
jQuery(this.element).find('.mergely-margin').css({display: 'none'});
this.element.find('.mergely-margin').css({display: 'none'});
}
}
var le, re;
if (this.settings.hasOwnProperty('wrap_lines')) {
if (this.editor) {
le = this.editor[this.id + '-lhs'];
re = this.editor[this.id + '-rhs'];
le.setOption('lineWrapping', this.settings.wrap_lines);
re.setOption('lineWrapping', this.settings.wrap_lines);
}
}
if (this.settings.hasOwnProperty('line_numbers')) {
if (this.editor) {
le = this.editor[this.id + '-lhs'];
re = this.editor[this.id + '-rhs'];
le.setOption('lineNumbers', this.settings.line_numbers);
re.setOption('lineNumbers', this.settings.line_numbers);
}
}
},
@@ -670,12 +689,12 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
jQuery('<style type="text/css">' + cmstyle + '</style>').appendTo('head');
//bind
var rhstx = jQuery('#' + this.id + '-rhs').get(0);
var rhstx = this.element.find('#' + this.id + '-rhs').get(0);
if (!rhstx) {
console.error('rhs textarea not defined - Mergely not initialized properly');
return;
}
var lhstx = jQuery('#' + this.id + '-lhs').get(0);
var lhstx = this.element.find('#' + this.id + '-lhs').get(0);
if (!rhstx) {
console.error('lhs textarea not defined - Mergely not initialized properly');
return;
@@ -708,6 +727,38 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
);
sz(true);
}
// scrollToDiff() from gutter
function gutterClicked(side, line, ev) {
// The "Merge left/right" buttons are also located in the gutter.
// Don't interfere with them:
if (ev.target && (jQuery(ev.target).closest('.merge-button').length > 0)) {
return;
}
// See if the user clicked the line number of a difference:
var i, change;
for (i = 0; i < this.changes.length; i++) {
change = this.changes[i];
if (line >= change[side+'-line-from'] && line <= change[side+'-line-to']) {
this._current_diff = i;
// I really don't like this here - something about gutterClick does not
// like mutating editor here. Need to trigger the scroll to diff from
// a timeout.
setTimeout(function() { this.scrollToDiff(); }.bind(this), 10);
break;
}
}
}
this.editor[this.id + '-lhs'].on('gutterClick', function(cm, n, gutterClass, ev) {
gutterClicked.call(this, 'lhs', n, ev);
}.bind(this));
this.editor[this.id + '-rhs'].on('gutterClick', function(cm, n, gutterClass, ev) {
gutterClicked.call(this, 'rhs', n, ev);
}.bind(this));
//bind
var setv;
if (this.settings.lhs) {
@@ -725,23 +776,10 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var self = this;
var led = self.editor[self.id+'-lhs'];
var red = self.editor[self.id+'-rhs'];
var yref = led.getScrollerElement().offsetHeight * 0.5; // center between >0 and 1/2
// set cursors
led.setCursor(Math.max(change["lhs-line-from"],0), 0); // use led.getCursor().ch ?
red.setCursor(Math.max(change["rhs-line-from"],0), 0);
// using directly CodeMirror breaks canvas alignment
// var ly = led.charCoords({line: Math.max(change["lhs-line-from"],0), ch: 0}, "local").top;
// calculate scroll offset for current change. Warning: returns relative y position so we scroll to 0 first.
led.scrollTo(null, 0);
red.scrollTo(null, 0);
self._calculate_offsets(self.id+'-lhs', self.id+'-rhs', [change]);
led.scrollTo(null, Math.max(change["lhs-y-start"]-yref, 0));
red.scrollTo(null, Math.max(change["rhs-y-start"]-yref, 0));
// right pane should simply follows
led.scrollIntoView({line: change["lhs-line-to"]});
},
_scrolling: function(editor_name) {
@@ -902,7 +940,7 @@ 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) {
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]);
@@ -970,7 +1008,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
// this is the distance from the top of the screen to the top of the
// content of the first codemirror editor
var topnode = jQuery('#' + this.id + ' .CodeMirror-measure').first();
var topnode = this.element.find('.CodeMirror-measure').first();
var top_offset = topnode.offset().top - 4;
if(!top_offset) return false;
@@ -1099,11 +1137,12 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
return changes;
},
_markup_changes: function (editor_name1, editor_name2, changes) {
jQuery('.merge-button').remove(); // clear
this.element.find('.merge-button').remove(); //clear
var self = this;
var led = this.editor[editor_name1];
var red = this.editor[editor_name2];
var current_diff = this._current_diff;
var timer = new Mgly.Timer();
led.operation(function() {
@@ -1118,6 +1157,12 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
led.addLineClass(llf, 'background', 'start');
led.addLineClass(llt, 'background', 'end');
if (current_diff == i) {
if (llf != llt) {
led.addLineClass(llf, 'background', 'current');
}
led.addLineClass(llt, 'background', 'current');
}
if (llf == 0 && llt == 0 && rlf == 0) {
led.addLineClass(llf, 'background', clazz.join(' '));
led.addLineClass(llf, 'background', 'first');
@@ -1163,7 +1208,13 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var clazz = ['mergely', 'rhs', change['op'], 'cid-' + i];
red.addLineClass(rlf, 'background', 'start');
red.addLineClass(rlt, 'background', 'end');
if (current_diff == i) {
if (rlf != rlt) {
red.addLineClass(rlf, 'background', 'current');
}
red.addLineClass(rlt, 'background', 'current');
}
if (rlf == 0 && rlt == 0 && llf == 0) {
red.addLineClass(rlf, 'background', clazz.join(' '));
red.addLineClass(rlf, 'background', 'first');
@@ -1264,11 +1315,12 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
self.chfns[self.id + '-rhs'].push(m[0].markText(m[1], m[2], m[3]));
}
});
this.trace('change', 'LCS markup time', timer.stop());
// merge buttons
var ed = {lhs:led, rhs:red};
jQuery('.merge-button').on('click', function(ev){
this.element.find('.merge-button').on('click', function(ev){
// side of mouseenter
var side = 'rhs';
var oside = 'lhs';
@@ -1292,6 +1344,35 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
self._merge_change(change, side, oside);
return false;
});
// gutter markup
var lhsLineNumbers = $('#mergely-lhs ~ .CodeMirror').find('.CodeMirror-linenumber');
var rhsLineNumbers = $('#mergely-rhs ~ .CodeMirror').find('.CodeMirror-linenumber');
rhsLineNumbers.removeClass('mergely current');
lhsLineNumbers.removeClass('mergely current');
for (var i = 0; i < changes.length; ++i) {
if (current_diff == i && change.op !== 'd') {
var change = changes[i];
var j, jf = change['rhs-line-from'], jt = change['rhs-line-to'] + 1;
for (j = jf; j < jt; j++) {
var n = (j + 1).toString();
rhsLineNumbers
.filter(function(i, node) { return $(node).text() === n; })
.addClass('mergely current');
}
}
if (current_diff == i && change.op !== 'a') {
var change = changes[i];
jf = change['lhs-line-from'], jt = change['lhs-line-to'] + 1;
for (j = jf; j < jt; j++) {
var n = (j + 1).toString();
lhsLineNumbers
.filter(function(i, node) { return $(node).text() === n; })
.addClass('mergely current');
}
}
}
this.trace('change', 'markup buttons time', timer.stop());
},
_merge_change : function(change, side, oside) {
@@ -1351,8 +1432,8 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var gutter_height = jQuery(this.editor[editor_name1].getScrollerElement()).children(':first-child').height();
var dcanvas = document.getElementById(editor_name1 + '-' + editor_name2 + '-canvas');
if (dcanvas == undefined) throw 'Failed to find: ' + editor_name1 + '-' + editor_name2 + '-canvas';
var clhs = jQuery('#' + this.id + '-lhs-margin');
var crhs = jQuery('#' + this.id + '-rhs-margin');
var clhs = this.element.find('#' + this.id + '-lhs-margin');
var crhs = this.element.find('#' + this.id + '-rhs-margin');
return {
visible_page_height: visible_page_height,
gutter_height: gutter_height,
@@ -1383,7 +1464,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
this.trace('draw', 'lhs-scroller-top', ex.lhs_scroller.scrollTop());
this.trace('draw', 'rhs-scroller-top', ex.rhs_scroller.scrollTop());
jQuery.each(jQuery.find('#' + this.id + ' canvas'), function () {
jQuery.each(this.element.find('canvas'), function () {
jQuery(this).get(0).height = ex.visible_page_height;
});
@@ -1405,6 +1486,10 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
var vp = this._get_viewport(editor_name1, editor_name2);
for (var i = 0; i < changes.length; ++i) {
var change = changes[i];
var fill = this.settings.fgcolor[change['op']];
if (this._current_diff==i) {
fill = '#000';
}
this.trace('draw', change);
// margin indicators
@@ -1415,14 +1500,14 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
this.trace('draw', 'marker calculated', lhs_y_start, lhs_y_end, rhs_y_start, rhs_y_end);
ctx_lhs.beginPath();
ctx_lhs.fillStyle = this.settings.fgcolor[(this._current_diff==i?'c':'')+change['op']];
ctx_lhs.fillStyle = fill;
ctx_lhs.strokeStyle = '#000';
ctx_lhs.lineWidth = 0.5;
ctx_lhs.fillRect(1.5, lhs_y_start, 4.5, Math.max(lhs_y_end - lhs_y_start, 5));
ctx_lhs.strokeRect(1.5, lhs_y_start, 4.5, Math.max(lhs_y_end - lhs_y_start, 5));
ctx_rhs.beginPath();
ctx_rhs.fillStyle = this.settings.fgcolor[(this._current_diff==i?'c':'')+change['op']];
ctx_rhs.fillStyle = fill;
ctx_rhs.strokeStyle = '#000';
ctx_rhs.lineWidth = 0.5;
ctx_rhs.fillRect(1.5, rhs_y_start, 4.5, Math.max(rhs_y_end - rhs_y_start, 5));
@@ -1441,7 +1526,7 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, {
// draw left box
ctx.beginPath();
ctx.strokeStyle = this.settings.fgcolor[(this._current_diff==i?'c':'')+change['op']];
ctx.strokeStyle = fill;
ctx.lineWidth = (this._current_diff==i) ? 1.5 : 1;
var rectWidth = this.draw_lhs_width;

7
lib/mergely.min.js vendored

File diff suppressed because one or more lines are too long