forked from lxm_front/Mergely
345 lines
12 KiB
HTML
345 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title>Mergely - Example editor</title>
|
|
<meta http-equiv="X-UA-Compatible" content="chrome=1, IE=edge">
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
|
|
<meta name="description" content="" />
|
|
<meta name="keywords" content="mergely,diff,merge,compare" />
|
|
<meta name="author" content="Jamie Peabody" />
|
|
<meta name="color-scheme" content="dark light">
|
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
|
|
|
<!-- CodeMirror peer dependency -->
|
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/codemirror.min.js"></script>
|
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/addon/search/searchcursor.min.js"></script>
|
|
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/codemirror.min.css" />
|
|
|
|
<!-- Bootstrap -->
|
|
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" />
|
|
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.0/font/bootstrap-icons.css">
|
|
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
|
|
|
|
<!-- jquery -->
|
|
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.slim.js"></script>
|
|
|
|
<!-- Mergely -->
|
|
<link type="text/css" rel="stylesheet" href="/lib/mergely.css" />
|
|
<script type="text/javascript" src="/lib/mergely.js"></script>
|
|
|
|
<style type="text/css">
|
|
html, body {
|
|
margin: 0;
|
|
}
|
|
body.dark-mode {
|
|
background-color: #000;
|
|
}
|
|
body.dark-mode .btn {
|
|
color: white;
|
|
}
|
|
body.dark-mode .text-black-50 {
|
|
color: #606060 !important;
|
|
}
|
|
.mergely-editor .CodeMirror {
|
|
/* adjust line height for bootstrap */
|
|
line-height: 21px;
|
|
}
|
|
#compare {
|
|
height: 300px;
|
|
visibility: hidden;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand" href="/">Mergely</a>
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
|
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
|
|
aria-label="Toggle navigation">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<span class="p-1">
|
|
<button class="btn btn-secondary" id="doc-new">
|
|
<span class="bi-file-earmark-text" />
|
|
New
|
|
</button>
|
|
</span>
|
|
<span class="p-1">
|
|
<button class="btn btn-secondary" id="doc-diff">
|
|
<span class="bi-file-diff" />
|
|
Download diff
|
|
</button>
|
|
</span>
|
|
<span class="p-1">
|
|
<button class="btn btn-secondary" id="prev-change" title="Go previous change">
|
|
<span class="bi-arrow-up-circle-fill" />
|
|
</button>
|
|
</span>
|
|
<span class="p-1">
|
|
<button class="btn btn-secondary" id="next-change" title="Go next change">
|
|
<span class="bi-arrow-down-circle-fill" />
|
|
</button>
|
|
</span>
|
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"
|
|
data-bs-toggle="dropdown" aria-expanded="false">
|
|
Options
|
|
</a>
|
|
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
|
|
<li><b class="dropdown-item">Editor options</b></li>
|
|
<li>
|
|
<div class="dropdown-item">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="dark-mode">
|
|
<label class="form-check-label" for="dark-mode">
|
|
Dark mode
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<div class="dropdown-item">
|
|
<div class="form-check form-switch">
|
|
<input checked class="form-check-input" type="checkbox" role="switch"
|
|
id="view-sidebar">
|
|
<label class="form-check-label" for="view-sidebar">
|
|
View sidebars
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<div class="dropdown-item">
|
|
<div class="form-check form-switch">
|
|
<input checked class="form-check-input" type="checkbox" role="switch"
|
|
id="wrap-lines">
|
|
<label class="form-check-label" for="wrap-lines">
|
|
Wrap lines
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<div class="dropdown-item">
|
|
<div class="form-check form-switch">
|
|
<input checked class="form-check-input" type="checkbox" role="switch"
|
|
id="line-numbers">
|
|
<label class="form-check-label" for="line-numbers">
|
|
Line numbers
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<div class="dropdown-item">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch"
|
|
id="read-only">
|
|
<label class="form-check-label" for="read-only">
|
|
Read only
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<hr class="dropdown-divider">
|
|
</li>
|
|
<li><b class="dropdown-item">Diff options</b></li>
|
|
<li>
|
|
<div class="dropdown-item">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch"
|
|
id="ignore-whitespace">
|
|
<label class="form-check-label" for="ignore-whitespace">
|
|
Ignore whitespace
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<div class="dropdown-item">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="ignore-case">
|
|
<label class="form-check-label" for="ignore-case">
|
|
Ignore case
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<div class="dropdown-item">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch"
|
|
id="ignore-ignoreaccents">
|
|
<label class="form-check-label" for="ignore-ignoreaccents">
|
|
Ignore accent characters
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<form class="d-flex flex-nowrap">
|
|
<input id="search-text" class="form-control me-2" type="search" placeholder="Search"
|
|
aria-label="Search">
|
|
<div class="btn-group">
|
|
<button id="search" type="button" class="btn btn-danger">Search</button>
|
|
<button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split"
|
|
data-bs-toggle="dropdown" aria-expanded="false">
|
|
<span class="visually-hidden">Toggle Dropdown</span>
|
|
</button>
|
|
<ul class="dropdown-menu dropdown-menu-end">
|
|
<li><a id="search-lhs" class="dropdown-item" href="#">
|
|
<span class="bi-check"></span>Search left editor</a>
|
|
</li>
|
|
<li><a id="search-rhs" class="dropdown-item" href="#">
|
|
<span class="bi-check" style="color:transparent"></span>Search right editor</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<div id="compare"></div>
|
|
<div class="container-fluid" style="font-size:12px">
|
|
<div class="row">
|
|
<div class="col" id="lhs-info">
|
|
<button class="btn p-0" id="download-lhs">
|
|
<span class="bi-box-arrow-in-down" />
|
|
</button>
|
|
<span class="text-black-50" id="lhs-characters"></span>
|
|
<span class="text-black-50" id="lhs-changes"></span>
|
|
</div>
|
|
<div class="col" style="flex: 0 0 24px">
|
|
</div>
|
|
<div class="col" id="rhs-info">
|
|
<button class="btn p-0" id="download-rhs">
|
|
<span class="bi-box-arrow-in-down" />
|
|
</button>
|
|
<span class="text-black-50" id="rhs-characters"></span>
|
|
<span class="text-black-50" id="rhs-changes"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const doc = new Mergely('#compare', {
|
|
license: 'lgpl',
|
|
wrap_lines: true
|
|
});
|
|
|
|
doc.once('updated', () => {
|
|
doc.lhs('the qúíck red FOX\njumped over the hairy dog');
|
|
doc.rhs('\tThe quick brown fox\njumped over the lazy dog');
|
|
|
|
doc.once('updated', () => {
|
|
document.getElementById('compare').style.visibility = 'visible';
|
|
});
|
|
|
|
jQuery('#ignore-whitespace').on('click', (ev) => {
|
|
doc.options({ ignorews: ev.target.checked });
|
|
});
|
|
jQuery('#ignore-case').on('click', (ev) => {
|
|
doc.options({ ignorecase: ev.target.checked });
|
|
});
|
|
jQuery('#ignore-ignoreaccents').on('click', (ev) => {
|
|
doc.options({ ignoreaccents: ev.target.checked });
|
|
});
|
|
jQuery('#view-sidebar').on('click', (ev) => {
|
|
doc.options({ sidebar: ev.target.checked });
|
|
});
|
|
jQuery('#wrap-lines').on('click', (ev) => {
|
|
doc.options({ wrap_lines: ev.target.checked });
|
|
});
|
|
jQuery('#line-numbers').on('click', (ev) => {
|
|
doc.options({ line_numbers: ev.target.checked });
|
|
});
|
|
jQuery('#read-only').on('click', (ev) => {
|
|
const lhsCm = doc.cm('lhs');
|
|
lhsCm.setOption('readOnly', ev.target.checked);
|
|
const rhsCm = doc.cm('rhs');
|
|
rhsCm.setOption('readOnly', ev.target.checked);
|
|
doc.options({});
|
|
});
|
|
jQuery('#next-change').on('click', (ev) => {
|
|
doc.scrollToDiff('next');
|
|
});
|
|
jQuery('#prev-change').on('click', (ev) => {
|
|
doc.scrollToDiff('prev');
|
|
});
|
|
jQuery('#dark-mode').on('click', (ev) => {
|
|
document.body.classList.toggle('dark-mode');
|
|
document.querySelector('.mergely-editor').classList.toggle('dark-mode');
|
|
// basically a no-op to force colors to be recalculated
|
|
doc.options({});
|
|
});
|
|
jQuery('#doc-new').on('click', () => {
|
|
doc.lhs('');
|
|
doc.rhs('');
|
|
});
|
|
jQuery('#doc-diff').on('click', () => downloadText(doc.diff(), 'doc.diff'));
|
|
jQuery('#download-lhs').on('click', () => downloadText(doc.get('lhs'), 'lhs.txt'));
|
|
jQuery('#download-rhs').on('click', () => downloadText(doc.diff('rhs'), 'rhs.txt'));
|
|
let searchLhs = true;
|
|
jQuery('#search-lhs').on('click', (ev) => {
|
|
searchLhs = true;
|
|
const lhs = document.getElementById('search-lhs').children[0];
|
|
const rhs = document.getElementById('search-rhs').children[0];
|
|
lhs.style = 'color:initial';
|
|
rhs.style = 'color:transparent';
|
|
});
|
|
jQuery('#search-rhs').on('click', (ev) => {
|
|
searchLhs = false;
|
|
const lhs = document.getElementById('search-lhs').children[0];
|
|
const rhs = document.getElementById('search-rhs').children[0];
|
|
lhs.style = 'color:transparent';
|
|
rhs.style = 'color:initial';
|
|
});
|
|
jQuery('#search-text').on('keypress', (ev) => {
|
|
console.log(ev.which)
|
|
if (event.which === 13) {
|
|
ev.preventDefault();
|
|
jQuery('#search').click();
|
|
}
|
|
});
|
|
jQuery('#search').on('click', (ev) => {
|
|
ev.preventDefault();
|
|
const text = jQuery('#search-text').get(0).value;
|
|
const direction = searchLhs ? 'lhs' : 'rhs';
|
|
doc.search(direction, text);
|
|
});
|
|
});
|
|
|
|
doc.on('updated', () => {
|
|
const info = doc.summary();
|
|
jQuery('#lhs-characters').text(`${info.lhsLength} characters`);
|
|
jQuery('#rhs-characters').text(`${info.rhsLength} characters`);
|
|
if (info.numChanges) {
|
|
jQuery('#lhs-changes').text('(changed)');
|
|
jQuery('#rhs-changes').text('(changed)');
|
|
} else {
|
|
jQuery('#lhs-changes').text('(no changes)');
|
|
jQuery('#rhs-changes').text('(no changes)');
|
|
}
|
|
});
|
|
|
|
function downloadText(text, filename) {
|
|
const b64 = btoa(text);
|
|
const link = document.createElement('a');
|
|
link.download = filename;
|
|
link.href = 'data:text/csv;charset=utf-8;base64,' + b64;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|