npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@markedjs/html-differ

v4.0.2

Published

Compares two HTML

Downloads

3,995

Readme

html-differ

Build Status Install Size

Compares two HTML strings.

The comparison algorithm

html-differ compares HTML using the following criteria:

  • <!DOCTYPE> declarations are case-insensitive, so the following two code samples will be considered to be equivalent:
<!DOCTYPE HTML PUBLIC "_PUBLIC" "_SYSTEM">
<!doctype html public "_PUBLIC" "_SYSTEM">
  • Whitespaces (spaces, tabs, new lines etc.) inside start and end tags are ignored during the comparison.

For example, the following two code samples will be considered to be equivalent:

<span id="1"></span>
<span id=
    "1"    ></span   >
  • Two respective lists of attributes are considered to be equivalent even if they are specified in different order.

For example, the following two code samples will be considered to be equivalent:

<span id="blah" class="ololo" tabIndex="1">Text</span>
<span tabIndex="1" id="blah" class="ololo">Text</span>
  • Two respective attributes class are considered to be equivalent if they refer to the same groups of CSS styles.

For example, the following two code samples will be considered to be equivalent:

<span class="ab bc cd">Text</span>
<span class=" cd  ab bc bc">Text</span>

CAUTION! html-differ does not check the validity of HTML, but compares them using the above shown criteria and specified options (see the list of possible options).

Install

$ npm install @markedjs/html-differ

API

HtmlDiffer

import { HtmlDiffer } from '@markedjs/html-differ';
const htmlDiffer = new HtmlDiffer(options);

where options is an object.

Options

ignoreAttributes: [Array]

Sets what kind of respective attributes' content will be ignored during the comparison (default: []).

Example: ['id', 'for'] The following two code samples will be considered to be equivalent:

<label for="random">Text</label>
<input id="random">
<label for="sfsdfksdf">Text</label>
<input id="sfsdfksdf">
compareAttributesAsJSON: [Array]

Sets what kind of respective attributes' content will be compared as JSON objects, but not as strings (default: []). In cases when the value of the attribute is an invalid JSON or can not be wrapped into a function, it will be compared as undefined.

Example: [{ name: 'data', isFunction: false }, { name: 'onclick', isFunction: true }] The following two code samples will be considered to be equivalent:

<div data='{"bla":{"first":"ololo","second":"trololo"}}'></div>
<span onclick='return {"aaa":"bbb","bbb":"aaa"}'></span>

<button data='REALLY BAD JSON'></button>
<button onclick='REALLY BAD FUNCTION'></button>
<div data='{"bla":{"second":"trololo","first":"ololo"}}'></div>
<span onclick='return {"bbb":"aaa","aaa":"bbb"}'></span>

<button data='undefined'></button>
<button onclick='undefined'></button>

REMARK! The first element of the array could be written in a short form as string: ['data', { name: 'onclick', isFunction: true }].

ignoreWhitespaces: Boolean

Makes html-differ ignore whitespaces (spaces, tabs, new lines etc.) during the comparison (default: true).

Example: true The following two code samples will be considered to be equivalent:

<html>Text Text<head lang="en"><title></title></head><body>Text</body></html>
 <html>
 Text   Text
<head lang="en">
    <title>               </title>


            </head>

<body>
     Text

    </body>




</html>
ignoreComments: Boolean

Makes html-differ ignore HTML comments during the comparison (default: true).

REMARK! Does not ignore conditional comments.

Example: true The following two code samples will be considered to be equivalent:

<!DOCTYPE html>
<!-- comments1 -->
<html>
<head lang="en">
    <meta charset="UTF-8">
    <!--[if IE]>
        <link rel="stylesheet" type="text/css" href="all-ie-only.css" />
    <![endif]-->
    <!--[if !IE]><!-->
        <link href="non-ie.css" rel="stylesheet">
    <!--<![endif]-->
</head>
<body>
Text<!-- comments2 -->
</body>
</html>
<!DOCTYPE html>

<html>
<head lang="en">
    <meta charset="UTF-8">
    <!--[if IE]>
        <link href="all-ie-only.css" type="text/css" rel="stylesheet"/>
    <![endif]-->
    <!--[if !IE]><!-->
        <link href="non-ie.css" rel="stylesheet">
    <!--<![endif]-->
</head>
<body>
Text
</body>
</html>
ignoreEndTags: Boolean

Makes html-differ ignore end tags during the comparison (default: false).

Example: true The following two code samples will be considered to be equivalent:

