IE has both a "Browser Mode" and a "Document Mode" which are defined
[0] as following:
"""
* Browser mode controls the way Internet Explorer identifies itself to
the server hosting a webpage.
...
* Document mode controls the way Internet Explorer interprets and
displays a webpage
"""
My understanding is that "Document Mode" determines HTML/CSS/JS
support and "Browser Mode" is mostly a surface level user agent thing.
At the end of the day, most of the closure-library samples have taken
to setting X-UA-Compatible to IE=edge to force the _document mode_ to
the most recent available (however this does not change the _browser
mode_). This msdn post [1] has a helpful flow chart to show how
_document mode_ is determined.
In addition to above, setting X-UA-Compatible also removes the ability
of the user to manually toggle on/off compatibility view (the "torn
paper" icon the right side of the location bar). However, it is still
possible for the user to force the _browser mode_ to something old.
For example, by selecting the "Display all websites in Compatibility
View" option. If a page also sets IE=edge this can result of a
_browser mode_ of 7 and a _document mode_ of 9 for example. To the
best of my knowledge, in this case the browser will function entirely
like IE9 (other than the user agent reported). Can anyone confirm if
this is true?
Which brings me to the closure-library portion of my question. In r263
[2] goog.userAgent.isVersion is modified to use the _document mode_ if
it is greater than the version returned in the user agent string.
Later in r837 [3] goog.userAgent.isDocumentMode is added to allow
clients to check the document mode directly.
What is the difference between isVersion and isDocumentMode? When
should each be used?
Thanks,
-Andy
[0] http://msdn.microsoft.com/en-us/library/cc288325(v=vs.85).aspx
[1] http://blogs.msdn.com/b/ie/archive/2010/03/02/how-ie8-determines-document-mode.aspx
Browser mode should be ignored - it only effects what browser ie pretends to be and based on that and many other factors what the document mode is. Only the document mode changes ie's rendering, so i think you are right. I can only think that the change makes isVersion more accurate by catching cases you describe where the browser version is lower than the document version. However since the browser version doesn't effect rendering and does not equal the document mode, the document mode is more accurate for use client side in determining differences in rendering.
However, am I right in thinking that if x-ua-compatability is edge the browser mode will now equal the document mode in all circumstances as document mode will never be less than browser mode?
Thanks for the confirmation. It sounds like we have the same understanding.
> I can
> only think that the change makes isVersion more accurate by catching cases
> you describe where the browser version is lower than the document version.
> However since the browser version doesn't effect rendering and does not
> equal the document mode, the document mode is more accurate for use client
> side in determining differences in rendering.
Sounds right to me.
If I'm not missing anything this means that IE feature detection in
closure-library should always be done using _document mode_. Does
anyone know of a case when this is not true?
However, currently IE feature detection is done using both isVersion
[0] and isDocumentMode [1]. Given their implementations it is not
immediately clear to me in all of the cases when they will differ. Can
anyone comment on these cases?
The isVersion implementation starts with the user agent string
(changed by _browser mode_) and then increases the version (if
applicable) using the _document version_ as described previously. The
isDocumentMode implementation uses the raw document mode.
I see three changes converting some (but not all) calls from isVersion
to isDocumentMode [2]. Can one of the authors of these changes
(wuyingbing, gboyer) comment on if the lingering isVersion calls
should be updated?
> However, am I right in thinking that if x-ua-compatability is edge the
> browser mode will now equal the document mode in all circumstances as
> document mode will never be less than browser mode?
I believe this is correct.
Per my understanding browser mode (as displayed in the dev tools) is
always >= the document mode. If the webpage sets IE=edge, the largest
available document mode is selected (making browser mode == document
mode).
A weirdness that I have seen here (mentioned previously) is in IE8
when the user sets the "Display all websites in Compatibility View"
option and the page sets IE=edge. In this case I see the following
output (note the MSIE 7 in user agent):
Browser Mode (from dev tools): IE8 Compat
Document Mode (from dev tools): IE8 Standards
User Agent (Note MSIE 7): Mozilla/4.0 (compatible; MSIE 7.0; Windows
NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC
5.0; .NET CLR 3.0.30729; .NET CLR 3.5.30729; .NET4.0C)
document.documentMode: 8
goog.userAgent.VERSION: 8
In this case using isVersion is the same as using isDocumentMode so I
must be overlooking the subtle difference.
Thanks,
-Andy
[0]
~/closure-library-read-only$ grep -Ri "IE.*isVersion" . | grep -v
_test | grep -v "\.svn"
./closure/goog/events/onlinehandler.js: goog.userAgent.IE &&
goog.userAgent.isVersion('8') ||
./closure/goog/storage/mechanism/ieuserdata.js: if (goog.userAgent.IE
&& !goog.userAgent.isVersion(9)) {
./closure/goog/style/style.js: if (goog.userAgent.IE &&
!goog.userAgent.isVersion('8')) {
./closure/goog/style/style.js: if (goog.userAgent.IE &&
!goog.userAgent.isVersion('8')) {
./closure/goog/style/style.js: if (goog.userAgent.IE &&
!goog.userAgent.isVersion('8')) {
./closure/goog/net/browsertestchannel.js: if (goog.userAgent.IE &&
!goog.userAgent.isVersion('8')) {
./closure/goog/net/browserchannel.js: if (goog.userAgent.IE &&
!goog.userAgent.isVersion('8')) {
./closure/goog/net/browserchannel.js: return goog.userAgent.IE &&
!goog.userAgent.isVersion('8');
./closure/goog/net/iframeloadmonitor.js: var isIe6OrLess =
goog.userAgent.IE && !goog.userAgent.isVersion('7');
./closure/goog/dom/browserfeature.js: CAN_USE_INNER_TEXT:
goog.userAgent.IE && !goog.userAgent.isVersion('9'),
./closure/goog/editor/plugins/enterhandler.js: if (goog.userAgent.IE
&& !goog.userAgent.isVersion(9)) {
./closure/goog/ui/hsvpalette.js: var noalpha = (goog.userAgent.IE &&
!goog.userAgent.isVersion('7')) ?
./closure/goog/ui/controlrenderer.js: if (goog.userAgent.IE &&
!goog.userAgent.isVersion('7')) {
./closure/goog/ui/controlrenderer.js: if (goog.userAgent.IE &&
!goog.userAgent.isVersion('7')) {
./closure/goog/ui/controlrenderer.js: if (goog.userAgent.IE &&
!goog.userAgent.isVersion('7')) {
./closure/goog/graphics/graphics.js: if (goog.userAgent.IE &&
!goog.userAgent.isVersion('9')) {
[1]
~/closure-library-read-only$ grep -Ri "IE.*isDocumentMode" . | grep -v
_test | grep -v "\.svn"
./closure/goog/events/keycodes.js: return !(goog.userAgent.IE &&
goog.userAgent.isDocumentMode(9));
./closure/goog/events/browserfeature.js: HAS_W3C_BUTTON:
!goog.userAgent.IE || goog.userAgent.isDocumentMode(9),
./closure/goog/style/style.js: if (goog.userAgent.IE &&
!goog.userAgent.isDocumentMode(9) &&
./closure/goog/dom/textrange.js: if (goog.userAgent.IE &&
!goog.userAgent.isDocumentMode(9)) {
./closure/goog/dom/textrange.js: (!(goog.userAgent.IE &&
!goog.userAgent.isDocumentMode(9)) ||
./closure/goog/dom/browserfeature.js: goog.userAgent.IE &&
goog.userAgent.isDocumentMode(9) ||
./closure/goog/dom/browserrange/browserrange.js: if
(goog.userAgent.IE && !goog.userAgent.isDocumentMode(9)) {
./closure/goog/dom/browserrange/browserrange.js: if
(goog.userAgent.IE && !goog.userAgent.isDocumentMode(9)) {
./closure/goog/dom/browserrange/browserrange.js: if
(goog.userAgent.IE && !goog.userAgent.isDocumentMode(9)) {
./closure/goog/editor/browserfeature.js: HAS_IE_RANGES:
goog.userAgent.IE && !goog.userAgent.isDocumentMode(9),
./closure/goog/editor/browserfeature.js: (goog.userAgent.IE &&
goog.userAgent.isDocumentMode(9)),
[2]
http://code.google.com/p/closure-library/source/detail?r=837
http://code.google.com/p/closure-library/source/detail?r=1038
http://code.google.com/p/closure-library/source/detail?r=1039
On Thu, Jul 28, 2011 at 12:17 PM, Garry Boyer <gbo...@google.com> wrote:
> If you just want to know if a new feature is available, usually the browser
> version provides more useful information.
Why is that?
The problem I have seen with using browser version for feature
detection is when compatibility view (or "all pages compat view") is
turned on the document mode may end up supporting a feature while the
user agent string (browser mode) implies the feature would not be
supported. I think this is why isVersion "bumps up" the version based
on the document mode.
> But for example, a widget embedded across the Web must support IE9 in both 8
> and 9 documentMode, because IE9 can't mix IE9 and IE8- frames on the same
> page. e.g. if the parent page is anything but IE9 standards mode, all
> iframes in it will be forced into IE8 mode. But IE doesn't tell you that
> this will happen -- it still identifies on the server as IE9, so you have to
> do your checks in JS.
Thanks for the example! I was unaware of this case and I can recreate
the exact behavior your describe.
Based on my test, this still seems to imply feature detection should
always be done based on documentMode. The IE9 in IE8 mode iframe does
not support IE9 features (as you state -- which corresponds with the
documentMode). My test case:
http://69.164.217.215/force_ie8.htm
http://69.164.217.215/browser_mode.htm
At the end of the day, it seems to me that the isVersion logic can be
simplified to help avoid the types of bugs that were resolved in r837,
r1038 and r1039. For IE, my current understanding is that isVersion()
should use the raw documentMode if it exists and fall back to the user
agent if it does not (ex: IE6 or no DOM). To be concrete:
http://codereview.appspot.com/4794066/diff/1/closure/goog/useragent/useragent.js
Can you help me understand the case when this logic does the "wrong thing"?
Many thanks for your help!
-Andy
I added a comment describing the reasoning behind this change:
http://codereview.appspot.com/4794066/diff/2001/closure/goog/useragent/useragent.js
-Andy
http://code.google.com/p/closure-library/issues/detail?id=355
Feedback is appreciated as time permits.
Thanks,
-Andy
Thanks!
-Andy
On Thu, Jul 28, 2011 at 2:21 PM, Hochhaus, Andrew
<ahoc...@samegoal.com> wrote:
:)
Thanks!
-Andy
On Thu, Sep 15, 2011 at 3:41 PM, Hochhaus, Andrew
Does anyone have time to comment on this change?
On Tue, Sep 27, 2011 at 5:16 PM, Hochhaus, Andrew
Does anyone have time to review it?
Thanks,
-Andy
/** * Opera, Safari 3, and Internet Explorer 9 all support innerText but they * include text nodes in script and style tags. Not document-mode-dependent. */
Hi Garry,
Thanks for your feedback.
I attempted to recreate this example, but as best I can tell, the
On Thu, Apr 19, 2012 at 4:37 PM, Garry Boyer <gbo...@google.com> wrote:
> Take a look at browserfeature.js -- I added this comment clarifying it's
> specifically the user agent version, not the document mode, that is needed
> here.
presence of text node descendants in style elements depends on
documentMode (not browser mode). For a minimal example load this page
in IE9:
http://69.164.217.215/inner_text_force_ie8.htm
http://69.164.217.215/inner_text.htm
Am I missing something? If not, this seems to be an example of when
document mode is the correct detection mechanism (and points to a
possible subtle bug in closure-library).
Earlier in this thread, you stated:
rendering bug, document mode is the right thing. If you just want to
"""
Generally, I've found if you're deciding whether to work around a
know if a new feature is available, usually the browser versionCan you offer more context or an example when browser mode is the
provides more useful information.
"""
right way to detect if a feature is available?
> I tried switching to documentMode but it really broke.Can you point me to one or two cases that broke in specific so that I
can understand them?