Search code examples
google-chrome-extensiondraggable

Make chrome extension popup opening in iframe draggable?


I want my extension to open up in the form of an iframe instead of the normal popup window. I've been able to achieve this so far. Now I'm trying to make this iframe draggable using jQuery UI but unable to do so. My code for inject.js is as below:

function toggleVisisbility (node) {
node.style.display = (node.style.display === 'none' || node.style.display === '') ? 'block' : 'none'
}

function appendIframe(app) {
var iframe = document.createElement('iframe');
iframe.id = 'popup-app';
iframe.style.cssText = 'position:absolute;top:0;right:0;display:block;' +
    'width:350px;height:500px;z-index:99999999;' +
    'border: none;' +
    'box-shadow: 0px 8px 16px rgba(0,0,0,0.25);';

chrome.storage.local.get("logged_in", function(data) {
    if(data.logged_in) {
        iframe.src = chrome.runtime.getURL('./html/loggedPopup.html')
    } else {
        iframe.src = chrome.runtime.getURL('./html/popup.html')
    }
});

app.appendChild(iframe)
}

function insertIframe(anchor) {
let app = Array.from(anchor.childNodes).find(function(node){ return node.id === 'popup-app'})

if (app) {
    if (app.querySelectorAll('iframe').length === 0) {
        appendIframe(app)
    }
    toggleVisisbility(app)
} else {
    appendIframe(anchor)
}
}

var extensionOrigin = 'chrome-extension://' + chrome.runtime.id
if (!location.ancestorOrigins.contains(extensionOrigin)) {
var anchor = document.getElementById('cfp-anchor')
if (anchor) {
    insertIframe(anchor)
} else {
    const AppRoot = document.createElement('div', { id: 'cfp-anchor' });
    AppRoot.id = 'cfp-anchor';
    const body = document.getElementsByTagName('body')[0];
    body.appendChild(AppRoot);
    AppRoot.innerHTML = '';
    insertIframe(AppRoot)
}
}

Solution

  • I figured out the solution. I used a div instead of an iframe, made the div draggable and then loaded my html inside the div. I used the following code:

    function appendIframe(app) {
    
    var draggableDiv = document.createElement('div');
    
    draggableDiv.id = 'popup-app';
    draggableDiv.className = 'draggable';
    draggableDiv.setAttribute('data-draggable', 'true');
    draggableDiv.style.cssText = 'position:fixed;top:16px;right:21px;display:block;' +
        'width:350px;height:500px;z-index:99999999;' +
        'border: none; cursor: move;' +
        'box-shadow: 0px 8px 16px rgba(0,0,0,0.25);' +
        'background: #25BAF1;';
    
    chrome.storage.local.get("logged_in", function(data) {
        if(data.logged_in) {
            document.getElementById("popup-app").innerHTML='<object id="overlay" style="width: 100%; height: 100%; position: absolute; top: 25px" type="text/html" data='+chrome.runtime.getURL('./html/loggedPopup.html')+' ></object>';
        } else {
            document.getElementById("popup-app").innerHTML='<object id="overlay" style="width: 100%; height: 100%; position: absolute; top: 25px" type="text/html" data='+chrome.runtime.getURL('./html/popup.html')+' ></object>';
        }
    });
    $("#popup-app").addClass(".draggable");
    makeDivDraggable();
    
    app.appendChild(draggableDiv)
    }
    
    
    function makeDivDraggable(){
    $(document).ready(function() {
    
        var $body = $('body');
        var $target = null;
        var isDraggEnabled = false;
    
        $body.on("mousedown", "div", function(e) {
    
            $this = $(this);
            isDraggEnabled = $this.data("draggable");
    
            if (isDraggEnabled) {
                if(e.offsetX===undefined){
                    x = e.pageX-$(this).offset().left;
                    y = e.pageY-$(this).offset().top;
                }else{
                    x = e.offsetX;
                    y = e.offsetY;
                }
    
                $this.addClass('draggable');
                $body.addClass('noselect');
                $target = $(e.target);
            }
    
        });
    
        $body.on("mouseup", function(e) {
            $target = null;
            $body.find(".draggable").removeClass('draggable');
            $body.removeClass('noselect');
        });
    
        $body.on("mousemove", function(e) {
            if ($target) {
                $target.offset({
                    top: e.pageY  - y,
                    left: e.pageX - x
                });
            }
        });
    
    });
    }
    

    What this basically does is create a div, which is draggable and then sticks up another layer of html on top. The modified position allows to grab the div from the top and then move it around.