Skip to content

Commit

Permalink
fix: avoid memory leak and concurrency issues (#157)
Browse files Browse the repository at this point in the history
  • Loading branch information
tripodsan committed Mar 12, 2022
1 parent 31e4302 commit b5f8c58
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 23 deletions.
14 changes: 13 additions & 1 deletion lib/HtmlDiff.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,20 @@ import { defaults } from './defaults.js';
* @param {Boolean} [options.ignoreSelfClosingSlash=false]
*/
export class HtmlDiff extends Diff {
constructor(options) {
constructor(options, tokens) {
super(options);
this.options = defaults(options);
this._tokenOverride = tokens;
}

/**
* Tokenizes the given HTML
*
* This overrides the default tokenizer from the `diff`
* @param {String} html
* @returns {Array}
*/
tokenize(html) {
return this._tokenOverride[html];
}
}
37 changes: 15 additions & 22 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,11 @@ import modifyHtmlAccordingToOptions from './utils/modify.js';
import { defaults } from './defaults.js';
import handleMasks from './utils/mask.js';

let htmlDifferOptions = {};
const modifiedTokens = {};

async function saveModifiedTokens(html) {
const tokens = await modifyHtmlAccordingToOptions(html, htmlDifferOptions);
modifiedTokens[html] = tokens.split(/({{.+?}}(?!})|[{}\(\)\[\]#\*`=:;,.<>"'\/]|\s+)/).filter(i => i);
async function getModifiedTokens(html, options) {
const tokens = await modifyHtmlAccordingToOptions(html, options);
return tokens.split(/({{.+?}}(?!})|[{}\(\)\[\]#\*`=:;,.<>"'\/]|\s+)/).filter(i => i);
}

/**
* Tokenizes the given HTML
* @param {String} html
* @returns {Array}
*/
HtmlDiff.prototype.tokenize = function(html) {
return modifiedTokens[html];
};

/**
* @class HtmlDiffer
* @constructor
Expand All @@ -33,9 +21,7 @@ HtmlDiff.prototype.tokenize = function(html) {
*/
export class HtmlDiffer {
constructor(options) {
options = defaults(options);

htmlDifferOptions = options;
this.options = defaults(options);
}

/**
Expand All @@ -47,11 +33,18 @@ export class HtmlDiffer {
* @returns {Diff}
*/
async diffHtml(html1, html2) {
await saveModifiedTokens(html1);
await saveModifiedTokens(html2);
// precompute the tokenized html here, since it can't do it in `Diff.tokenize()` because
// the sax parser is async
const tokens = {
html1: await getModifiedTokens(html1, this.options),
html2: await getModifiedTokens(html2, this.options)
};

const htmlDiffer = new HtmlDiff(this.options, tokens);

const htmlDiffer = new HtmlDiff(htmlDifferOptions);
const diff = htmlDiffer.diff(html1, html2);
// just pass in keys for the left and right html, the original strings are no longer used
// after tokenize()
const diff = htmlDiffer.diff('html1', 'html2');

return handleMasks(diff);
};
Expand Down

0 comments on commit b5f8c58

Please sign in to comment.