Content deleted Content added
1.0.11 fix ShortenOutput omitting changes/html, improve bubble up |
1.0.12 (September 10, 2014) skin/sky/cloud colored theme, new inline chunk split, new custom split, IE8 compatibility mouse/click handler, fix bubbling, fix ShortenOutput (paragraphs, headings) |
||
Line 3:
// ==UserScript==
// @name wDiff
// @version 1.0.
// @date September
// @description improved word-based diff library with block move detection
// @homepage https://en.wikipedia.org/wiki/User:Cacycle/diff
Line 136:
if (wDiff.regExpSplit === undefined) {
wDiff.regExpSplit = {
// paragraphs: after newline
paragraph:
// sentences: after .spaces or before newline
sentence:
// inline chunks
// [[wiki link]] | {{template}} | [ext. link] |<html> | [[wiki link| | {{template| | url
chunk: /\[\[[^\[\]\n]+\]\]|\{\{[^\{\}\n]+\}\}|\[[^\[\]\n]+\]|<[^<>\[\]\{\}\n]+>|\[\[[^\[\]\|\n]+\]\]\||\{\{[^\{\}\|\n]+\||\b((https?:|)\/\/)[^\x00-\x20\s"\[\]\x7f]+/g,
// words, multi-char markup, and chars
word: new RegExp('([' + wDiff.letters + '])+|\\[\\[|\\]\\]|\\{\\{|\\}\\}|&\\w+;|\'\'\'|\'\'|==+|\\{\\||\\|\\}|\\|-|.', 'g'),
// chars
character:
};
}
Line 203 ⟶ 207:
'.wDiffMarkRight:before { content: "▶"; }' +
'.wDiffMarkLeft:before { content: "◀"; }' +
'.wDiffDelete { font-weight:
'.wDiffInsert { font-weight:
'.wDiffBlockLeft { font-weight: bold; background-color: #
'.wDiffBlockRight { font-weight: bold; background-color: #
'.wDiffMarkLeft {
'.wDiffMarkRight {
'.wDiffFragment { white-space: pre-wrap; background: #
'.wDiffContainer { }' +
'.wDiffNoChange { white-space: pre-wrap; background: #f0f0f0; border: #bbb solid; border-width: 1px 1px 1px 0.5em; border-radius: 0.5em; font-family:
'.wDiffSeparator { margin-bottom: 1em; }' +
'.wDiffBlock { }' +
Line 232 ⟶ 237:
'.wDiffMark7 { color: #ff9999; }' +
'.wDiffMark8 { color: #90d090; }' +
'.wDiffBlockHighlight { background-color: #
'.wDiffMarkHighlight { background-color: #
}
Line 263 ⟶ 268:
// dynamic replacements: {block}: block number style, {mark}: mark number style, {class}: class number, {number}: block number, {title}: title attribute (popup)
// class plus html comment are required indicators for wDiff.ShortenOutput()
if (wDiff.blockEvent === undefined) { wDiff.blockEvent = ' onmouseover="wDiff.BlockHandler(
if (wDiff.htmlContainerStart === undefined) { wDiff.htmlContainerStart = '<div class="wDiffContainer" style="' + wDiff.styleContainer + '">'; }
Line 299 ⟶ 304:
//
// javascript handler for output code, compatible with IE 8
//
// wDiff.BlockHandler: event handler for block and mark elements
if (wDiff.BlockHandler === undefined) { wDiff.BlockHandler = function (event, element, type) {
//
if ( (event === undefined) && (window.event !== undefined) ) {
type = event.type;▼
}
Line 319 ⟶ 321:
// highlight corresponding mark/block pairs
if
}▼
else if (element.attachEvent !== undefined) {▼
}▼
else {▼
}▼
block.className += ' wDiffBlockHighlight';
mark.className += ' wDiffMarkHighlight';
Line 336 ⟶ 330:
// remove mark/block highlighting
element.onmouseout = null;
element.onmouseover = function (event) { wDiff.BlockHandler(event, element, 'mouseover'); };
// getElementsByClassName
Line 355 ⟶ 351:
// scroll to corresponding mark/block element
if (type == 'click') {
if (element.removeEventListener !== undefined) {▼
// get corresponding element
Line 381 ⟶ 369:
// scroll element under mouse cursor
var top
var cursor = event.pageY;▼
top = window.pageXOffset;
var line = parseInt(window.getComputedStyle(corrElement).getPropertyValue('line-height'));▼
▲ }
▲ else {
document.documentElement.scrollTop;
▲ }
var cursor;
if (event.pageY !== undefined) {
▲ }
▲ }
var line = 12;
if (window.getComputedStyle !== undefined) {
▲ }
window.scroll(0, corrElementPos + top - cursor + line / 2);
}
Line 478 ⟶ 483:
return text.diff;
}
// new symbols object
var symbols = {
Line 498 ⟶ 503:
// calculate refined diff
wDiff.CalculateDiff(text, symbols, 'sentence');
// refine different paragraphs into chunks
wDiff.SplitRefine(text.newText, 'chunk');
wDiff.SplitRefine(text.oldText, 'chunk');
// calculate refined diff
wDiff.CalculateDiff(text, symbols, 'chunk');
// refine different sentences into words
Line 550 ⟶ 562:
var first = current;
var string = '';
// split full text or specified token
if (token === undefined) {
Line 561 ⟶ 573:
}
// split text into tokens, regExp match as separator
var number = 0;
var split = [];
var regExpMatch;
var lastIndex = 0;
while ( (regExpMatch = wDiff.regExpSplit[level].exec(string)) !== null) {
if (regExpMatch.index > lastIndex) {
split.push(string.substring(lastIndex, regExpMatch.index));
▲ }
split.push(regExpMatch[0]);
lastIndex = wDiff.regExpSplit[level].lastIndex;
▲ }
if (lastIndex < string.length) {
split.push(string.substring(lastIndex));
▲ }
// cycle trough new tokens
for (var i = 0; i < split.length; i ++) {
text.tokens[current] = {
token:
prev: prev,
next: null,
Line 900 ⟶ 926:
// bubble down as deep as possible
var front =
var back =
while (
(front !== null) && (back !== null) &&
Line 916 ⟶ 942:
// test baloon up, remember last line break or closing text
var frontStop = null;
front = text.tokens[front].prev;
back = text.tokens[back].prev;
var frontTest = front;
var backTest = back;
while (
(frontTest !== null) && (backTest !== null) &&
(text.tokens[frontTest].link !== null)
(text.tokens[frontTest].token == text.tokens[backTest].token)
) {
Line 926 ⟶ 954:
backTest = text.tokens[backTest].prev;
if (wDiff.regExpBubbleStop.test(text.tokens[frontTest].token) === true) {
frontStop =
break;
}
Line 1,220 ⟶ 1,248:
// recursively diff the unresolved sequence
if ( (iLength > 1) || (jLength > 1) ) {
// new symbols object for sub-region
var symbolsRecurse = {
Line 1,272 ⟶ 1,300:
iNext = text.newText.tokens[iNext].prev;
}
// determine the limits of of the unresolved old sequence
var jStart = null;
Line 1,289 ⟶ 1,317:
// recursively diff the unresolved sequence
if ( (iLength > 1) || (jLength > 1) ) {
// new symbols object for sub-region
var symbolsRecurse = {
Line 1,354 ⟶ 1,382:
// sort blocks by new text token number and update groups
wDiff.SortBlocks(blocks, groups);
// convert groups to insertions/deletions if maximal block length is too short
if (wDiff.blockMinLength > 0) {
Line 1,840 ⟶ 1,868:
var blockStart = groups[group].blockStart;
var blockEnd = groups[group].blockEnd;
// no block in group is at least blockMinLength words long
if (groups[group].maxWords < wDiff.blockMinLength) {
Line 1,860 ⟶ 1,888:
for (var block = blockStart; block <= blockEnd; block ++) {
if ( (block > 0) && (blocks[block - 1].type == 'del') && (blocks[block].type == 'same') ) {
// stop unlinking if more than one word or a unique word
if ( (blocks[block].words > 1) || ( (blocks[block].words == 1) && (blocks[block].unique === true) ) ) {
Line 1,874 ⟶ 1,902:
for (var block = blockEnd; block > blockStart; block --) {
if ( (blockEnd < blocks.length - 1) && (blocks[block + 1].type == 'del') && (blocks[block].type == 'same') ) {
// stop unlinking if more than one word or a unique word
if ( (blocks[block].words > 1) || ( (blocks[block].words == 1) && (blocks[block].unique === true) ) ) {
Line 2,464 ⟶ 2,492:
lines.push(regExpMatch.index);
}
// get heading positions
var headings = [];
|