From 7a727714c5a40f893ae3a0143b5059d4c34767f6 Mon Sep 17 00:00:00 2001 From: Matias Lopez Date: Wed, 28 Oct 2020 22:14:30 -0300 Subject: [PATCH] FIX:Render empty content and attributes elements --- README.md | 4 ++-- dist/iframex.min.js | 4 ++-- dist/iframex.min.js.map | 2 +- examples/index.html | 9 +-------- src/index.js | 29 ++++++++++++----------------- 5 files changed, 18 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 77b0b13..f95dacb 100755 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Use iFrameX is really easy, only need do two things: ```js const iframe = new iFrameX(options); -await iframe.create(); // Asynchronous +iframe.create(); ``` ## Params @@ -165,7 +165,7 @@ const content = { }; const iframe = new IframeX({content, options}); -await iframe.create(); +iframe.create(); ``` The above example code, create an iframe and when this will render, sent custom event `CustomEventName` with data, that contains an `Object` with `date: new Date()`. (Obviously data is completely customizable) diff --git a/dist/iframex.min.js b/dist/iframex.min.js index 53dc0a4..817d563 100644 --- a/dist/iframex.min.js +++ b/dist/iframex.min.js @@ -1,4 +1,4 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.iFrameX=t():e.iFrameX=t()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:this.eventName,t=arguments[1],n=new CustomEvent(e,{detail:t});this.iframe.document.dispatchEvent(n)}},{key:"addIframeEventListener",value:function(){var e=this,t=this.iframe.contentWindow;window.addEventListener(this.eventName,(function(n){return n.source===t&&e.gateway(n.detail)}))}},{key:"render",value:function(){var e=this;if(this.iframe)throw new Error("An iframe already exists, please instance a new iFrameX. Read docs here: https://github.com/videsk/iframex");var t=document.createElement("iframe");if(this.attr["data-iframe-id"]=this.id,Object.keys(this.attr).forEach((function(n){return t.setAttribute(n,e.attr[n])})),!this.container)throw new Error("The container selector is not valid.");this.container.appendChild(t),this.iframe=t}},{key:"addElements",value:function(e){Array.isArray(e)?this._addByObject(e):"object"===(void 0===e?"undefined":r(e))&&this._addByArray(e)}},{key:"_createAndBind",value:function(e){var t=e.type,n=e.content,r=void 0===n?"":n,o=e.attr,i=void 0===o?{}:o,a=document.createElement(t);return["style","script"].includes(t)?a.appendChild(document.createTextNode(r)):a.innerText=r,Object.keys(i).length>0&&Object.keys(i).forEach((function(e){return a.setAttribute(e,i[e])})),a}},{key:"_addByArray",value:function(e){var t=this;if(!(Array.isArray(e)&&e.length>0))return console.warn("No elements found in array elements.");e.forEach((function(e){return t._addByObject(e)}))}},{key:"_addByObject",value:function(e){if(!(Object.keys(e).length>0))return console.warn("No element found in object elements.");this._delayRenderHack(e)}},{key:"_delayRenderHack",value:function(e){var t=this,n=e.append,r=void 0===n?"body":n;setTimeout((function(){return t.iframe.contentWindow.document.querySelector(r).appendChild(t._createAndBind(e))}),1)}}]),e}()}])})); +e.exports=function(){function e(t){var n=t.attributes,r=void 0===n?{}:n,i=t.container,o=void 0===i?"body":i,a=t.content,u=void 0===a?[]:a,c=t.options,d=void 0===c?{}:c;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.attr=r,this.content=u,this.container="string"==typeof o?document.querySelector(o):o,this.id=d.id||Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15),this.eventName=d.eventName,this.gateway=d.gateway||function(){},this.iframe=null}return i(e,[{key:"create",value:function(){this.render(),this.addElements(this.content),this.eventName&&this.addIframeEventListener()}},{key:"sendMessage",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.eventName,t=arguments[1],n=new CustomEvent(e,{detail:t});this.iframe.contentWindow.document.dispatchEvent(n)}},{key:"addIframeEventListener",value:function(){var e=this;window.addEventListener(this.eventName,(function(t){return e.gateway(t.detail)}))}},{key:"render",value:function(){if(this.iframe)throw new Error("An iframe already exists, please instance a new iFrameX. Read docs here: https://github.com/videsk/iframex");this.attr["data-iframe-id"]=this.id;var e=this._createAndBind({type:"iframe",attr:this.attr});if(!this.container)throw new Error("The container selector is not valid.");this.container.appendChild(e),this.iframe=e}},{key:"addElements",value:function(e){Array.isArray(e)?this._addByArray(e):"object"===(void 0===e?"undefined":r(e))&&this._addByObject(e)}},{key:"_createAndBind",value:function(e){var t=e.type,n=e.content,r=void 0===n?"":n,i=e.attr,o=void 0===i?{}:i,a=document.createElement(t);return["style","script"].includes(t)?a.appendChild(document.createTextNode(r)):a.innerHTML=r,Object.keys(o).length>0&&Object.keys(o).forEach((function(e){return a.setAttribute(e,o[e])})),a}},{key:"_addByArray",value:function(e){var t=this;if(!(Array.isArray(e)&&e.length>0))return console.warn("No elements found in array elements.");e.forEach((function(e){return t._addByObject(e)}))}},{key:"_addByObject",value:function(e){if(!("type"in e))return console.warn("Tag element is mandatory.");this._delayRenderHack(e)}},{key:"_delayRenderHack",value:function(e){var t=this,n=e.append,r=void 0===n?"body":n;setTimeout((function(){return t.iframe.contentWindow.document.querySelector(r).appendChild(t._createAndBind(e))}),1)}}]),e}()}])})); //# sourceMappingURL=iframex.min.js.map \ No newline at end of file diff --git a/dist/iframex.min.js.map b/dist/iframex.min.js.map index 9a8a250..0674f75 100644 --- a/dist/iframex.min.js.map +++ b/dist/iframex.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack://iFrameX/webpack/universalModuleDefinition","webpack://iFrameX/webpack/bootstrap","webpack://iFrameX/./src/index.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","attributes","container","content","options","this","attr","document","querySelector","id","Math","random","toString","substring","eventName","gateway","iframe","Promise","resolve","render","addElements","addIframeEventListener","addEventListener","data","event","CustomEvent","detail","dispatchEvent","contentWindow","message","source","Error","createElement","keys","forEach","setAttribute","appendChild","elements","Array","isArray","_addByObject","_addByArray","objectElement","type","element","includes","createTextNode","innerText","length","attribute","console","warn","_delayRenderHack","append","setTimeout","_createAndBind"],"mappings":"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","file":"iframex.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"iFrameX\"] = factory();\n\telse\n\t\troot[\"iFrameX\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/**\n * @name iFrameX\n * @author Videsk™\n * @license LGPL-2.1\n *\n * Javascript Iframe generator with dynamic content injection like HTML,\n * CSS, scripts, etc. and iframe custom event listener.\n *\n*/\n\nmodule.exports = class iFrameX {\n /**\n * Create iframe with custom attributes and dynamic content with object schema\n * @class iFrameX\n * @param attributes={} {Object} - List of iframe attributes\n * @param container=\"body\" {String|Object} - Container where iframe will append\n * @param content=[] {Array|Object} - List of elements want append into iframe\n * @param options={} {Object} - Options of iframe\n * @param options.id {String} - Set custom id\n * @param options.eventName {String} - Event name want listen from iframe\n * @param options.gateway {Function} - Function want handle every event comes from iframe\n */\n constructor ({\n attributes = {},\n container = 'body',\n content = [],\n options = {}\n }) {\n this.attr = attributes;\n this.content = content;\n this.container = (typeof container === 'string') ? document.querySelector(container) : container;\n this.id = options.id || Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);\n this.eventName = options.eventName;\n this.gateway = options.gateway || function(){};\n this.iframe = null;\n };\n\n /**\n * Function to create iframe based on constructor params\n * @public\n */\n create() {\n return new Promise(resolve => {\n this.render();\n this.addElements(this.content);\n if (this.eventName) this.addIframeEventListener();\n this.iframe.addEventListener('load', resolve);\n });\n };\n\n /**\n * Send data from parent to iframe\n * @param name {String} - Event name\n * @param data {*} - Anything you want\n * @public\n */\n sendMessage(name = this.eventName, data) {\n const event = new CustomEvent(name, {detail: data});\n this.iframe.document.dispatchEvent(event);\n }\n\n /**\n * Add iframe event listener\n * @public\n */\n addIframeEventListener() {\n const {contentWindow} = this.iframe;\n window.addEventListener(this.eventName, message => (message.source === contentWindow) && this.gateway(message.detail));\n }\n\n /**\n * Create iframe with attributes and append custom elements\n * @public\n */\n render() {\n if (this.iframe) throw new Error('An iframe already exists, please instance a new iFrameX. Read docs here: https://github.com/videsk/iframex');\n const iframe = document.createElement('iframe');\n this.attr['data-iframe-id'] = this.id;\n Object.keys(this.attr).forEach(key => iframe.setAttribute(key, this.attr[key]));\n if (this.container) this.container.appendChild(iframe);\n else throw new Error('The container selector is not valid.');\n this.iframe = iframe;\n }\n\n /**\n * Add elements\n * @param elements {Object} - List of elements\n * @public\n */\n addElements(elements) {\n if (Array.isArray(elements)) this._addByObject(elements);\n else if (typeof elements === 'object') this._addByArray(elements);\n }\n\n /**\n * Create and bind element\n * @param objectElement {Object} - Schema of element\n * @param objectElement.type {String} - HTML tag\n * @param objectElement.append {String} - DOM querySelector in string\n * @param objectElement.content {String} - Content of element in HTML or plain text\n * @param objectElement.attr {Object} - List of attributes of element in key-value format\n * @returns {Object}\n * @private\n */\n _createAndBind(objectElement) {\n const {type, content = '', attr = {}} = objectElement;\n const element = document.createElement(type);\n if (['style', 'script'].includes(type)) element.appendChild(document.createTextNode(content));\n else element.innerText = content;\n if (Object.keys(attr).length > 0) Object.keys(attr).forEach(attribute => element.setAttribute(attribute, attr[attribute]));\n return element;\n }\n\n /**\n * Add elements by array of objects\n * @param elements {[Object]} - Array with elements in object format\n * @private\n */\n _addByArray(elements) {\n const isValidArray = Array.isArray(elements) && elements.length > 0;\n if (!isValidArray) return console.warn('No elements found in array elements.');\n elements.forEach(element => this._addByObject(element));\n }\n\n /**\n * Add only one element by object structure\n * @param element\n * @private\n */\n _addByObject(element) {\n const isValidObject = Object.keys(element).length > 0;\n if (!isValidObject) return console.warn('No element found in object elements.');\n this._delayRenderHack(element);\n }\n\n /**\n * This avoid errors with render on Firefox (Gecko engine)\n * @param element {Object} - Element want render\n * @private\n */\n _delayRenderHack(element) {\n const {append = 'body'} = element;\n setTimeout(() => this.iframe.contentWindow.document.querySelector(append).appendChild(this._createAndBind(element)), 1);\n }\n};\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack://iFrameX/webpack/universalModuleDefinition","webpack://iFrameX/webpack/bootstrap","webpack://iFrameX/./src/index.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","attributes","container","content","options","this","attr","document","querySelector","id","Math","random","toString","substring","eventName","gateway","iframe","render","addElements","addIframeEventListener","data","event","CustomEvent","detail","contentWindow","dispatchEvent","addEventListener","message","Error","_createAndBind","type","appendChild","elements","Array","isArray","_addByArray","_addByObject","objectElement","element","createElement","includes","createTextNode","innerHTML","keys","length","forEach","attribute","setAttribute","console","warn","_delayRenderHack","append","setTimeout"],"mappings":"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","file":"iframex.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"iFrameX\"] = factory();\n\telse\n\t\troot[\"iFrameX\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/**\n * @name iFrameX\n * @author Videsk™\n * @license LGPL-2.1\n *\n * Javascript Iframe generator with dynamic content injection like HTML,\n * CSS, scripts, etc. and iframe custom event listener.\n *\n*/\n\nmodule.exports = class iFrameX {\n /**\n * Create iframe with custom attributes and dynamic content with object schema\n * @class iFrameX\n * @param attributes={} {Object} - List of iframe attributes\n * @param container=\"body\" {String|Object} - Container where iframe will append\n * @param content=[] {Array|Object} - List of elements want append into iframe\n * @param options={} {Object} - Options of iframe\n * @param options.id {String} - Set custom id\n * @param options.eventName {String} - Event name want listen from iframe\n * @param options.gateway {Function} - Function want handle every event comes from iframe\n */\n constructor ({\n attributes = {},\n container = 'body',\n content = [],\n options = {}\n }) {\n this.attr = attributes;\n this.content = content;\n this.container = (typeof container === 'string') ? document.querySelector(container) : container;\n this.id = options.id || Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);\n this.eventName = options.eventName;\n this.gateway = options.gateway || function(){};\n this.iframe = null;\n };\n\n /**\n * Function to create iframe based on constructor params\n * @public\n */\n create() {\n this.render();\n this.addElements(this.content);\n if (this.eventName) this.addIframeEventListener();\n };\n\n /**\n * Send data from parent to iframe\n * @param name {String} - Event name\n * @param data {*} - Anything you want\n * @public\n */\n sendMessage(name = this.eventName, data) {\n const event = new CustomEvent(name, {detail: data});\n this.iframe.contentWindow.document.dispatchEvent(event);\n }\n\n /**\n * Add iframe event listener\n * @public\n */\n addIframeEventListener() {\n window.addEventListener(this.eventName, message => this.gateway(message.detail));\n }\n\n /**\n * Create iframe with attributes and append custom elements\n * @public\n */\n render() {\n if (this.iframe) throw new Error('An iframe already exists, please instance a new iFrameX. Read docs here: https://github.com/videsk/iframex');\n this.attr['data-iframe-id'] = this.id;\n const iframe = this._createAndBind({type: 'iframe', attr: this.attr});\n if (this.container) this.container.appendChild(iframe);\n else throw new Error('The container selector is not valid.');\n this.iframe = iframe;\n }\n\n /**\n * Add elements\n * @param elements {Object|Array} - List of elements\n * @public\n */\n addElements(elements) {\n if (Array.isArray(elements)) this._addByArray(elements);\n else if (typeof elements === 'object') this._addByObject(elements);\n }\n\n /**\n * Create and bind element\n * @param objectElement {Object} - Schema of element\n * @param objectElement.type {String} - HTML tag\n * @param objectElement.append {String} - DOM querySelector in string\n * @param objectElement.content {String} - Content of element in HTML or plain text\n * @param objectElement.attr {Object} - List of attributes of element in key-value format\n * @returns {Object}\n * @private\n */\n _createAndBind(objectElement) {\n const {type, content = '', attr = {}} = objectElement;\n const element = document.createElement(type);\n if (['style', 'script'].includes(type)) element.appendChild(document.createTextNode(content));\n else element.innerHTML = content;\n if (Object.keys(attr).length > 0) Object.keys(attr).forEach(attribute => element.setAttribute(attribute, attr[attribute]));\n return element;\n }\n\n /**\n * Add elements by array of objects\n * @param elements {[Object]} - Array with elements in object format\n * @private\n */\n _addByArray(elements) {\n const isValidArray = Array.isArray(elements) && elements.length > 0;\n if (!isValidArray) return console.warn('No elements found in array elements.');\n elements.forEach(element => this._addByObject(element));\n }\n\n /**\n * Add only one element by object structure\n * @param element\n * @private\n */\n _addByObject(element) {\n const isValidObject = 'type' in element;\n if (!isValidObject) return console.warn('Tag element is mandatory.');\n this._delayRenderHack(element);\n }\n\n /**\n * This avoid errors with render on Firefox (Gecko engine)\n * @param element {Object} - Element want render\n * @private\n */\n _delayRenderHack(element) {\n const {append = 'body'} = element;\n setTimeout(() => this.iframe.contentWindow.document.querySelector(append).appendChild(this._createAndBind(element)), 1);\n }\n};\n"],"sourceRoot":""} \ No newline at end of file diff --git a/examples/index.html b/examples/index.html index db68a16..eb1ebf0 100755 --- a/examples/index.html +++ b/examples/index.html @@ -31,13 +31,6 @@ rel: 'stylesheet', }, }, - { - type: 'script', - append: 'head', - attr: { - src: 'https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js', - }, - }, { type: 'div', content: 'A simple primary alert—check it out!', @@ -86,7 +79,7 @@ async function createIframe(){ iframe = new iFrameX(options); - await iframe.create(); + iframe.create(); iframe.sendMessage('CustomEventName', {date: new Date(), message: "Sent from parent to iframe"}); // Parent sender } diff --git a/src/index.js b/src/index.js index 5208f52..ed09b9a 100755 --- a/src/index.js +++ b/src/index.js @@ -40,12 +40,9 @@ module.exports = class iFrameX { * @public */ create() { - return new Promise(resolve => { - this.render(); - this.addElements(this.content); - if (this.eventName) this.addIframeEventListener(); - this.iframe.addEventListener('load', resolve); - }); + this.render(); + this.addElements(this.content); + if (this.eventName) this.addIframeEventListener(); }; /** @@ -56,7 +53,7 @@ module.exports = class iFrameX { */ sendMessage(name = this.eventName, data) { const event = new CustomEvent(name, {detail: data}); - this.iframe.document.dispatchEvent(event); + this.iframe.contentWindow.document.dispatchEvent(event); } /** @@ -64,8 +61,7 @@ module.exports = class iFrameX { * @public */ addIframeEventListener() { - const {contentWindow} = this.iframe; - window.addEventListener(this.eventName, message => (message.source === contentWindow) && this.gateway(message.detail)); + window.addEventListener(this.eventName, message => this.gateway(message.detail)); } /** @@ -74,9 +70,8 @@ module.exports = class iFrameX { */ render() { if (this.iframe) throw new Error('An iframe already exists, please instance a new iFrameX. Read docs here: https://github.com/videsk/iframex'); - const iframe = document.createElement('iframe'); this.attr['data-iframe-id'] = this.id; - Object.keys(this.attr).forEach(key => iframe.setAttribute(key, this.attr[key])); + const iframe = this._createAndBind({type: 'iframe', attr: this.attr}); if (this.container) this.container.appendChild(iframe); else throw new Error('The container selector is not valid.'); this.iframe = iframe; @@ -84,12 +79,12 @@ module.exports = class iFrameX { /** * Add elements - * @param elements {Object} - List of elements + * @param elements {Object|Array} - List of elements * @public */ addElements(elements) { - if (Array.isArray(elements)) this._addByObject(elements); - else if (typeof elements === 'object') this._addByArray(elements); + if (Array.isArray(elements)) this._addByArray(elements); + else if (typeof elements === 'object') this._addByObject(elements); } /** @@ -106,7 +101,7 @@ module.exports = class iFrameX { const {type, content = '', attr = {}} = objectElement; const element = document.createElement(type); if (['style', 'script'].includes(type)) element.appendChild(document.createTextNode(content)); - else element.innerText = content; + else element.innerHTML = content; if (Object.keys(attr).length > 0) Object.keys(attr).forEach(attribute => element.setAttribute(attribute, attr[attribute])); return element; } @@ -128,8 +123,8 @@ module.exports = class iFrameX { * @private */ _addByObject(element) { - const isValidObject = Object.keys(element).length > 0; - if (!isValidObject) return console.warn('No element found in object elements.'); + const isValidObject = 'type' in element; + if (!isValidObject) return console.warn('Tag element is mandatory.'); this._delayRenderHack(element); }