[unsolved] Include new js libraries to NodeBB... using iFrame Resizer to Cross domain iFrames that supports window/content resizing

Unsolved Technical Support
  • Hello Community! I'm Implementing a JavaScript Library called iFrame Resizer that keeps same and cross domain iFrames sized to their content with support for window/content resizing, and multiple iFrames.

    Resources:

    The way I'm trying to implement is by using a 'valid' html widget but without sucess

    Widget Code normally placed in the footer

    
    <iframe src="http://davidjbradshaw.com/iframe-resizer/example/frame.content.html" width="100%" scrolling="no"></iframe>
    
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/3.5.14/iframeResizer.js"></script>
    
    <script type="text/javascript">
        iFrameResize({
            log: true
        });
    </script>
    

    Footer Framed Page

    <script>
        var iFrameResizer = {
            messageCallback: function (message) {
                alert(message, parentIFrame.getId());
            }
        }
    </script>
    
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/3.5.14/iframeResizer.contentWindow.min.js" defer></script>
    
    

    NodeBB uncaugth error

    require.js:7 Uncaught Error: Mismatched anonymous define() module: function factory(){function init(options,element){function chkType(){if(!element.tagName){throw new TypeError('Object is not a valid DOM element');}else if('IFRAME'!==element.tagName.toUpperCase()){throw new TypeError('Expected <IFRAME> tag, found <'+element.tagName+'>');}}
    if(element){chkType();setupIFrame(element,options);iFrames.push(element);}}
    function warnDeprecatedOptions(options){if(options&&options.enablePublicMethods){warn('enablePublicMethods option has been removed, public methods are now always available in the iFrame');}}
    var iFrames;setupRequestAnimationFrame();setupEventListeners();return function iFrameResizeF(options,target){iFrames=[];warnDeprecatedOptions(options);switch(typeof(target)){case'undefined':case'string':Array.prototype.forEach.call(document.querySelectorAll(target||'iframe'),init.bind(undefined,options));break;case'object':init(options,target);break;default:throw new TypeError('Unexpected data type ('+typeof(target)+')');}
    return iFrames;};}
    http://requirejs.org/docs/errors.html#mismatch
        at F (require.js:7)
        at v (require.js:14)
        at Object.c [as require] (require.js:26)
        at requirejs (require.js:32)
        at i.eval (main.js:1)
        at i.onack (socket.io.js:2)
        at i.onpacket (socket.io.js:2)
        at i.eval (socket.io.js:2)
        at i.emit (socket.io.js:1)
        at i.ondecoded (socket.io.js:1)
    

    I'm a newbie in NodeJS and JavaScript WebApps so it's hard for me yet understand how to fix it yet " 'Object is not a valid DOM element' ".

    How do I embed successfully a javascript in the footer of custom-page? Thanks in advance


    Vinicius
    BRBRBR

  • I believe the issue here is that iframeResizer is meant to be loaded by require.js (or detects it, and so it interferes as it wasn't loaded in the correct order).

    What we usually do is modify the define line in the troublesome library and set a name for it.

    So define(function ()... becomes define('myModule', function ()...

  • @julian Thank you for the answer, but still undefined

    error

  • You have to do this for the last one:

    <script type="text/javascript">
      require(['iFrameResize'], function (iFrameResize) {
        iFrameResize({
            log: true
        });
      });
    </script>
    
  • Thank you very much for collaboration to solve and fix it this error Pitaj

    We are near to fix it now. I HAVE FAITH! ☝

    I've done what you suggest and it returns:
    error

    Tada... still not defined 🙇 🙇 🙇

    Way I'm implementing is using 3 widgets:

    1. Content Widget : Iframe -> https://vinipereira.github.io/iframe-help/frame.content.html
    <div style="margin:20px;">
        <iframe src="https://vinipereira.github.io/iframe-help/frame.content.html" width="100%" scrolling="no"></iframe>
    </div>
    
    2. Footer Widget : Script with define

    as @julian suggests

    define("iFrameResize", function(){
    
        /* below is the file that I copy and pasted here
        //vinipereira.github.io/iframe-help/js/iframeResizer.min.js
        {iframeResizer.min.js}
        */
    
    });
    
    3. Widget : Function call

    as @pitaj suggests

    <script type="text/javascript">
      require(['iFrameResize'], function (iFrameResize) {
        iFrameResize({
            log: true
        });
      });
    </script>
    

    Here the link of a website that works: //vinipereira.github.io/iframe-help/index.html
    This repo has the files: //github.com/vinipereira/iframe-help

    Guys just to explain, I'm doing my homework... I'm not a lazy programmer 🐼
    I have spend more than hours testing multiples hypothesis, watching youtube lessons about requireJS, it's everything new to me... The devil is in details, probably the answer is the point of my nose all this time...

    Promise when I understand it I'll do a tutorial for everybody who wants to fit a iframe well (adjust height) in NodeBB forums!

    Everyone is welcome to suggest something

    I really want my awesome nodebb forum with a iframe that fits!

    Keep the good work, you rule guys
    Thanks in advance!


    Vinicius Pereira

  • I'm thinking that you didn't remove the existing define call inside the file. At the end of the file is

    "function"==typeof define&&define.amd?define([],C)
    

    You need to change that to

    "function"==typeof define&&define.amd?define('iFrameResizer', [],C)
    

    Instead of doing the wrapper thing you said you're doing.

  • @pitaj I have removed the wrapper "thing" and changed the end of file as you suggest to

    "function"==typeof define&&define.amd?define('iFrameResizer', [],C)
    

    and now its trowing a another error 😦

    Uncaught Error: Mismatched anonymous define() module: function factory(){
    		function init(options,element){
    			function chkType(){
    				if(!element.tagName) {
    					throw new TypeError('Object is not a valid DOM element');
    				} else if ('IFRAME' !== element.tagName.toUpperCase()) {
    					throw new TypeError('Expected <IFRAME> tag, found <'+element.tagName+'>');
    				}
    			}
    
    			if(element) {
    				chkType();
    				setupIFrame(element, options);
    				iFrames.push(element);
    			}
    		}
    
    		function warnDeprecatedOptions(options) {
    			if (options && options.enablePublicMethods) {
    				warn('enablePublicMethods option has been removed, public methods are now always available in the iFrame');
    			}
    		}
    
    		var iFrames;
    
    		setupRequestAnimationFrame();
    		setupEventListeners();
    
    		return function iFrameResizeF(options,target){
    			iFrames = []; //Only return iFrames past in on this call
    
    			warnDeprecatedOptions(options);
    
    			switch (typeof(target)){
    			case 'undefined':
    			case 'string':
    				Array.prototype.forEach.call(
    					document.querySelectorAll( target || 'iframe' ),
    					init.bind(undefined, options)
    				);
    				break;
    			case 'object':
    				init(options,target);
    				break;
    			default:
    				throw new TypeError('Unexpected data type ('+typeof(target)+')');
    			}
    
    			return iFrames;
    		};
    	}
    http://requirejs.org/docs/errors.html#mismatch
        at F (nodebb.min.js:1)
        at v (nodebb.min.js:1)
        at Object.c [as require] (nodebb.min.js:1)
        at requirejs (nodebb.min.js:1)
        at <anonymous>:2:3
        at m (nodebb.min.js:1)
        at Pe (nodebb.min.js:1)
        at v.fn.init.append (nodebb.min.js:1)
        at v.fn.init.<anonymous> (nodebb.min.js:1)
        at W (nodebb.min.js:1)
    

    Can someone please try these 3 steps using widgets above? I'm really sorry to be a pain in the asx guys, kind of surprise that nobody have already try to implement this (An iFrame that fits well in nodeBB forums)

    In the meantime, thank you so much for your attention and participation guys.


    Vinicius Pereira

  • Edit Nevermind, I actually got it figured out.

    @vinipereira

    Sorry to necro this, but I was just looking into this repo when I came across this post. I have a wordpress site and I wanted to embed my NodeBB forum into it. I have it embeded, I was just looking for a way to resize the frame automatically when I found this. I have the wordpress side of things setup, I was just trying to see if there were any examples of this forum being in the iframe as opposed to a frame being within a post on the board.

    Was anything ever figured out, or were you able to make it work at all with the way you were attempting to do it, here?

  • @mosthated , Most probably your website already in production (hope it's being doing well 😊). Still, if you'll need to auto-resize the NodeBB embedded in iframe into a host website, try this plugin https://www.npmjs.com/package/nodebb-plugin-iframe-resizable (together with iframe-resizer of course). I wrote it just because I have struggled with exactly the same problem as you.


Suggested Topics


  • NodeBB on cPanel with Root

    Technical Support
    4
    0 Votes
    4 Posts
    353 Views

    If you have ssh access, there will likely be a way of getting it to work, but I don't know how cpanel will interact with everything.

  • 0 Votes
    4 Posts
    718 Views

    @evgeniy-onegin like change the colors displayed in the UI? There are many NodeBB themes you can try. If you want to customize yourself you can use custom CSS in the ACP.

  • 0 Votes
    1 Posts
    960 Views

    i give you the link of the forum https://forum.civilitas.xyz/

  • NodeBB With Apache2, Proxy

    Technical Support
    6
    0 Votes
    6 Posts
    3k Views

    @mttprvst13 It probably failed because you don't have mod_rewrite enabled.

    Do

    a2enmod rewrite systemctl restart apache2
  • 0 Votes
    24 Posts
    12k Views

    I started off this quest with just a simple problem. To have the ability for users to address my nodebb forum (http://theamericanbulletin.com:8080) as (“http://forum.theamericanbulletin.com”). This simple problem turned into a quest through countless videos and reading ( at least fifty) mindnumbing posts on blogs and other forums. I am running a Windows server ( 2008 ) with IIS to service my Wordpress main site. My NodeBB forum is listening on port 8080. All advice was to work within the framework of Windows and IIS, using 'Rewrite', to route traffic on the Server. After days of frustration, I had to come up with a better plan. One that gets me above proprietary nuances. The only way to do that was to get hold of port 80 myself..my own proxy server.. and what better webserver than Nodejs. With little of a search I came accoss this project.

    https://github.com/nodejitsu/node-http-proxy

    I git cloned the above link. Renamed the new directory to nodeproxy e:\nodeproxy> npm install ( pulls all the needed modules) created a new directory under the new 'nodeproxy' entitled MyProxy Created the MyProxy.js file ( contents below ) Moved my WordPress to listen on port 8081 in IIS Started new proxy server (e:\nodeproxy\myproxy> node myproxy.js ) Done!

    Some notes about the js file. When I first started I used this post as a guideline. It used a routing table... exactly what I was looking for. Although I was not needing to spin-up three test servers, this provided some insight into the power if this little application. I could, if I wanted to.... spin-up as many listeners as I wanted..... listening on whatever, or as many port(s) as I wanted.

    http://stackoverflow.com/questions/25896608/nodejs-routing-table-using-http-proxy

    var httpProxy = require("http-proxy"); var url = require("url"); httpProxy.createServer(function(req, res, proxy) { var hostname = req.headers.host.split(":")[0]; var pathname = url.parse(req.url).pathname; // Options for the outgoing proxy request. var options = { host: hostname }; // Routing logic if(hostname == "127.0.0.1") { options.port = 8083; } else if(pathname == "/upload") { options.port = 8082; options.path = "/"; } else { options.port = 8081; } // (add more conditional blocks here) proxy.proxyRequest(req, res, options); }).listen(8080); console.log("Proxy listening on port 8080"); // We simulate the 3 target applications var http = require("http"); http.createServer(function(req, res) { res.end("Request received on 8081"); }).listen(8081); http.createServer(function(req, res) { res.end("Request received on 8082"); }).listen(8082); http.createServer(function(req, res) { res.end("Request received on 8083"); }).listen(8083);

    I modified the above code to tailor it to my routes, but the server kept breaking. The proxy would throw a “socket hang up” when I moved between the Wordpress site and the NodeBB site. The error was not getting caught and the proxy would just break and go back to a system prompt. Another day of research lead me to this post.

    http://www.clock.co.uk/blog/preventing-http-raise-hangup-error-on-destroyed-socket-write-from-crashing-your-nodejs-server

    It was in this post where the idea of wrapping the proxy-server within a domain arose. Perfect! I can pass the error up to the domain and let it dispose of it while the proxy keeps serving ( at least that's how I think it works). Plus the added benefit of having and overlord (parent) to all the potential listeners that could be spun-up to report to. But that is a whole different subject.

    So I added a Domain to the mix and came-up with a working solution. While this only apples to those with 'full' control over their servers, it does add a layer of control over proprietary systems running on your machine, and frees the developer (to a point) from those systems. I do not have to mess with rewrite... or some Apache routine tables. This is 'clean' and simple.

    Please feel free to improve on this concept and tighten this up. There is room for lots of improvement here. Please add to the knowledge.

    Rich

    MyProxy.Js

    var util = require('util'),
    http = require('http'),
    url = require('url'),
    domain = require('domain')
    httpProxy = require('../lib/http-proxy'),
    proxy = httpProxy.createProxyServer({});
    serverDomain = domain.create();
    proxy.on('error', function(err, req, res)
    {
    console.log(err.message);
    });
    serverDomain.run(function () {http.createServer(function(req, res)
    {
    var reqd = domain.create()
    reqd.add(req)
    reqd.add(res)
    // On error dispose of the domain
    reqd.on('error', function (error) {
    console.error('Error', error, req.url)
    reqd.dispose()
    });
    var oUrl = url.parse(req.url);
    if (typeof req.headers !== 'undefined' && req.headers.host.split)
    {
    var hostname = req.headers.host.split(":")[0];
    var pathname = oUrl.pathname;
    switch(hostname)
    {
    case 'forum.theamericanbulletin.com':
    proxy.web(req, res, { target: 'http://localhost:8080' });
    break;
    default:
    proxy.web(req, res, { target: 'http://localhost:8081' });
    };
    console.log(hostname);
    console.log(pathname);
    }
    }).listen(80,function(){
    console.log('proxy listening on port 80');
    });
    });