23

We are working on the software for a museum. There are several interactive kiosks with touch screen running on Windows 8.1 which are connected into local network. No keyboard, no mouse. The server with Apache on it contains several local websites. Each kiosk runs a copy of Google Chrome in a kiosk mode. So, we have some kind of local web applications which provide a museum visitor with information.

Now, the problem. If a visitor does long touch on screen it works like an analogue of right click. Context menu appears. We don't want it at all. I've added "oncontextmenu = return false" into the body tag and it helped. But. We have a couple of external websites running in iframes (the museum has a connection to Internet). And context menu does appear on iframes. AFAIK, there is no way to disable it using javascript.

Our system engineer got a software which completely disables right click in Windows. Anywhere including Chrome. But. It works for a mouse. And as for touches... well, it disables touch events anywhere besides Chrome. Maybe Chrome has its own touch events handler, I don't know.

So, after all. We need to get rid off context menu on iframes on right click/long touch in a kiosk mode of Chrome. Please give me some advice.

korsun
  • 618
  • 2
  • 6
  • 12
  • Although it *potentially* could be a security loophole, you could try and disable Chrome's cross domain origin policy and use `window.frames["frame_id"].document.oncontextmenu = function(){ return false };` – JCOC611 Jan 29 '15 at 19:12
  • @JCOC611, by disabling Chrome's cross domain origin policy you mean launch with the --disable-web-security switch? If so, it doesn't work, unfortunately... – korsun Jan 29 '15 at 19:59
  • I think my answer won't work if your kisok view is inside of a Chrome app -- you can't inject a content script into an iframe loaded inside of another extension's or app's page, even if the iframe is for a page that the extension should normally have access to. **However,** I think it could be possible to solve your problem by using [``](https://developer.chrome.com/apps/tags/webview) elements instead of iframes: use the `executeScript` method when the webview fires a `contentload` event. – apsillers Jan 29 '15 at 20:25

2 Answers2

27

I assume you're displaying a plain http://... (or possibly https://... or file://...) Web page on your kiosk. If you're actually showing an app (i.e., chrome-extension://...), then this strategy will not work.

A Chrome extension that injects window.addEventListener("contextmenu", function(e) { e.preventDefault(); }) into every browsing context would probably do the trick to block context menus on iframes.

manifest.json:

{
    "manifest_version": 2,
    "name": "Context Menu Blocker",
    "version": "1.0",
    "content_scripts": [
      {
        "matches": ["<all_urls>"],
        "js": ["contextblocker.js"],
        "all_frames": true,
        "match_about_blank": true
      }
    ]
}

contextblocker.js:

window.addEventListener("contextmenu", function(e) { e.preventDefault(); })

Simply create a folder and place the two files inside. Then, go to chrome://extensions/, check the Developer Mode box. Finally, click Load unpacked extension... and select the folder you just created.

This should prevent the context menu from appearing in anywhere extension content scripts are allowed to run, include any page loaded inside of an iframe. There are few notable points where it fails:

  • Extensions are not allowed to run on chrome:// or chrome-extension:// pages, or on Google's Web Store. If your kiosk is displaying an app, this whole strategy won't work, because this extension won't be able to access iframes inside of another app or extension (even if the source of the iframe is an origin that it would normally have permission to access).
  • If you navigate directly to about:blank, the content script will not run and the context menu can appear. (If about:blank is loaded in an iframe, however, the block will work correctly.)
  • If an iframe has a sandbox attribute that does not include the allow-scripts permission, then the extension cannot block context menus from that iframe.

As long as none of those restrictions apply (and as long as a script on the page itself does not clear all event listeners on window), then it should work.

I have used the code above to create a simple extension in the Chrome Web Store. (Developer-mode extensions now produce a warning on start-up, while Web Store extensions do not.)

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • At first I took your answer sceptically but... it works! It really works! Thanks a lot! – korsun Jan 29 '15 at 20:42
  • Chrome will display a popup altering the user to unsafe extensions being used. – Twilite May 28 '15 at 14:36
  • 1
    @Twilite Hm, they added that behavior in the a recent update, I think. The only suggestion I can make is to upload the extension to the Chrome Web Store and install it from there. If you're not a developer (and don't want to get set up or spend the $5), I'll upload it later today and add a link. – apsillers May 28 '15 at 15:25
  • If you did that, it would be awesome. Please post the link here. – Twilite May 28 '15 at 15:35
  • greetings @apsillers, i have tried to deploy your extension as part of R&Ding a windows application that uses [Ctrl + Right-click] as its default global bind to trigger an action (on a word or image), and it appears to no longer suppress the context menu in chrome 62. Apparently chrome started rolling their own context menu sometime last year and i suspect that's why your ext is no longer working-- any thoughts/ideas? – propagated Nov 16 '17 at 15:02
  • @propagated I am running Chrome 62 (on Windows 7) and the extension still works fine for me. I installed the extension from the Web Store, loaded http://example.com in a new tab, and it correctly suppresses the context menu. Are you working with something other than an `http:` or `https:` page? This will not work for `chrome-extension:` pages, and to have it work on `file:` pages, you have to explicitly enable that in `chrome://extensions`. It also will not work in the Chrome Web Store because all extensions are disabled there. – apsillers Nov 16 '17 at 16:28
  • I was having a similar issue. My touch events were triggering a context menu. It appears touch events invoke mouse events after. You can stop this by calling "preventDefault()" within the touch event handler (touchDown, etc). This fixed the issue for me; I didn't need to preventDefault() within the context menu handler. – Enigma22134 Sep 05 '19 at 01:08
3

If you're using jQuery, the below code will disable the context menu (aka 'right click').

$(document).on("contextmenu",function(){
       return false;
    }); 
}); 
daCoda
  • 3,583
  • 5
  • 33
  • 38