0

The problem: a Chrome sidebar

For a long time, I've wanted a Chrome extension that puts other content in a sidebar within Gmail, much like the Remember the Milk Gmail extension.

It seems I'm not alone2 but the Chrome devs have made this functionality much more difficult than, say, Firefox3. After failing to make several hacks and workarounds function, I used extensionizr and someone else's code to write my first Chrome extension.

The aim is to allow me to have a sidebar with a to-do list or whatever iframe I want available in my Chrome tabs, especially my Gmail tab.

The issue: iframes in Gmail html pages

The issue I'm having is that with https://todoist.com/ as my iframe src, it works in every tab I've tried except Gmail. A caveat: it works in some Gmail accounts but not others. I can't find any differences that would cause this.

I've tried disabling all other extensions in case there are the compatibility issue but no luck and it works in some Gmail accounts even with everything activated. I've tried disabling all Labs and changing all settings to match but still no dice.

Another angle where SSL is interfering (but with very weird symptoms)?

I'm inclined to think it's an SSL issue as Gmail doesn't like embedding iframes with non HTTPS content but this doesn't make sense because it works with some Gmail accounts, not others.

Any thoughts, input, advice would be greatly appreciated as I'm an utter novice and completely stuck here.


More info in case it helps: when I edit the page source, I can literally remove everything in the Gmail page apart from html and body tags and the injected iframe and it still comes up blank as though the content isn't being grabbed by the iframe src in the first place somehow...


addendum the second: a) Logging network data, with the working account it pulls the data successfully from the SSL site with a GET request. On the non-working account, no request is ever made. b) Even if I load Gmail, then strip down the DOM to bare HTML and body tags then inject the iframe it comes up blank. The source is as follows but no content is requested, loaded or displayed. wtactualf?!

<html class="aAX" style="position: relative; width: 1187px;">
  <body class="aAU fullcontact-minimized GmInitDone">
  </body>
  <iframe id="someSidebar" src="https://todoist.com/" frameborder="0" allowtransparency="false" style="position: fixed; height: 100%;border:none;z-index: 2147483647;top:0px;right:0px;width: 400px;"></iframe>
</html>
Community
  • 1
  • 1
Turkeyphant
  • 222
  • 1
  • 3
  • 15
  • Using Iframe inside the content with chrome:// as the base url and load the iframe inside this page again. As mentioned by Rob. We have released our extension a few days back https://chrome.google.com/webstore/detail/typeless-chrome-extension/glggemdefgdemakpkekbbmjdpgljekhm which does the same. – sudhanshu Jan 13 '15 at 10:42

1 Answers1

-1

Ignore all below the first horizontal rule - short story it was a CSP issue but Rob W's solution is far superior:

manifest.json

    {
      "name": "Todoist Gmail Sidebar",
      "manifest_version": 2,
      "description": "Toggle a Todoist sidebar on the gmail tabs when the page action is clicked",
      "version": "0.9",
      "homepage_url": "http://turkeyphant.org",
      "icons": {
        "16": "icon16.png",
        "48": "icon48.png",
        "128": "icon128.png"
      },
      "permissions": [ "tabs",
        "https://*/*","http://*/*","activeTab"
      ],
      "background":{
        "persistent":true,
        "scripts": ["background.js"]
      },
      "browser_action": {
        "default_icon": "icon128.png",
         "default_title": "Toggle Todoist sidebar"
      },
        "content_scripts": [
            {
              "js": [
            "jquery.min.js",
            "jquery.easing.1.3.js",
            "contentscript.js"
                ],
                "matches": [
            "*://mail.google.com/*"
                ],
                "run_at": "document_end"
            }
        ],
        "web_accessible_resources": [
            "frame.html",
            "toggleSidebar.js"
        ]
    }

contentscript.js

    if (typeof sidebarOpen == 'undefined') { //if not set yet, it's closed
    console.log("sidebar initiated");
    sidebarOpen = false; //set closed

    var width = '400';//variables
    //resolve html tag, which is more dominant than <body>
                    var html;
                    if (document.documentElement) {
                      html = $(document.documentElement); //just drop $ wrapper if no jQuery
                    } else if (document.getElementsByTagName('html') && document.getElementsByTagName('html')[0]) {
                      html = $(document.getElementsByTagName('html')[0]);
                    } else if ($('html').length > -1) {//drop this branch if no jQuery
                      html = $('html');
                    } else {
                      alert('no html tag retrieved...!');
                      throw 'no html tag retrieved son.';
                    }
                  //position
                  if (html.css('position') === 'static') { //or getComputedStyle(html).position
                    html.css('position', 'relative');//or use .style or setAttribute
                  }

    // Avoid recursive frame insertion...
    var extensionOrigin = 'chrome-extension://' + chrome.runtime.id;
    if (!location.ancestorOrigins.contains(extensionOrigin)) {
        var iframe = document.createElement('iframe');
        // Must be declared at web_accessible_resources in manifest.json
        iframe.src = chrome.runtime.getURL('frame.html');
        iframe.className = 'todo-sidebar';

        // Some styles for a fancy sidebar
        iframe.style.cssText = 'position:fixed;top:0;right:-'+width+'px;display:block;width:'+width+'px;height:100%;z-index:1000;border-width: 0px 0px 0px 0px;';
        document.body.appendChild(iframe);
      }
    } 

frame.html

<iframe id="iframe-sidebar" src="https://todoist.com/"></iframe>

Then you can put whatever you want in toggleSidebar.js.


So after further investigation it seems the issue is something in Gmail which is blocking iframe content from certain domains:

Refused to frame 'https://todoist.com/' because it violates the following Content Security Policy directive: "frame-src https://.talkgadget.google.com/ 'self' https://accounts.google.com/ https://apis.google.com/u/ https://clients6.google.com/static/ https://content.googleapis.com/static/ https://mail-attachment.googleusercontent.com/ https://www.google.com/calendar/ https://docs.google.com/ https://drive.google.com https://.googleusercontent.com/docs/securesc/ https://feedback.googleusercontent.com/resources/ https://www.google.com/tools/feedback/ https://*.googleusercontent.com/gadgets/ifr https://talkgadget.google.com/u/ https://talkgadget.google.com/talkgadget/ https://isolated.mail.google.com/mail/ https://www-gm-opensocial.googleusercontent.com/gadgets/ https://plus.google.com/ https://wallet.google.com/gmail/ https://www.youtube.com/embed/ https://clients5.google.com/pagead/drt/dn/ https://clients5.google.com/ads/measurement/jn/ https://www.gstatic.com/mail/ww/ https://clients5.google.com/webstore/wall/ https://ci3.googleusercontent.com/ https://apis.google.com/additnow/".

However, I can't figure out why one Gmail account is blocking this but not the other. Nor where this list is coming from or how I can override/change it for my extension.

Turkeyphant
  • 222
  • 1
  • 3
  • 15
  • 1
    Downvoted because the suggested solution reduces the security of Google, it is not scalable (only one extension can modify the header). See also https://code.google.com/p/chromium/issues/detail?id=408932 and https://code.google.com/p/chromium/issues/detail?id=391128 – Rob W Jan 05 '15 at 16:55
  • Of course - it's only intended as a personal fix for my issue and can be altered to only affect the URL patterns you require. Of course an alternative would be preferred but I found nothing. Do you know of anything else that works? – Turkeyphant Jan 05 '15 at 17:03
  • 1
    A proper way to work around the issue has been posted here: https://stackoverflow.com/questions/24641592/injecting-iframe-into-page-with-restrictive-content-security-policy – Rob W Jan 05 '15 at 17:04