<span>Text</span>
<span>Text</spane>
ignoreSelfClosingSlash: Boolean

Makes html-differ ignore tags' self closing slash during the comparison (default: false).

Example: true For example, the following two code samples will be considered to be equivalent:

<img src="blah.jpg" />
<img src="blah.jpg">

Presets

  • bem - sets predefined options for BEM.
Usage

Passing of a preset via the constructor:

import { HtmlDiffer } from '@markedjs/html-differ';
const htmlDiffer = new HtmlDiffer('bem');

Redefinition of a preset via the constructor:

import { HtmlDiffer } from '@markedjs/html-differ';
const htmlDiffer = new HtmlDiffer({ preset: 'bem', ignoreAttributes: [] });

Methods

htmlDiffer.diffHtml

@param {String} - the 1-st HTML code @param {String} - the 2-nd HTML code @returns Promise<{Array of objects}> - array with diffs between HTML

htmlDiffer.isEqual

@param {String} - the 1-st HTML code @param {String} - the 2-nd HTML code @returns Promise<{Boolean}>

Logger

import * as logger from '@markedjs/html-differ/lib/logger';

Methods

logger.getDiffText

@param {Array of objects} - the result of the work of the method htmlDiffer.diffHtml @param {Object} - options:

  • charsAroundDiff: Number - the number of characters around the diff result between two HTML (default: 40).

@returns {String}

logger.logDiffText

@param {Array of objects} - the result of the work of the method htmlDiffer.diffHtml @param {Object} - options:

  • charsAroundDiff: Number - the number of characters around the diff result between two HTML (default: 40).

@returns - pretty logging of diffs:

Example

import fs from 'fs';
import { HtmlDiffer } from '@markedjs/html-differ';
import * as logger from '@markedjs/html-differ/lib/logger';

const html1 = fs.readFileSync('1.html', 'utf-8');
const html2 = fs.readFileSync('2.html', 'utf-8');

const options = {
  ignoreAttributes: [],
  compareAttributesAsJSON: [],
  ignoreWhitespaces: true,
  ignoreComments: true,
  ignoreEndTags: false
};

const htmlDiffer = new HtmlDiffer(options);

async function run() {
  const diff = await htmlDiffer.diffHtml(html1, html2);
  const isEqual = await htmlDiffer.isEqual(html1, html2);
  const res = logger.getDiffText(diff, { charsAroundDiff: 40 });

  logger.logDiffText(diff, { charsAroundDiff: 40 });
}

run();

Usage as a program

$ html-differ --help
Compares two HTML

Usage:
  html-differ [OPTIONS] [ARGS]

Options:
  -h, --help : Help
  -v, --version : Shows the version number
  --config=CONFIG : Path to a configuration JSON file
  --bem : Uses predefined options for BEM (deprecated)
  -p PRESET, --preset=PRESET : Name of a preset
  --chars-around-diff=CHARSAROUNDDIFF : The number of characters around the diff (default: 40)

Arguments:
  PATH1 : Path to the 1-st HTML file (required)
  PATH2 : Path to the 2-nd HTML file (required)

Example

$ html-differ path/to/html1 path/to/html2

$ html-differ --config=path/to/config --chars-around-diff=40 path/to/html1 path/to/html2

$ html-differ --preset=bem path/to/html1 path/to/html2

Configuration file

Study the following file config.json:

{
  "ignoreAttributes": [],
  "compareAttributesAsJSON": [],
  "ignoreWhitespaces": true,
  "ignoreComments": true,
  "ignoreEndTags": false
}

Masks

html-differ supports handling of masks in HTML.

For example, the following two code samples will be considered to be equivalent:

<div id="{{[a-z]*\s\d+}}">
<div id="text 12345">

Syntax

Masks in html-differ have the following syntax:

{{RegExp}}

where:

  • {{ – opening identifier of the mask.

  • RegExp – regular expression for matching with the corresponding value in another HTML. The syntax is similar to regular expressions in JavaScript written in a literal notation.

  • }} – closing identifier of the mask.

Screening

The rules of screening of symbols are similar to the rules which are used in regular expressions in JavaScript written in a literal notation.

For example, the following two code samples will be considered to be equivalent:

<div id="{{\d\.\d}}">
<div id="1.1">

If you want to use {{ or }} inside a mask, you should screen both curly braces, i.e. \{\} or \}\}.

For example, the following two code samples will be considered to be equivalent:

<div class="{{a\{\{b\}\}c}}">
<div class="a{{b}}c">