mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-11 10:28:41 -04:00
Replace domdiff library with morphdom
We added domdiff to replace the DiffDOM library here: https://github.com/alphagov/notifications-admin/commit/87f54d1e886f5c45ef7f12d88ef988c3f9343641 DiffDOM had updated its code to be written to the ECMAScript 6 (ES6) standard and so needed extra work to work with the older browsers in our support matrix. This was recorded as an issue here: https://www.pivotaltracker.com/n/projects/1443052/stories/165380360 Domdiff didn't work (see below for more details) so this replaces it with the morphdom library. Morphdom supports the same browsers as us and is relied on by a range of large open source projects: https://github.com/patrick-steele-idem/morphdom#what-projects-are-using-morphdom It was tricky to find alternatives to DiffDOM so if we have to source alternatives in future, other options could be: - https://github.com/choojs/nanomorph - https://diffhtml.org/index.html (using its outerHTML method) Why domdiff didn't work Turns out that domdiff was replacing the page HTML with the HTML from the AJAX response every time, not just when they differed. This isn't a bug. Domdiff is bare bones enough that it compares old DOM nodes to new DOM nodes with ===. With our code, this always results to false because our new nodes are made from HTML strings from AJAX response so are never the same node as the old one.
This commit is contained in:
@@ -6,11 +6,16 @@
|
|||||||
//
|
//
|
||||||
// Exported items will be added to the window.GOVUK namespace.
|
// Exported items will be added to the window.GOVUK namespace.
|
||||||
// For example, `export { Frontend }` will assign `Frontend` to `window.Frontend`
|
// For example, `export { Frontend }` will assign `Frontend` to `window.Frontend`
|
||||||
|
|
||||||
|
// GOVUK Frontend modules
|
||||||
import Header from 'govuk-frontend/components/header/header';
|
import Header from 'govuk-frontend/components/header/header';
|
||||||
import Details from 'govuk-frontend/components/details/details';
|
import Details from 'govuk-frontend/components/details/details';
|
||||||
import Button from 'govuk-frontend/components/button/button';
|
import Button from 'govuk-frontend/components/button/button';
|
||||||
import Radios from 'govuk-frontend/components/radios/radios';
|
import Radios from 'govuk-frontend/components/radios/radios';
|
||||||
|
|
||||||
|
// Modules from 3rd party vendors
|
||||||
|
import morphdom from 'morphdom';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Ideally this would be a NodeList.prototype.forEach polyfill
|
* TODO: Ideally this would be a NodeList.prototype.forEach polyfill
|
||||||
* This seems to fail in IE8, requires more investigation.
|
* This seems to fail in IE8, requires more investigation.
|
||||||
@@ -62,6 +67,13 @@ var Frontend = {
|
|||||||
"initAll": initAll
|
"initAll": initAll
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vendor = {
|
||||||
|
"morphdom": morphdom
|
||||||
|
}
|
||||||
|
|
||||||
|
// The exported object will be assigned to window.GOVUK in our production code
|
||||||
|
// (bundled into an IIFE by RollupJS)
|
||||||
export {
|
export {
|
||||||
Frontend
|
Frontend,
|
||||||
|
vendor
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var queues = {};
|
var queues = {};
|
||||||
|
var morphdom = global.GOVUK.vendor.morphdom;
|
||||||
var defaultInterval = 2000;
|
var defaultInterval = 2000;
|
||||||
var interval = 0;
|
var interval = 0;
|
||||||
|
|
||||||
@@ -10,18 +11,10 @@
|
|||||||
1000
|
1000
|
||||||
));
|
));
|
||||||
|
|
||||||
var getRenderer = $component => {
|
var getRenderer = $component => response => morphdom(
|
||||||
var key = $component.data('key'); // use closure to retain key when component is replaced
|
$component.get(0),
|
||||||
return response => {
|
$(response[$component.data('key')]).get(0)
|
||||||
$component = $(
|
|
||||||
global.domdiff(
|
|
||||||
$component.parent().get(0),
|
|
||||||
[$component.get(0)],
|
|
||||||
[$(response[key]).get(0)]
|
|
||||||
)[0]
|
|
||||||
);
|
);
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var getQueue = resource => (
|
var getQueue = resource => (
|
||||||
queues[resource] = queues[resource] || []
|
queues[resource] = queues[resource] || []
|
||||||
|
|||||||
@@ -146,7 +146,6 @@ const javascripts = () => {
|
|||||||
paths.npm + 'hogan.js/dist/hogan-3.0.2.js',
|
paths.npm + 'hogan.js/dist/hogan-3.0.2.js',
|
||||||
paths.npm + 'jquery/dist/jquery.min.js',
|
paths.npm + 'jquery/dist/jquery.min.js',
|
||||||
paths.npm + 'query-command-supported/dist/queryCommandSupported.min.js',
|
paths.npm + 'query-command-supported/dist/queryCommandSupported.min.js',
|
||||||
paths.npm + 'domdiff/min.js',
|
|
||||||
paths.npm + 'timeago/jquery.timeago.js',
|
paths.npm + 'timeago/jquery.timeago.js',
|
||||||
paths.npm + 'textarea-caret/index.js',
|
paths.npm + 'textarea-caret/index.js',
|
||||||
paths.npm + 'cbor-js/cbor.js'
|
paths.npm + 'cbor-js/cbor.js'
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,6 @@
|
|||||||
"@babel/preset-env": "7.4.2",
|
"@babel/preset-env": "7.4.2",
|
||||||
"cbor-js": "0.1.0",
|
"cbor-js": "0.1.0",
|
||||||
"del": "5.1.0",
|
"del": "5.1.0",
|
||||||
"domdiff": "2.2.2",
|
|
||||||
"govuk_frontend_toolkit": "8.1.0",
|
"govuk_frontend_toolkit": "8.1.0",
|
||||||
"govuk-elements-sass": "3.1.2",
|
"govuk-elements-sass": "3.1.2",
|
||||||
"govuk-frontend": "2.13.0",
|
"govuk-frontend": "2.13.0",
|
||||||
@@ -39,6 +38,7 @@
|
|||||||
"hogan": "1.0.2",
|
"hogan": "1.0.2",
|
||||||
"jquery": "3.5.0",
|
"jquery": "3.5.0",
|
||||||
"leaflet": "1.6.0",
|
"leaflet": "1.6.0",
|
||||||
|
"morphdom": "2.6.1",
|
||||||
"query-command-supported": "1.0.0",
|
"query-command-supported": "1.0.0",
|
||||||
"rollup": "1.23.1",
|
"rollup": "1.23.1",
|
||||||
"sass": "1.32.7",
|
"sass": "1.32.7",
|
||||||
|
|||||||
@@ -31,13 +31,12 @@ beforeAll(() => {
|
|||||||
|
|
||||||
$.ajax.mockImplementation(() => jqueryAJAXReturnObj);
|
$.ajax.mockImplementation(() => jqueryAJAXReturnObj);
|
||||||
|
|
||||||
// using require to execute the version we use in our our frontend build here can't add
|
// RollupJS assigns our bundled module code, including morphdom, to window.GOVUK.
|
||||||
// the domdiff variable to this scope like it does when executed in browsers because
|
// morphdom is assigned to its vendor property so we need to copy that here for the updateContent
|
||||||
// that version doesn't export it
|
// code to pick it up.
|
||||||
// we use CommonJS version instead because it does (as the default property)
|
window.GOVUK.vendor = {
|
||||||
// see https://nodejs.org/en/knowledge/getting-started/what-is-require/ for more info
|
morphdom: require('morphdom')
|
||||||
// also, we're not a browser so we need to manually attach domdiff to window
|
};
|
||||||
window.domdiff = require('domdiff/cjs').default;
|
|
||||||
require('../../app/assets/javascripts/updateContent.js');
|
require('../../app/assets/javascripts/updateContent.js');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user