@hugsmidjan/htmldiff-js
Version:
JavaScript port of HtmlDiff.Net which is itself a C# port of HtmlDiff. Modified for reglugerd.is
1 lines • 9.63 kB
JavaScript
module.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var s=t[r]={i:r,l:!1,exports:{}};return e[r].call(s.exports,s,s.exports,n),s.l=!0,s.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)n.d(r,s,function(t){return e[t]}.bind(null,s));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";n.r(t);var r={equal:0,delete:1,insert:2,none:3,replace:4};class s{constructor(e,t,n){this.startInOld=e,this.startInNew=t,this.size=n}get endInOld(){return this.startInOld+this.size}get endInNew(){return this.startInNew+this.size}}class i{constructor(){this.blockSize=0,this.repeatingWordsAccuracy=0,this.ignoreWhitespaceDifferences=!1}}const o=/^\s*<\/?[^>]+>\s*$/,l=/<[^\s>]+/,h=/^(\s| )+$/,c=/(?:[\w\d#@þæðöøóòôõáàåäãúùůüûíïýỳÿéèêßçñąćęłńśżź,.])+/i,d=["<img","<video","<iframe"];function a(e){return!d.some(t=>null!==e&&e.startsWith(t))&&o.test(e)}function u(e,t,n){return["<",t,' class="',n,'">',e,"</",t,">"].join("")}function f(e){return"<"===e}function p(e){return"&"===e}function w(e){return";"===e}function g(e){return h.test(e)}function I(e){return a(e)?function(e){return e=l.exec(e)[0]+(e.endsWith("/>")?"/>":">")}(e):e}function W(e){return c.test(e)}function O(e,t,n){return e.push(t),e.length>n&&e.shift(),e.length!==n?null:e.join("")}class m{constructor(e,t,n,r,s,i,o){this.oldWords=e,this.newWords=t,this.startInOld=n,this.endInOld=r,this.startInNew=s,this.endInNew=i,this.options=o}indexNewWords(){this.wordIndices=new Map;let e=[];for(let t=this.startInNew;t<this.endInNew;t++){let n=O(e,this.normalizeForIndex(this.newWords[t]),this.options.blockSize);null!==n&&(this.wordIndices.has(n)?this.wordIndices.get(n).push(t):this.wordIndices.set(n,[t]))}}normalizeForIndex(e){return e=I(e),this.options.IgnoreWhiteSpaceDifferences&&g(e)?" ":e}findMatch(){if(this.indexNewWords(),this.removeRepeatingWords(),0===this.wordIndices.length)return null;let e=this.startInOld,t=this.startInNew,n=0,r=new Map;const i=this.options.blockSize;let o=[];for(let s=this.startInOld;s<this.endInOld;s++){let l=O(o,this.normalizeForIndex(this.oldWords[s]),i);if(null===l)continue;let h=new Map;if(this.wordIndices.has(l)){for(let o of this.wordIndices.get(l)){let l=(r.has(o-1)?r.get(o-1):0)+1;h.set(o,l),l>n&&(e=s-l-i+2,t=o-l-i+2,n=l)}r=h}else r=h}return 0!==n?new s(e,t,n+i-1):null}removeRepeatingWords(){let e=this.newWords.length+this.options.repeatingWordsAccuracy,t=Array.from(this.wordIndices.entries()).filter(t=>t[1].length>e).map(e=>e[0]);for(let e of t)this.wordIndices.delete(e)}}class x{constructor(e,t,n,r,s){this.action=e,this.startInOld=t,this.endInOld=n,this.startInNew=r,this.endInNew=s}}var b={character:0,tag:1,whitespace:2,entity:3};function N(e,t){let n={mode:b.character,currentWord:[],words:[]},r=function(e,t){let n=new Map;if(null===t)return n;for(let r of t){let t;for(;null!==(t=r.exec(e));){if(n.has(t.index))throw new Error("One or more block expressions result in a text sequence that overlaps. Current expression: "+r.toString());n.set(t.index,t.index+t[0].length)}}return n}(e,t),s=!!r.size,i=!1,o=-1;for(let t=0;t<e.length;t++){var l=e[t];if(s){o===index&&(o=-1,i=!1);let e=0;if(r.has(index)&&(e=r.get(index),i=!0,o=e),i){n.currentWord.push(l),n.mode=b.character;continue}}switch(n.mode){case b.character:f(l)?k(n,"<",b.tag):p(l)?k(n,l,b.entity):g(l)?k(n,l,b.whitespace):/[,.]/.test(l)&&(g(e[t+1])||void 0===e[t+1])?k(n,l,b.character):W(l)&&(0===n.currentWord.length||W(n.currentWord[n.currentWord.length-1]))?n.currentWord.push(l):k(n,l,b.character);break;case b.tag:">"===l?(n.currentWord.push(l),n.words.push(n.currentWord.join("")),n.currentWord=[],n.mode=g(l)?b.whitespace:b.character):n.currentWord.push(l);break;case b.whitespace:f(l)?k(n,l,b.tag):p(l)?k(n,l,b.entity):g(l)?n.currentWord.push(l):k(n,l,b.character);break;case b.entity:if(f(l))k(n,l,b.tag);else if(g(l))k(n,l,b.whitespace);else if(w(l)){let e=!0;if(0!==n.currentWord.length&&(n.currentWord.push(l),n.words.push(n.currentWord.join("")),n.words.length>2&&g(n.words[n.words.length-2])&&g(n.words[n.words.length-1]))){let t=n.words[n.words.length-2],r=n.words[n.words.length-1];n.words.splice(n.words.length-2,2),n.currentWord=[(t+r).split()],n.mode=b.whitespace,e=!1}e&&(n.currentWord=[],n.mode=b.character)}else W(l)?n.currentWord.push(l):k(n,l,b.character)}}return 0!==n.currentWord.length&&n.words.push(n.currentWord.join("")),n.words}function k(e,t,n){0!==e.currentWord.length&&e.words.push(e.currentWord.join("")),e.currentWord=[t],e.mode=n}const y=new Map([["</strong>",0],["</em>",0],["</b>",0],["</i>",0],["</big>",0],["</small>",0],["</u>",0],["</sub>",0],["</strike>",0],["</s>",0],["</dfn>",0]]),v=/<((strong)|(b)|(i)|(dfn)|(em)|(big)|(small)|(u)|(sub)|(sup)|(strike)|(s))[\>\s]+/gi;class M{constructor(e,t){this.content=[],this.newText=t.normalize("NFC"),this.oldText=e.normalize("NFC"),this.specialTagDiffStack=[],this.newWords=[],this.oldWords=[],this.matchGranularity=0,this.blockExpressions=[],this.repeatingWordsAccuracy=1,this.ignoreWhiteSpaceDifferences=!1,this.orphanMatchThreshold=0}build(){if(this.oldText===this.newText)return this.newText;this.splitInputsIntoWords(),this.matchGranularity=Math.min(4,this.oldWords.length,this.newWords.length);let e=this.operations();for(let t of e)this.performOperation(t);return this.content.join("")}addBlockExpression(e){this.blockExpressions.push(e)}splitInputsIntoWords(){this.oldWords=N(this.oldText,this.blockExpressions),this.oldText=null,this.newWords=N(this.newText,this.blockExpressions),this.newText=null}performOperation(e){switch(e.action){case r.equal:this.processEqualOperation(e);break;case r.delete:this.processDeleteOperation(e,"diffdel");break;case r.insert:this.processInsertOperation(e,"diffins");break;case r.none:break;case r.replace:this.processReplaceOperation(e)}}processReplaceOperation(e){this.processDeleteOperation(e,"diffmod"),this.processInsertOperation(e,"diffmod")}processInsertOperation(e,t){let n=this.newWords.filter((t,n)=>n>=e.startInNew&&n<e.endInNew);this.insertTag("ins",t,n)}processDeleteOperation(e,t){let n=this.oldWords.filter((t,n)=>n>=e.startInOld&&n<e.endInOld);this.insertTag("del",t,n)}processEqualOperation(e){let t=this.newWords.filter((t,n)=>n>=e.startInNew&&n<e.endInNew);this.content.push(t.join(""))}insertTag(e,t,n){for(;n.length;){let r=this.extractConsecutiveWords(n,e=>!a(e)),s="",i=!1;if(0!==r.length){let n=u(r.join(""),e,t);this.content.push(n)}else{if(v.test(n[0])){let t=n[0].match(v);if(t="<"+t[0].replace(/(<|>| )/g,"")+">",this.specialTagDiffStack.push(t),s='<ins class="mod">',"del"===e)for(n.shift();n.length>0&&v.test(n[0]);)n.shift()}else if(y.has(n[0])){let t=0===this.specialTagDiffStack.length?null:this.specialTagDiffStack.pop();if(null===t||t!==n[n.length-1].replace(/\//g,"")||(s="</ins>",i=!0),"del"===e)for(n.shift();n.length>0&&y.has(n[0]);)n.shift()}if(0===n.length&&0===s.length)break;i?this.content.push(s+this.extractConsecutiveWords(n,a).join("")):this.content.push(this.extractConsecutiveWords(n,a).join("")+s)}}}extractConsecutiveWords(e,t){let n=null;for(let r=0;r<e.length;r++){let s=e[r];if(0===r&&" "===s&&(e[r]=" "),!t(s)){n=r;break}}if(null!==n){let t=e.filter((e,t)=>t>=0&&t<n);return n>0&&e.splice(0,n),t}{let t=e.filter((t,n)=>n>=0&&n<e.length);return e.splice(0,e.length),t}}operations(){let e=0,t=0,n=[],i=this.matchingBlocks();i.push(new s(this.oldWords.length,this.newWords.length,0));let o=this.removeOrphans(i);for(let s of o){let i,o=e===s.startInOld,l=t===s.startInNew;i=o||l?o&&!l?r.insert:o?r.none:r.delete:r.replace,i!==r.none&&n.push(new x(i,e,s.startInOld,t,s.startInNew)),0!==s.length&&n.push(new x(r.equal,s.startInOld,s.endInOld,s.startInNew,s.endInNew)),e=s.endInOld,t=s.endInNew}return n}*removeOrphans(e){let t=null,n=null;for(let r of e){if(null===n){t=new s(0,0,0),n=r;continue}if(t.endInOld===n.startInOld&&t.endInNew===n.startInNew||n.endInOld===r.startInOld&&n.endInNew===r.startInNew){yield n;t=n;n=r;continue}let e=(e,t)=>e+t.length,i=this.oldWords.slice(t.endInOld,r.startInOld).reduce(e,0),o=this.newWords.slice(t.endInNew,r.startInNew).reduce(e,0);this.newWords.slice(n.startInNew,n.endInNew).reduce(e,0)>Math.max(i,o)*this.orphanMatchThreshold&&(yield n),t=n,n=r}yield n}matchingBlocks(){let e=[];return this.findMatchingBlocks(0,this.oldWords.length,0,this.newWords.length,e),e}findMatchingBlocks(e,t,n,r,s){let i=this.findMatch(e,t,n,r);null!==i&&(e<i.startInOld&&n<i.startInNew&&this.findMatchingBlocks(e,i.startInOld,n,i.startInNew,s),s.push(i),i.endInOld<t&&i.endInNew<r&&this.findMatchingBlocks(i.endInOld,t,i.endInNew,r,s))}findMatch(e,t,n,r){for(let s=this.matchGranularity;s>0;s--){let o=new i;o.blockSize=s,o.repeatingWordsAccuracy=this.repeatingWordsAccuracy,o.ignoreWhitespaceDifferences=this.ignoreWhiteSpaceDifferences;let l=new m(this.oldWords,this.newWords,e,t,n,r,o).findMatch();if(null!==l)return l}return null}}M.execute=function(e,t){return new M(e,t).build()};t.default=M}]);