:-moz-system-metric(touch-enabled) looks like a really useful CSS selector for working on mobile sites.
Unfortunately Webkit is dominant on mobile touch devices so does anyone know if there is a Webkit equivalent?
(Ideally it'd be good if this was managed by CSS3 media queries)
Edit: Looks like it is supported in Gecko as a media query
There's no way to accomplish this without resorting to Javascript, at present.
As #easwee said, Modernizr is a well-regarded JS library that focuses on feature detection. You can use its touch test for your use case.
If you don't need all of Modernizr's bells and whistles, you can do the following:
A) Load the following JS as early in your <body> tag as you can:
<script type="text/javascript">
if( !!window.TouchEvent ) body.className += " touch-enabled ";
</script>
B) Write your CSS. Since Gecko uses a media query to inform you of touch availability, you'll have to dupe the touch-specific CSS, like so:
BODY.touch-enabled DIV.foo
{
/* touch-specific CSS */
}
#media screen and (-moz-touch-enabled)
{
DIV.foo
{
/* touch-specific CSS */
}
}
If the per-selector code is identical in both circumstances, GZIP ought to optimize away some of the duplication. (You are using compression, I hope.)
In Ian Wessman's answer the test !!window.TouchEvent works incorrectly. In current desktop Chrome (23.0.1271.52, Linux) window.TouchEvent is a function, so Ian's code considers the browser touch-enabled.
If you want short code, it's probably best to copy-paste the relevant code from Modernizr.
Chrome is another browser that tried to implement a similar selector but unfortunately it was removed out for now.
Modernizr could be and interesting detection tool since it can detect touch events too.
http://www.modernizr.com/docs/#touch
Related
Problem: when I use a visual regression testing tool such as PhantomCSS, the screenshots produced contain the website with dramatically moved HTML elements.
Problem image:
How it should really look like: (taken from esfiddle.net )
Tools: PhantomCSS. The same problem happens with BackstopJS.
What can I do to prevent the problem image?
The flex CSS property is causing the problems.
Since version 3 backstop supports chrome as engine, so you could specify
"engine": "chrome"
I think it would work fine in Chrome.
OK, so I use Respond.js a polyfill for mediaqueries on legacy browsers (ie8 being the most important).
At the same time I'm investigating in using Enquire.js which enables executing js-code based on media-query matches.
Tested in isolation this stuff works:
respond.js executes media-queries defined in css correctly for IE8
enquire.js executes javascript code correctly based on media-queries matching css. (for NON-legacy browsers)
However the combi doesn't seem to work. I.e:
Enquire.js doesn't execute javascript based on a media-query which gets enabled through respond.js (for legacy browsers)
Since Respond.js contains Paul Irish's polyfill for MatchMedia which (as per: Enquire's documentation) should be enough for legacy support, I'm not sure what could be wrong.
So just to be checking: this combination should work right?
I'm the author of enquire, so i'll help where i can.
I've just browsed through the respond.js source to find out how it works. Respond extracts any media queries from your CSS, then depending on the width of the window it will create new style blocks containing that CSS if the media query matches (this is why it only supports simple media queries such as max/min-width). This of course means that it will not help enquire JS, as it is simulating media queries.
The inclusion of the matchMedia polyfill is actually a red herring. All that does is create an equivalent to the matchMedia browser API. Thus if the browser only supports very limited set of media queries (as IE8 does), it will not expand it's capabilities, it will only allow you to work within it's means. I made this mistake myself at first!
I don't know if this will help you, but enquire's register method can accept a third parameter, shouldDegrade which is a signal to enquire that you intend the functionality to always run if the browser is deemed incapable. Thus if you pass in true, the match function will always be executed for incapable desktop browsers (whilst still being conditional for capable browsers). This will allow you to deliver a desktop experience to older browsers, especially useful in mobile-first approaches.
Happy to help further if you have any more questions
Try removing the inclusion of matchMedia from respond.js, and then loading match.media and enquire.js after respond.js. Worked for me in IE 7 and 8 with enquire v 2.0.2.
I found a solution that seems to work for IE8
1.Very important ! Remove match.media from respond JS if you use it (if not it will silently fail in IE)
2.Include Modernizr with at least mediaqueries testing, load, shiv : http://modernizr.com/download/#-shiv-mq-cssclasses-teststyles-load
3.In < head > (because we need respondjs in head)
<script src="../../common/vendor/modernizr/modernizr.custom.js"></script>
<script>
Modernizr.load([
// Test need for CSS media query polyfill
{
test: Modernizr.mq("only all"),
nope: "../../common/vendor/respond/respond.min.js"
}
]);
</script>
4.Before < /body > tag to load polyfill and your scripts
<script>
Modernizr.load([
{
test: window.matchMedia,
nope: [
"../../common/vendor/polyfills/media.match.js",
"../../common/vendor/polyfills/matchMedia.addListener.js"
]
},
'../../common/vendor/enquire/enquire.min.js',
'../../common/scripts/script.js'
]);
</script>
I hope it will work for you !
I'm a friend clean GUI's. Unfortunately I need to overwrite the "chrome://global/skin" stylesheets for some reason.
What's the best method, to implement different os-based stylesheets into xul-documents - eg. for GUI's like windows xp, windows aero or macosx aqua (overlay-aero.css, overlay-aqua.css...).
Does Mozilla provide any standards for os-based stylesheet-implementing?
Without really knowing how you intend to overlay the styles: yes, the usual approach would be using manifest flags. For example, if you define a style overlay in your extension's chrome.manifest file, you would do it like this:
style chrome://browser/content/browser.xul chrome://myExtension/skin/overlay-win.css os=WINNT
style chrome://browser/content/browser.xul chrome://myExtension/skin/overlay-osx.css os=Darwin
style chrome://browser/content/browser.xul chrome://myExtension/skin/overlay-linux.css os=Linux
You can also use Mozilla-specific media features to distinguish between different themes of one OS in your stylesheet. For example:
#media all and (-moz-windows-classic)
{
...
}
#media all and (-moz-windows-theme: aero)
{
...
}
#media all and (-moz-windows-compositor)
{
...
}
Sounds to me like you want to create your own Firefox Theme (essential an extension made up of CSS files and images that replace the standard look of the browser). There's a whole section about this on Mozilla Development Center: https://addons.mozilla.org/en-US/developers/docs/how-to/theme-development
In my Cocoa app, I want to prevent Flash from loading in a WebView, and let the user decide if the Flash should be shown for each page. (That's the same behavior already available through the ClickToFlash plugin or Safari extension. Bundling any of those extensions is probably not an option because of licensing issues.)
Unfortunately most of the Flash I'm trying to avoid is generated from embedded JavaScript specifically designed to prevent easy flash blocking, so I cannot filter the raw HTML for inclusion of Flash objects.
Also, I cannot disable JavaScript for my WebView, as the page I want to display looks completely different when JavaScript is turned off.
Is there a notification/hook I can use to modify the page DOM after JavaScript has been executed, but before the Flash plugin is loaded?
Or should I pursue a different direction?
Thanks,
Ilja
Ideally, you would just define your own WebKit plug-in that handles the application/shockwave-flash MIME type and make your plug-in do nothing.
However, there is unfortunately no way to control the priority of multiple WebKit plug-ins that all register for the same MIME type. The loading order of WebKit plug-ins is totally random and arbitrary, so you cannot guarantee that your plug-in will handle the Flash object instead of the Flash plug-in.
The only way around this that I've found is to subclass WebView and override the private method -_pluginForMIMEType: like so:
#class WebBasePluginPackage;
#interface WebView ( MyFlashPluginHack )
- (WebBasePluginPackage *)_pluginForMIMEType:(NSString *)MIMEType;
#end
#implementation MyWebView
- (WebBasePluginPackage *)_pluginForMIMEType:(NSString *)MIMEType
{
if ( [MIMEType isEqualToString:#"application/x-shockwave-flash"] )
{
return [super _pluginForMIMEType:#"application/my-plugin-type"];
}
else
{
return [super _pluginForMIMEType:MIMEType];
}
}
#end
Then you just need to create a custom WebKit plugin to handle "application/my-plugin-type" and have that plug-in do nothing at all.
Okay, we pretty much figured this out.
Since there is no official API that lets the host app know when JavaScript has finished or control what plugin should load, we are now using custom JavaScript that gets inserted into the received HTML we want to display.
The ClickToFlash Safari extension (not the Internet plugin, which it is based on) was a good inspiration.
Thanks to everyone in advance -
So I have been banging on this issue for quite a while now and have burned through all my options. My current approach to canceling css requests is with nsIRequest.cancel inside of nsIWebProgressListener.onStateChange. This works most of the time, except when things are a little laggy a few will slip through and jump out of the loadgroup before I can get to them. This is obviously a dirty solution.
I have read through the following links to try and get a better idea of how to disable css before a nsIRequest is created...no dice.
https://developer.mozilla.org/en/Document_Loading_-_From_Load_Start_to_Finding_a_Handler
https://developer.mozilla.org/en/The_life_of_an_HTML_HTTP_request
https://developer.mozilla.org/en/Bird's_Eye_View_of_the_Mozilla_Framework
How do I disable css via presentation objects/interfaces? Is this possible? Inside of nsIDocShell there are a few attributes that kind of imply you can disable css via the browsers docshell - allowPlugins, allowJavascript, allowMetaRedirects, allowSubframes, allowImages.
Any suggestions?
Thanks,
Sam
The menu option that disables style sheets uses a function
setStyleDisabled(true)
so you probably can just call this function whenever new browser tab is created. Style sheets are still requested from server, but not applied. This function is not very sophisticated and doesn't mess with nsIRequest, source:
function setStyleDisabled(disabled) {
getMarkupDocumentViewer().authorStyleDisabled = disabled;
}
Digging in Web Developer Toolbar source code I have noticed that their "disable stylesheets" function loops trough all document.styleSheets and sets the disabled property to true, like:
/* if DOM content is loaded */
var sheets = document.styleSheets;
for(var i in sheets){ sheets[i].disabled = true; }
So if the key is to not apply CSS to pages, one of the above solutions should work. But if you really need to stop style sheets from being downloaded from servers, I'm affraid nsIRequest interception is your only option.
Set permissions.default.stylesheet to 2 and voilĂ !
You can actually use the permissions manager to block or allow stylesheets on a host-by-host basis.
Unfortunately there doesn't seem to be a simple flag like allowImages. The bugzilla adding for that is https://bugzilla.mozilla.org/show_bug.cgi?id=340746. You can now vote for it using the new bugzilla voting functionality. You can also add yourself to the CC list to be notified if anyone ever works on it.
A related request is to just give us basic HTML parsing support, which may be what you are trying to do. Unfortunately that isn't supported yet either, but you can vote/track the bugzilla for that at https://bugzilla.mozilla.org/show_bug.cgi?id=102699.
So the only workable solution seems to be some sort of interception as #pawal suggests. Here is a link that talks about the basics of interception to at least get you/us started https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads. It lists several options that I list below.
These first few seem to just be at the page/document level so I don't think they help:
Load Events (addEventListener load)
Web Progress Listeners (nsIWebProgressListener) - I tried this approach, it only seems to be called for the page itself, not for content within the page.
Document Loader Service - A global version of nsIWebProgressListener so I think it has the same problem (page level only)
That leaves two others I have not tried yet. They work globally so you would need to filter them to just the browser/pages you care about.
HTTP Observers - Seems like it might work, need to verify it calls back for CSS
Content Policy - Seems like the best option to me since it explicitly is called for CSS, someday I hope to try it :)