From 985453bd506b573ddf677c18c1e34b1ffa750e99 Mon Sep 17 00:00:00 2001
From: s-yadav <sudhanshuyadav2@gmail.com>
Date: Fri, 9 Nov 2018 16:46:50 +0530
Subject: [PATCH] - Fixed memory leak. Temporary node not getting unmounted.
 Merged #24 - Move lifecycle methods on top - Handle null nodes inside MetaTag

---
 dist/react-meta-tags.es.js  | 40 ++++++++++++++++++-------------------
 dist/react-meta-tags.js     | 40 ++++++++++++++++++-------------------
 dist/react-meta-tags.min.js |  4 ++--
 lib/meta_tags.js            | 38 +++++++++++++++++------------------
 lib/meta_tags_server.js     |  6 +++++-
 package.json                |  2 +-
 src/meta_tags.js            | 28 +++++++++++++-------------
 src/meta_tags_server.js     |  4 ++++
 8 files changed, 85 insertions(+), 77 deletions(-)

diff --git a/dist/react-meta-tags.es.js b/dist/react-meta-tags.es.js
index d1b9541..b368542 100644
--- a/dist/react-meta-tags.es.js
+++ b/dist/react-meta-tags.es.js
@@ -1,5 +1,5 @@
 /**
- * react-meta-tags - 0.7.1
+ * react-meta-tags - 0.7.2
  * Author : Sudhanshu Yadav
  * Copyright (c) 2016, 2018 to Sudhanshu Yadav, released under the MIT license.
  * https://github.com/s-yadav/react-meta-tags
@@ -366,12 +366,16 @@ function (_Component) {
   }
 
   _createClass(MetaTags, [{
-    key: "extractChildren",
-    value: function extractChildren() {
-      var extract = this.context.extract;
-
-      if (extract) {
-        extract(this.props.children);
+    key: "componentDidMount",
+    value: function componentDidMount() {
+      this.temporaryElement = document.createElement('div');
+      this.handleChildrens();
+    }
+  }, {
+    key: "componentDidUpdate",
+    value: function componentDidUpdate(oldProps) {
+      if (oldProps.children !== this.props.children) {
+        this.handleChildrens();
       }
     }
   }, {
@@ -381,6 +385,15 @@ function (_Component) {
         ReactDOM.unmountComponentAtNode(this.temporaryElement);
       }
     }
+  }, {
+    key: "extractChildren",
+    value: function extractChildren() {
+      var extract = this.context.extract;
+
+      if (extract) {
+        extract(this.props.children);
+      }
+    }
   }, {
     key: "handleChildrens",
     value: function handleChildrens() {
@@ -428,19 +441,6 @@ function (_Component) {
         appendChild(document.head, childNodes);
       });
     }
-  }, {
-    key: "componentDidMount",
-    value: function componentDidMount() {
-      this.temporaryElement = document.createElement('div');
-      this.handleChildrens();
-    }
-  }, {
-    key: "componentDidUpdate",
-    value: function componentDidUpdate(oldProps) {
-      if (oldProps.children !== this.props.children) {
-        this.handleChildrens();
-      }
-    }
   }, {
     key: "render",
     value: function render() {
diff --git a/dist/react-meta-tags.js b/dist/react-meta-tags.js
index 236ca26..0df3768 100644
--- a/dist/react-meta-tags.js
+++ b/dist/react-meta-tags.js
@@ -1,5 +1,5 @@
 /**
- * react-meta-tags - 0.7.1
+ * react-meta-tags - 0.7.2
  * Author : Sudhanshu Yadav
  * Copyright (c) 2016, 2018 to Sudhanshu Yadav, released under the MIT license.
  * https://github.com/s-yadav/react-meta-tags
@@ -372,12 +372,16 @@
     }
 
     _createClass(MetaTags, [{
-      key: "extractChildren",
-      value: function extractChildren() {
-        var extract = this.context.extract;
-
-        if (extract) {
-          extract(this.props.children);
+      key: "componentDidMount",
+      value: function componentDidMount() {
+        this.temporaryElement = document.createElement('div');
+        this.handleChildrens();
+      }
+    }, {
+      key: "componentDidUpdate",
+      value: function componentDidUpdate(oldProps) {
+        if (oldProps.children !== this.props.children) {
+          this.handleChildrens();
         }
       }
     }, {
@@ -387,6 +391,15 @@
           ReactDOM.unmountComponentAtNode(this.temporaryElement);
         }
       }
+    }, {
+      key: "extractChildren",
+      value: function extractChildren() {
+        var extract = this.context.extract;
+
+        if (extract) {
+          extract(this.props.children);
+        }
+      }
     }, {
       key: "handleChildrens",
       value: function handleChildrens() {
@@ -434,19 +447,6 @@
           appendChild(document.head, childNodes);
         });
       }
-    }, {
-      key: "componentDidMount",
-      value: function componentDidMount() {
-        this.temporaryElement = document.createElement('div');
-        this.handleChildrens();
-      }
-    }, {
-      key: "componentDidUpdate",
-      value: function componentDidUpdate(oldProps) {
-        if (oldProps.children !== this.props.children) {
-          this.handleChildrens();
-        }
-      }
     }, {
       key: "render",
       value: function render() {
diff --git a/dist/react-meta-tags.min.js b/dist/react-meta-tags.min.js
index 73c9b01..0788767 100644
--- a/dist/react-meta-tags.min.js
+++ b/dist/react-meta-tags.min.js
@@ -1,8 +1,8 @@
 /**
- * react-meta-tags - 0.7.1
+ * react-meta-tags - 0.7.2
  * Author : Sudhanshu Yadav
  * Copyright (c) 2016, 2018 to Sudhanshu Yadav, released under the MIT license.
  * https://github.com/s-yadav/react-meta-tags
  */
 
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("react-dom")):"function"==typeof define&&define.amd?define(["exports","react","react-dom"],t):t(e.MetaTags={},e.React,e.ReactDOM)}(this,function(e,n,r){"use strict";var o="default"in n?n.default:n;function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function c(e,t,n){return t&&a(e.prototype,t),n&&a(e,n),e}function t(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&p(e,t)}function l(e){return(l=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function p(e,t){return(p=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function f(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}r=r&&r.hasOwnProperty("default")?r.default:r;var s=Object.getOwnPropertySymbols,d=Object.prototype.hasOwnProperty,h=Object.prototype.propertyIsEnumerable;(function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}})()&&Object.assign;function y(){}var m,v=(function(e){e.exports=function(){function e(e,t,n,r,o,i){if("SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"!==i){var a=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw a.name="Invariant Violation",a}}function t(){return e}var n={array:e.isRequired=e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return n.checkPropTypes=y,n.PropTypes=n}()}(m={exports:{}},m.exports),m.exports),b=function(e){function t(){return i(this,t),f(this,l(t).apply(this,arguments))}return u(t,n.Component),c(t,[{key:"getChildContext",value:function(){return{extract:this.props.extract}}},{key:"render",value:function(){return n.Children.only(this.props.children)}}]),t}();t(b,"childContextTypes",{extract:v.func});var O=["property","name","itemprop"];function g(o){var i=document.head,e=o.id;return e?e&&i.querySelector("#".concat(e)):O.reduce(function(e,t){var n,r=o.getAttribute(t);return r?e.concat((n=i.querySelectorAll("[".concat(t,' = "').concat(r,'"]')),(n=Array.prototype.slice.call(n||[])).filter(function(e){return!e.id}))):e},[])}function C(e,t){void 0===t.length&&(t=[t]);for(var n=0,r=t.length;n<r;n++)e.removeChild(t[n])}var j=function(e){function t(){return i(this,t),f(this,l(t).apply(this,arguments))}return u(t,n.Component),c(t,[{key:"extractChildren",value:function(){var e=this.context.extract;e&&e(this.props.children)}},{key:"componentWillUnmount",value:function(){this.temporaryElement&&r.unmountComponentAtNode(this.temporaryElement)}},{key:"handleChildrens",value:function(){var n=this,e=this.props.children;if(!this.context.extract){var t=o.createElement("div",{className:"react-head-temp"},e);r.render(t,this.temporaryElement,function(){var e=n.temporaryElement.innerHTML;if(n.lastChildStr!==e){n.lastChildStr=e;var t=Array.prototype.slice.call(n.temporaryElement.querySelector(".react-head-temp").children),i=document.head,r=i.innerHTML;(t=t.filter(function(e){return-1===r.indexOf((t=e,(n=document.createElement("div")).appendChild(t),n.innerHTML));var t,n})).forEach(function(e){var t=e.tagName.toLowerCase();if("title"===t){var n=document.head.querySelectorAll("title");n&&C(i,n)}else if("meta"===t){var r=g(e);r&&C(i,r)}else if("link"===t&&"canonical"===e.rel){var o=document.head.querySelectorAll('link[rel="canonical"]');o&&C(i,o)}}),function(e,t){void 0===t.length&&(t=[t]);for(var n=document.createDocumentFragment(),r=0,o=t.length;r<o;r++)n.appendChild(t[r]);e.appendChild(n)}(document.head,t)}})}}},{key:"componentDidMount",value:function(){this.temporaryElement=document.createElement("div"),this.handleChildrens()}},{key:"componentDidUpdate",value:function(e){e.children!==this.props.children&&this.handleChildrens()}},{key:"render",value:function(){return this.extractChildren(),null}}]),t}();t(j,"contextTypes",{extract:v.func});var x=function(e){function t(){return i(this,t),f(this,l(t).apply(this,arguments))}return u(t,n.Component),c(t,[{key:"render",value:function(){return o.createElement(j,null,o.createElement("title",null,this.props.title))}}]),t}();t(x,"propTypes",{title:v.string}),e.default=j,e.MetaTags=j,e.MetaTagsContext=b,e.ReactTitle=x,Object.defineProperty(e,"__esModule",{value:!0})});
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("react-dom")):"function"==typeof define&&define.amd?define(["exports","react","react-dom"],t):t(e.MetaTags={},e.React,e.ReactDOM)}(this,function(e,n,r){"use strict";var o="default"in n?n.default:n;function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function c(e,t,n){return t&&a(e.prototype,t),n&&a(e,n),e}function t(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function u(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&p(e,t)}function l(e){return(l=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function p(e,t){return(p=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function f(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}r=r&&r.hasOwnProperty("default")?r.default:r;var s=Object.getOwnPropertySymbols,d=Object.prototype.hasOwnProperty,h=Object.prototype.propertyIsEnumerable;(function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}})()&&Object.assign;function y(){}var m,v=(function(e){e.exports=function(){function e(e,t,n,r,o,i){if("SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"!==i){var a=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw a.name="Invariant Violation",a}}function t(){return e}var n={array:e.isRequired=e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return n.checkPropTypes=y,n.PropTypes=n}()}(m={exports:{}},m.exports),m.exports),b=function(e){function t(){return i(this,t),f(this,l(t).apply(this,arguments))}return u(t,n.Component),c(t,[{key:"getChildContext",value:function(){return{extract:this.props.extract}}},{key:"render",value:function(){return n.Children.only(this.props.children)}}]),t}();t(b,"childContextTypes",{extract:v.func});var O=["property","name","itemprop"];function g(o){var i=document.head,e=o.id;return e?e&&i.querySelector("#".concat(e)):O.reduce(function(e,t){var n,r=o.getAttribute(t);return r?e.concat((n=i.querySelectorAll("[".concat(t,' = "').concat(r,'"]')),(n=Array.prototype.slice.call(n||[])).filter(function(e){return!e.id}))):e},[])}function C(e,t){void 0===t.length&&(t=[t]);for(var n=0,r=t.length;n<r;n++)e.removeChild(t[n])}var j=function(e){function t(){return i(this,t),f(this,l(t).apply(this,arguments))}return u(t,n.Component),c(t,[{key:"componentDidMount",value:function(){this.temporaryElement=document.createElement("div"),this.handleChildrens()}},{key:"componentDidUpdate",value:function(e){e.children!==this.props.children&&this.handleChildrens()}},{key:"componentWillUnmount",value:function(){this.temporaryElement&&r.unmountComponentAtNode(this.temporaryElement)}},{key:"extractChildren",value:function(){var e=this.context.extract;e&&e(this.props.children)}},{key:"handleChildrens",value:function(){var n=this,e=this.props.children;if(!this.context.extract){var t=o.createElement("div",{className:"react-head-temp"},e);r.render(t,this.temporaryElement,function(){var e=n.temporaryElement.innerHTML;if(n.lastChildStr!==e){n.lastChildStr=e;var t=Array.prototype.slice.call(n.temporaryElement.querySelector(".react-head-temp").children),i=document.head,r=i.innerHTML;(t=t.filter(function(e){return-1===r.indexOf((t=e,(n=document.createElement("div")).appendChild(t),n.innerHTML));var t,n})).forEach(function(e){var t=e.tagName.toLowerCase();if("title"===t){var n=document.head.querySelectorAll("title");n&&C(i,n)}else if("meta"===t){var r=g(e);r&&C(i,r)}else if("link"===t&&"canonical"===e.rel){var o=document.head.querySelectorAll('link[rel="canonical"]');o&&C(i,o)}}),function(e,t){void 0===t.length&&(t=[t]);for(var n=document.createDocumentFragment(),r=0,o=t.length;r<o;r++)n.appendChild(t[r]);e.appendChild(n)}(document.head,t)}})}}},{key:"render",value:function(){return this.extractChildren(),null}}]),t}();t(j,"contextTypes",{extract:v.func});var x=function(e){function t(){return i(this,t),f(this,l(t).apply(this,arguments))}return u(t,n.Component),c(t,[{key:"render",value:function(){return o.createElement(j,null,o.createElement("title",null,this.props.title))}}]),t}();t(x,"propTypes",{title:v.string}),e.default=j,e.MetaTags=j,e.MetaTagsContext=b,e.ReactTitle=x,Object.defineProperty(e,"__esModule",{value:!0})});
diff --git a/lib/meta_tags.js b/lib/meta_tags.js
index c283de1..c969606 100644
--- a/lib/meta_tags.js
+++ b/lib/meta_tags.js
@@ -50,12 +50,16 @@ function (_Component) {
   }
 
   _createClass(MetaTags, [{
-    key: "extractChildren",
-    value: function extractChildren() {
-      var extract = this.context.extract;
-
-      if (extract) {
-        extract(this.props.children);
+    key: "componentDidMount",
+    value: function componentDidMount() {
+      this.temporaryElement = document.createElement('div');
+      this.handleChildrens();
+    }
+  }, {
+    key: "componentDidUpdate",
+    value: function componentDidUpdate(oldProps) {
+      if (oldProps.children !== this.props.children) {
+        this.handleChildrens();
       }
     }
   }, {
@@ -65,6 +69,15 @@ function (_Component) {
         _reactDom.default.unmountComponentAtNode(this.temporaryElement);
       }
     }
+  }, {
+    key: "extractChildren",
+    value: function extractChildren() {
+      var extract = this.context.extract;
+
+      if (extract) {
+        extract(this.props.children);
+      }
+    }
   }, {
     key: "handleChildrens",
     value: function handleChildrens() {
@@ -113,19 +126,6 @@ function (_Component) {
         (0, _utils.appendChild)(document.head, childNodes);
       });
     }
-  }, {
-    key: "componentDidMount",
-    value: function componentDidMount() {
-      this.temporaryElement = document.createElement('div');
-      this.handleChildrens();
-    }
-  }, {
-    key: "componentDidUpdate",
-    value: function componentDidUpdate(oldProps) {
-      if (oldProps.children !== this.props.children) {
-        this.handleChildrens();
-      }
-    }
   }, {
     key: "render",
     value: function render() {
diff --git a/lib/meta_tags_server.js b/lib/meta_tags_server.js
index a03b74f..c1a8c26 100644
--- a/lib/meta_tags_server.js
+++ b/lib/meta_tags_server.js
@@ -19,8 +19,12 @@ function MetaTagsServer() {
     extract: function extract(elms) {
       if (!(elms instanceof Array)) {
         elms = [elms];
-      }
+      } //filter out null nodes
 
+
+      elms = elms.filter(function (elm) {
+        return !!elm;
+      });
       headElms = headElms.concat(elms);
     },
     renderToString: function renderToString() {
diff --git a/package.json b/package.json
index 29e834d..e67ebba 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "react-meta-tags",
   "description": "Handle document meta/head tags in isomorphic react with ease.",
-  "version": "0.7.1",
+  "version": "0.7.2",
   "main": "lib/index.js",
   "author": "Sudhanshu Yadav",
   "license": "MIT",
diff --git a/src/meta_tags.js b/src/meta_tags.js
index 320f640..c217705 100644
--- a/src/meta_tags.js
+++ b/src/meta_tags.js
@@ -9,11 +9,13 @@ class MetaTags extends Component {
   static contextTypes = {
     extract: PropTypes.func
   };
-  extractChildren() {
-    const {extract} = this.context;
-
-    if (extract) {
-      extract(this.props.children);
+  componentDidMount() {
+    this.temporaryElement = document.createElement('div');
+    this.handleChildrens();
+  }
+  componentDidUpdate(oldProps) {
+    if (oldProps.children !== this.props.children) {
+      this.handleChildrens();
     }
   }
   componentWillUnmount() {
@@ -21,6 +23,13 @@ class MetaTags extends Component {
       ReactDOM.unmountComponentAtNode(this.temporaryElement);
     }
   }
+  extractChildren() {
+    const {extract} = this.context;
+
+    if (extract) {
+      extract(this.props.children);
+    }
+  }
   handleChildrens() {
     const {children} = this.props;
 
@@ -69,15 +78,6 @@ class MetaTags extends Component {
     });
 
   }
-  componentDidMount() {
-    this.temporaryElement = document.createElement('div');
-    this.handleChildrens();
-  }
-  componentDidUpdate(oldProps) {
-    if (oldProps.children !== this.props.children) {
-      this.handleChildrens();
-    }
-  }
   render() {
     this.extractChildren();
     return null;
diff --git a/src/meta_tags_server.js b/src/meta_tags_server.js
index 8e53f8d..3048139 100644
--- a/src/meta_tags_server.js
+++ b/src/meta_tags_server.js
@@ -10,6 +10,10 @@ function MetaTagsServer(){
       if (!(elms instanceof Array)) {
         elms = [elms];
       }
+      
+      //filter out null nodes
+      elms = elms.filter(elm => !!elm);
+
       headElms = headElms.concat(elms);
     },
     renderToString() {
-- 
GitLab