diff --git a/__tests__/router.spec.js b/__tests__/router.spec.js index b07e8ba..dc51f97 100644 --- a/__tests__/router.spec.js +++ b/__tests__/router.spec.js @@ -216,4 +216,27 @@ describe('router', () => { }); }); }); + + describe('with IE9', () => { + test('no error is thrown, because of the domNode.remove()', () => { + const domEntryPointMock = { + parentElement: { + insertBefore: () => {} + }, + cloneNode: () => domEntryPointMock, + removeNode: jest.fn(), + remove: undefined + }; + + const init = () => { + const router = createRouter(domEntryPointMock); + router + .addRoute('', () => {}); + simulateHashChange(''); + expect(domEntryPointMock.removeNode.mock.calls.length).toEqual(1); + }; + expect(init).not.toThrow(); + + }); + }); }); diff --git a/dist/vanilla-ui-router.js b/dist/vanilla-ui-router.js index a7b0ba2..251d874 100644 --- a/dist/vanilla-ui-router.js +++ b/dist/vanilla-ui-router.js @@ -120,7 +120,13 @@ var createRouter = function createRouter(domEntryPoint) { var domClone = lastDomEntryPoint.cloneNode(true); domEntryPoint.parentElement.insertBefore(domClone, domEntryPoint); - domEntryPoint.remove(); + + if (typeof domEntryPoint.remove === 'undefined') { + domEntryPoint.removeNode(true); + } else { + domEntryPoint.remove(); + } + domEntryPoint = domClone; }; diff --git a/dist/vanilla-ui-router.js.map b/dist/vanilla-ui-router.js.map index 5e36cce..da7461c 100644 --- a/dist/vanilla-ui-router.js.map +++ b/dist/vanilla-ui-router.js.map @@ -1 +1 @@ -{"version":3,"file":null,"sources":["../core/routeParams.js","../core/dataProvider.js","../core/templates.js","../index.js"],"sourcesContent":["export const parseRouteParamToCorrectType = paramValue => {\n\tif (!isNaN(paramValue)) {\n\t\treturn parseInt(paramValue, 10);\n\t}\n\n\tif (paramValue === 'true' || paramValue === 'false') {\n\t\treturn JSON.parse(paramValue);\n\t}\n\n\treturn paramValue;\n};\n\nexport const extractRouteParams = (routeIdentifier, currentHash) => {\n\tconst splittedHash = currentHash.split('/');\n\tconst splittedRouteIdentifier = routeIdentifier.split('/');\n\n\treturn splittedRouteIdentifier.map((routeIdentifierToken, index) => {\n\t\tif (routeIdentifierToken.indexOf(':', 0) === -1) {\n\t\t\treturn null;\n\t\t}\n\t\tconst routeParam = {};\n\t\tconst key = routeIdentifierToken.substr(1, routeIdentifierToken.length - 1);\n\t\trouteParam[key] = splittedHash[index];\n\t\treturn routeParam;\n\t})\n\t.filter(p => p !== null)\n\t.reduce((acc, curr) => {\n\t\tObject.keys(curr).forEach(key => {\n\t\t\tacc[key] = parseRouteParamToCorrectType(curr[key]);\n\t\t});\n\t\treturn acc;\n\t}, {});\n};\n\nexport const findMatchingRouteIdentifier = (currentHash, routeKeys) => {\n\tconst splittedHash = currentHash.split('/');\n\tconst firstHashToken = splittedHash[0];\n\n\treturn routeKeys\n\t\t.filter(routeKey => {\n\t\t\tconst splittedRouteKey = routeKey.split('/');\n\t\t\tconst staticRouteTokensAreEqual = splittedRouteKey\n\t\t\t\t.map((routeToken, i) => {\n\t\t\t\t\tif (routeToken.indexOf(':', 0) !== -1) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn routeToken === splittedHash[i];\n\t\t\t\t})\n\t\t\t\t.reduce((countInvalid, currentValidationState) => {\n\t\t\t\t\tif (currentValidationState === false) {\n\t\t\t\t\t\t++countInvalid;\n\t\t\t\t\t}\n\t\t\t\t\treturn countInvalid;\n\t\t\t\t}, 0) === 0;\n\n\t\t\treturn routeKey.indexOf(firstHashToken, 0) !== -1 &&\n\t\t\t\t\t\t\tstaticRouteTokensAreEqual &&\n\t\t\t\t\t\t\tsplittedHash.length === splittedRouteKey.length;\n\t\t})[0];\n};\n","export const loadTemplate = (templateUrl, successCallback) => {\n\tvar xhr = new XMLHttpRequest();\n\txhr.onreadystatechange = function () {\n\t\tif (xhr.readyState === 4) {\n\t\t\tsuccessCallback(xhr.responseText);\n\t\t}\n\t};\n\txhr.open('GET', templateUrl);\n\txhr.send();\n};\n","import {loadTemplate} from './dataProvider';\n\nexport const renderTemplates = (routeConfiguration, domEntryPoint, successCallback) => {\n\tif (!routeConfiguration) {\n\t\treturn;\n\t}\n\n\tif (routeConfiguration.templateString) {\n\t\tdomEntryPoint.innerHTML = routeConfiguration.templateString;\n\t\tsuccessCallback();\n\t}\n\n\tif (routeConfiguration.templateUrl) {\n\t\tloadTemplate(routeConfiguration.templateUrl, templateString => {\n\t\t\tdomEntryPoint.innerHTML = templateString;\n\t\t\tsuccessCallback();\n\t\t});\n\t}\n\n\tif (routeConfiguration.templateId) {\n\t\tconst templateScript = document.getElementById(routeConfiguration.templateId);\n\t\tdomEntryPoint.innerHTML = templateScript.text;\n\t\tsuccessCallback();\n\t}\n};\n","import {\n\textractRouteParams,\n\tfindMatchingRouteIdentifier\n} from './core/routeParams';\nimport {renderTemplates} from './core/templates';\n\nexport const createRouter = domEntryPoint => {\n\tlet routes = {};\n\tconst lastDomEntryPoint = domEntryPoint.cloneNode(true);\n\tlet lastRouteHandler = null;\n\n\tconst navigateTo = hashUrl => {\n\t\twindow.location.hash = hashUrl;\n\t};\n\n\tconst otherwise = routeHandler => {\n\t\troutes['*'] = routeHandler;\n\t};\n\n\tconst addRoute = (hashUrl, routeHandler) => {\n\t\troutes[hashUrl] = routeHandler;\n\t\treturn {addRoute, otherwise, navigateTo};\n\t};\n\n\tconst initializeDomElement = () => {\n\t\tif (!domEntryPoint.parentElement) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domClone = lastDomEntryPoint.cloneNode(true);\n\t\tdomEntryPoint.parentElement.insertBefore(domClone, domEntryPoint);\n\t\tdomEntryPoint.remove();\n\t\tdomEntryPoint = domClone;\n\t};\n\n\tconst disposeLastRoute = () => {\n\t\tif (!lastRouteHandler) return;\n\t\tif (typeof lastRouteHandler.dispose === 'undefined') return;\n\t\tlastRouteHandler.dispose(domEntryPoint);\n\t};\n\n\tconst handleRouting = () => {\n\t\tconst defaultRouteIdentifier = '*';\n\t\tconst currentHash = location.hash.slice(1);\n\n\t\tconst maybeMatchingRouteIdentifier = findMatchingRouteIdentifier(currentHash, Object.keys(routes));\n\t\tlet routeParams = {};\n\t\tif (maybeMatchingRouteIdentifier) {\n\t\t\trouteParams = extractRouteParams(maybeMatchingRouteIdentifier, currentHash);\n\t\t}\n\n\t\tconst routeHandler = Object.keys(routes).indexOf(maybeMatchingRouteIdentifier) > -1 ? routes[maybeMatchingRouteIdentifier] : routes[defaultRouteIdentifier];\n\n\t\tif (!routeHandler) {\n\t\t\treturn;\n\t\t}\n\n\t\tdisposeLastRoute(routeHandler);\n\n\t\t// Memory last routeHandler\n\t\tlastRouteHandler = routeHandler;\n\n\t\tinitializeDomElement();\n\n\t\tif (typeof routeHandler === 'function') {\n\t\t\trouteHandler(domEntryPoint, routeParams);\n\t\t} else {\n\n\t\t\trenderTemplates(routeHandler, domEntryPoint, () => {\n\t\t\t\tif (typeof routeHandler.routeHandler === 'function') {\n\t\t\t\t\trouteHandler.routeHandler(domEntryPoint, routeParams);\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\t};\n\n\tif (window) {\n\t\twindow.removeEventListener('hashchange', handleRouting);\n\t\twindow.addEventListener('hashchange', handleRouting);\n\t\twindow.removeEventListener('load', handleRouting);\n\t\twindow.addEventListener('load', handleRouting);\n\t}\n\n\treturn {addRoute, otherwise, navigateTo};\n};\n"],"names":["parseRouteParamToCorrectType","isNaN","paramValue","parseInt","JSON","parse","extractRouteParams","routeIdentifier","currentHash","splittedHash","split","splittedRouteIdentifier","map","routeIdentifierToken","index","indexOf","routeParam","key","substr","length","filter","p","reduce","acc","curr","keys","forEach","findMatchingRouteIdentifier","routeKeys","firstHashToken","splittedRouteKey","routeKey","staticRouteTokensAreEqual","routeToken","i","countInvalid","currentValidationState","loadTemplate","templateUrl","successCallback","xhr","XMLHttpRequest","onreadystatechange","readyState","responseText","open","send","renderTemplates","routeConfiguration","domEntryPoint","templateString","innerHTML","templateId","templateScript","document","getElementById","text","createRouter","routes","lastDomEntryPoint","cloneNode","lastRouteHandler","navigateTo","location","hash","hashUrl","otherwise","routeHandler","addRoute","initializeDomElement","parentElement","domClone","insertBefore","remove","disposeLastRoute","dispose","handleRouting","defaultRouteIdentifier","slice","maybeMatchingRouteIdentifier","Object","routeParams","window","removeEventListener","addEventListener"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":null,"sources":["../core/routeParams.js","../core/dataProvider.js","../core/templates.js","../index.js"],"sourcesContent":["export const parseRouteParamToCorrectType = paramValue => {\n\tif (!isNaN(paramValue)) {\n\t\treturn parseInt(paramValue, 10);\n\t}\n\n\tif (paramValue === 'true' || paramValue === 'false') {\n\t\treturn JSON.parse(paramValue);\n\t}\n\n\treturn paramValue;\n};\n\nexport const extractRouteParams = (routeIdentifier, currentHash) => {\n\tconst splittedHash = currentHash.split('/');\n\tconst splittedRouteIdentifier = routeIdentifier.split('/');\n\n\treturn splittedRouteIdentifier.map((routeIdentifierToken, index) => {\n\t\tif (routeIdentifierToken.indexOf(':', 0) === -1) {\n\t\t\treturn null;\n\t\t}\n\t\tconst routeParam = {};\n\t\tconst key = routeIdentifierToken.substr(1, routeIdentifierToken.length - 1);\n\t\trouteParam[key] = splittedHash[index];\n\t\treturn routeParam;\n\t})\n\t.filter(p => p !== null)\n\t.reduce((acc, curr) => {\n\t\tObject.keys(curr).forEach(key => {\n\t\t\tacc[key] = parseRouteParamToCorrectType(curr[key]);\n\t\t});\n\t\treturn acc;\n\t}, {});\n};\n\nexport const findMatchingRouteIdentifier = (currentHash, routeKeys) => {\n\tconst splittedHash = currentHash.split('/');\n\tconst firstHashToken = splittedHash[0];\n\n\treturn routeKeys\n\t\t.filter(routeKey => {\n\t\t\tconst splittedRouteKey = routeKey.split('/');\n\t\t\tconst staticRouteTokensAreEqual = splittedRouteKey\n\t\t\t\t.map((routeToken, i) => {\n\t\t\t\t\tif (routeToken.indexOf(':', 0) !== -1) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn routeToken === splittedHash[i];\n\t\t\t\t})\n\t\t\t\t.reduce((countInvalid, currentValidationState) => {\n\t\t\t\t\tif (currentValidationState === false) {\n\t\t\t\t\t\t++countInvalid;\n\t\t\t\t\t}\n\t\t\t\t\treturn countInvalid;\n\t\t\t\t}, 0) === 0;\n\n\t\t\treturn routeKey.indexOf(firstHashToken, 0) !== -1 &&\n\t\t\t\t\t\t\tstaticRouteTokensAreEqual &&\n\t\t\t\t\t\t\tsplittedHash.length === splittedRouteKey.length;\n\t\t})[0];\n};\n","export const loadTemplate = (templateUrl, successCallback) => {\n\tvar xhr = new XMLHttpRequest();\n\txhr.onreadystatechange = function () {\n\t\tif (xhr.readyState === 4) {\n\t\t\tsuccessCallback(xhr.responseText);\n\t\t}\n\t};\n\txhr.open('GET', templateUrl);\n\txhr.send();\n};\n","import {loadTemplate} from './dataProvider';\n\nexport const renderTemplates = (routeConfiguration, domEntryPoint, successCallback) => {\n\tif (!routeConfiguration) {\n\t\treturn;\n\t}\n\n\tif (routeConfiguration.templateString) {\n\t\tdomEntryPoint.innerHTML = routeConfiguration.templateString;\n\t\tsuccessCallback();\n\t}\n\n\tif (routeConfiguration.templateUrl) {\n\t\tloadTemplate(routeConfiguration.templateUrl, templateString => {\n\t\t\tdomEntryPoint.innerHTML = templateString;\n\t\t\tsuccessCallback();\n\t\t});\n\t}\n\n\tif (routeConfiguration.templateId) {\n\t\tconst templateScript = document.getElementById(routeConfiguration.templateId);\n\t\tdomEntryPoint.innerHTML = templateScript.text;\n\t\tsuccessCallback();\n\t}\n};\n","import {\n\textractRouteParams,\n\tfindMatchingRouteIdentifier\n} from './core/routeParams';\nimport {renderTemplates} from './core/templates';\n\nexport const createRouter = domEntryPoint => {\n\tlet routes = {};\n\tconst lastDomEntryPoint = domEntryPoint.cloneNode(true);\n\tlet lastRouteHandler = null;\n\n\tconst navigateTo = hashUrl => {\n\t\twindow.location.hash = hashUrl;\n\t};\n\n\tconst otherwise = routeHandler => {\n\t\troutes['*'] = routeHandler;\n\t};\n\n\tconst addRoute = (hashUrl, routeHandler) => {\n\t\troutes[hashUrl] = routeHandler;\n\t\treturn {addRoute, otherwise, navigateTo};\n\t};\n\n\tconst initializeDomElement = () => {\n\t\tif (!domEntryPoint.parentElement) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domClone = lastDomEntryPoint.cloneNode(true);\n\t\tdomEntryPoint.parentElement.insertBefore(domClone, domEntryPoint);\n\n\t\tif (typeof domEntryPoint.remove === 'undefined') {\n\t\t\tdomEntryPoint.removeNode(true);\n\t\t} else {\n\t\t\tdomEntryPoint.remove();\n\t\t}\n\n\t\tdomEntryPoint = domClone;\n\t};\n\n\tconst disposeLastRoute = () => {\n\t\tif (!lastRouteHandler) return;\n\t\tif (typeof lastRouteHandler.dispose === 'undefined') return;\n\t\tlastRouteHandler.dispose(domEntryPoint);\n\t};\n\n\tconst handleRouting = () => {\n\t\tconst defaultRouteIdentifier = '*';\n\t\tconst currentHash = location.hash.slice(1);\n\n\t\tconst maybeMatchingRouteIdentifier = findMatchingRouteIdentifier(currentHash, Object.keys(routes));\n\t\tlet routeParams = {};\n\t\tif (maybeMatchingRouteIdentifier) {\n\t\t\trouteParams = extractRouteParams(maybeMatchingRouteIdentifier, currentHash);\n\t\t}\n\n\t\tconst routeHandler = Object.keys(routes).indexOf(maybeMatchingRouteIdentifier) > -1 ? routes[maybeMatchingRouteIdentifier] : routes[defaultRouteIdentifier];\n\n\t\tif (!routeHandler) {\n\t\t\treturn;\n\t\t}\n\n\t\tdisposeLastRoute(routeHandler);\n\n\t\t// Memory last routeHandler\n\t\tlastRouteHandler = routeHandler;\n\n\t\tinitializeDomElement();\n\n\t\tif (typeof routeHandler === 'function') {\n\t\t\trouteHandler(domEntryPoint, routeParams);\n\t\t} else {\n\n\t\t\trenderTemplates(routeHandler, domEntryPoint, () => {\n\t\t\t\tif (typeof routeHandler.routeHandler === 'function') {\n\t\t\t\t\trouteHandler.routeHandler(domEntryPoint, routeParams);\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\t};\n\n\tif (window) {\n\t\twindow.removeEventListener('hashchange', handleRouting);\n\t\twindow.addEventListener('hashchange', handleRouting);\n\t\twindow.removeEventListener('load', handleRouting);\n\t\twindow.addEventListener('load', handleRouting);\n\t}\n\n\treturn {addRoute, otherwise, navigateTo};\n};\n"],"names":["parseRouteParamToCorrectType","isNaN","paramValue","parseInt","JSON","parse","extractRouteParams","routeIdentifier","currentHash","splittedHash","split","splittedRouteIdentifier","map","routeIdentifierToken","index","indexOf","routeParam","key","substr","length","filter","p","reduce","acc","curr","keys","forEach","findMatchingRouteIdentifier","routeKeys","firstHashToken","splittedRouteKey","routeKey","staticRouteTokensAreEqual","routeToken","i","countInvalid","currentValidationState","loadTemplate","templateUrl","successCallback","xhr","XMLHttpRequest","onreadystatechange","readyState","responseText","open","send","renderTemplates","routeConfiguration","domEntryPoint","templateString","innerHTML","templateId","templateScript","document","getElementById","text","createRouter","routes","lastDomEntryPoint","cloneNode","lastRouteHandler","navigateTo","location","hash","hashUrl","otherwise","routeHandler","addRoute","initializeDomElement","parentElement","domClone","insertBefore","remove","removeNode","disposeLastRoute","dispose","handleRouting","defaultRouteIdentifier","slice","maybeMatchingRouteIdentifier","Object","routeParams","window","removeEventListener","addEventListener"],"mappings":"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"} \ No newline at end of file diff --git a/dist/vanilla-ui-router.min.js b/dist/vanilla-ui-router.min.js index 68ffa75..333df1d 100644 --- a/dist/vanilla-ui-router.min.js +++ b/dist/vanilla-ui-router.min.js @@ -1 +1 @@ -!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.vanillaUIRouter=e.vanillaUIRouter||{})}(this,function(e){"use strict";var n=function(e){return isNaN(e)?"true"===e||"false"===e?JSON.parse(e):e:parseInt(e,10)},t=function(e,t){var r=t.split("/"),o=e.split("/");return o.map(function(e,n){if(e.indexOf(":",0)===-1)return null;var t={},o=e.substr(1,e.length-1);return t[o]=r[n],t}).filter(function(e){return null!==e}).reduce(function(e,t){return Object.keys(t).forEach(function(r){e[r]=n(t[r])}),e},{})},r=function(e,n){var t=e.split("/"),r=t[0];return n.filter(function(e){var n=e.split("/"),o=0===n.map(function(e,n){return e.indexOf(":",0)!==-1||e===t[n]}).reduce(function(e,n){return n===!1&&++e,e},0);return e.indexOf(r,0)!==-1&&o&&t.length===n.length})[0]},o=function(e,n){var t=new XMLHttpRequest;t.onreadystatechange=function(){4===t.readyState&&n(t.responseText)},t.open("GET",e),t.send()},i=function(e,n,t){if(e&&(e.templateString&&(n.innerHTML=e.templateString,t()),e.templateUrl&&o(e.templateUrl,function(e){n.innerHTML=e,t()}),e.templateId)){var r=document.getElementById(e.templateId);n.innerHTML=r.text,t()}},u=function(e){var n={},o=e.cloneNode(!0),u=null,a=function(e){window.location.hash=e},f=function(e){n["*"]=e},c=function e(t,r){return n[t]=r,{addRoute:e,otherwise:f,navigateTo:a}},d=function(){if(e.parentElement){var n=o.cloneNode(!0);e.parentElement.insertBefore(n,e),e.remove(),e=n}},l=function(){u&&"undefined"!=typeof u.dispose&&u.dispose(e)},s=function(){var o="*",a=location.hash.slice(1),f=r(a,Object.keys(n)),c={};f&&(c=t(f,a));var s=Object.keys(n).indexOf(f)>-1?n[f]:n[o];s&&(l(s),u=s,d(),"function"==typeof s?s(e,c):i(s,e,function(){"function"==typeof s.routeHandler&&s.routeHandler(e,c)}))};return window&&(window.removeEventListener("hashchange",s),window.addEventListener("hashchange",s),window.removeEventListener("load",s),window.addEventListener("load",s)),{addRoute:c,otherwise:f,navigateTo:a}};e.createRouter=u,Object.defineProperty(e,"__esModule",{value:!0})}); +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.vanillaUIRouter=e.vanillaUIRouter||{})}(this,function(e){"use strict";var n=function(e){return isNaN(e)?"true"===e||"false"===e?JSON.parse(e):e:parseInt(e,10)},t=function(e,t){var r=t.split("/"),o=e.split("/");return o.map(function(e,n){if(e.indexOf(":",0)===-1)return null;var t={},o=e.substr(1,e.length-1);return t[o]=r[n],t}).filter(function(e){return null!==e}).reduce(function(e,t){return Object.keys(t).forEach(function(r){e[r]=n(t[r])}),e},{})},r=function(e,n){var t=e.split("/"),r=t[0];return n.filter(function(e){var n=e.split("/"),o=0===n.map(function(e,n){return e.indexOf(":",0)!==-1||e===t[n]}).reduce(function(e,n){return n===!1&&++e,e},0);return e.indexOf(r,0)!==-1&&o&&t.length===n.length})[0]},o=function(e,n){var t=new XMLHttpRequest;t.onreadystatechange=function(){4===t.readyState&&n(t.responseText)},t.open("GET",e),t.send()},i=function(e,n,t){if(e&&(e.templateString&&(n.innerHTML=e.templateString,t()),e.templateUrl&&o(e.templateUrl,function(e){n.innerHTML=e,t()}),e.templateId)){var r=document.getElementById(e.templateId);n.innerHTML=r.text,t()}},u=function(e){var n={},o=e.cloneNode(!0),u=null,a=function(e){window.location.hash=e},f=function(e){n["*"]=e},d=function e(t,r){return n[t]=r,{addRoute:e,otherwise:f,navigateTo:a}},c=function(){if(e.parentElement){var n=o.cloneNode(!0);e.parentElement.insertBefore(n,e),"undefined"==typeof e.remove?e.removeNode(!0):e.remove(),e=n}},l=function(){u&&"undefined"!=typeof u.dispose&&u.dispose(e)},s=function(){var o="*",a=location.hash.slice(1),f=r(a,Object.keys(n)),d={};f&&(d=t(f,a));var s=Object.keys(n).indexOf(f)>-1?n[f]:n[o];s&&(l(s),u=s,c(),"function"==typeof s?s(e,d):i(s,e,function(){"function"==typeof s.routeHandler&&s.routeHandler(e,d)}))};return window&&(window.removeEventListener("hashchange",s),window.addEventListener("hashchange",s),window.removeEventListener("load",s),window.addEventListener("load",s)),{addRoute:d,otherwise:f,navigateTo:a}};e.createRouter=u,Object.defineProperty(e,"__esModule",{value:!0})}); diff --git a/index.js b/index.js index f7d9a8c..77833a2 100644 --- a/index.js +++ b/index.js @@ -29,7 +29,13 @@ export const createRouter = domEntryPoint => { const domClone = lastDomEntryPoint.cloneNode(true); domEntryPoint.parentElement.insertBefore(domClone, domEntryPoint); - domEntryPoint.remove(); + + if (typeof domEntryPoint.remove === 'undefined') { + domEntryPoint.removeNode(true); + } else { + domEntryPoint.remove(); + } + domEntryPoint = domClone; };