I've a particular requirement in which I need to link stylesheets
already included in a parent html. In that HTML file, another iframe
is being on the fly and I need to link same stylesheets into the child
iframe. I can't link those stylesheets individually into the child
iframe because in the parent frame it is being included using an HTMLF
file (using java include directive).
I don't want to hardcode names of the individual stylesheets (as I'm
currently doing) in the child frame,
So, the options are
1.) Dynamically check the stylesheets linked to the parent frame and
link them to child frame
OR
2.) Need a way to include an HTMLF file using javascript.
which is sometimes disabled. And then your "page" will be totally stuffed
up.
Include the CSS in each page referenced by an iframe, server side.
For this case, you can assume that javascript will always be enabled.
I can't use server side include as the child iframe is being built on
the fly using a javascript function.
You can start with the document.styleSheets array in the parent
frame. But this is more difficult than you might like, because of
even greater than usual inconsistencies between browsers. Or perhaps
you can just list all the LINK elements with type="stylesheet" and all
the STYLE elements, copying them to the child frame. This certainly
sounds doable.
-- Scott
I need to bother about IE7 onwards only. Ok, I'll try copying the LINK
elements having type stylesheets into the child iframe, to see if it
helps.
Thanks for your help.
> prabhjot singh wrote:
>> "rf" <r...@z.invalid> wrote:
>>> Include the CSS in each page referenced by an iframe, server side.
>> For this case, you can assume that javascript will always be enabled.
>> I can't use server side include as the child iframe is being built on
>> the fly using a javascript function.
>
> You can start with the document.styleSheets array in the parent
> frame.
It is _not_ an array, but a StyleSheetList implementation (more or less).
<http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-
StyleSheet-DocumentStyle>
> But this is more difficult than you might like, because of
> even greater than usual inconsistencies between browsers.
The only known inconsistency is that MSHTML provides the `rules' property
instead of the standards-compliant `cssRules' property, which can be easily
feature-tested for.
<http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleSheet>
<http://msdn.microsoft.com/en-us/library/ms531199%28VS.85%29.aspx>
> Or perhaps you can just list all the LINK elements with type="stylesheet"
> and all the STYLE elements, copying them to the child frame. This
> certainly sounds doable.
It would additionally require calling an elements matcher capable of
recognizing the "stylesheet" word in the attribute value, though.
PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee
>> But this is more difficult than you might like, because of
>> even greater than usual inconsistencies between browsers.
>
> The only known inconsistency is that MSHTML provides the `rules' property
> instead of the standards-compliant `cssRules' property, which can be easily
> feature-tested for.
I was assuming that the OP would then go on to use the rules in the
style sheet, and then run into the addRule/insertRule differences as
well, especially the bit about IE's version taking separate strings
for the selector and the style, whereas FF and others put them into a
single string. Or that the OP might run into some of the oddities of
cssText.
>> Or perhaps you can just list all the LINK elements with type="stylesheet"
>> and all the STYLE elements, copying them to the child frame. This
>> certainly sounds doable.
>
> It would additionally require calling an elements matcher capable of
> recognizing the "stylesheet" word in the attribute value, though.
Well yes, that seems obvious, or are you talking also about "alternate
stylesheet" and such?
-- Scott
> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> But this is more difficult than you might like, because of
>>> even greater than usual inconsistencies between browsers.
>>
>> The only known inconsistency is that MSHTML provides the `rules'
>> property instead of the standards-compliant `cssRules' property,
>> which can be easily feature-tested for.
>
> I was assuming that the OP would then go on to use the rules in the
> style sheet, and then run into the addRule/insertRule differences as
> well, especially the bit about IE's version taking separate strings
> for the selector and the style, whereas FF and others put them into
> a single string. Or that the OP might run into some of the oddities
> of cssText.
What are you talking about? One iterates over the `styleSheets' list and
where there is a non-empty `href' property value one adds the corresponding
LINK element to the target document, perhaps adapting the path.
>>> Or perhaps you can just list all the LINK elements with
>>> type="stylesheet" and all the STYLE elements, copying them to the child
>>> frame. This certainly sounds doable.
>>
>> It would additionally require calling an elements matcher capable of
>> recognizing the "stylesheet" word in the attribute value, though.
>
> Well yes, that seems obvious, or are you talking also about "alternate
> stylesheet" and such?
Exactly.
PointedEars
--
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
-- Richard Cornford, cljs, <cife6q$253$1$8300...@news.demon.co.uk> (2004)
This was what I was suggesting by using the LINK elements in the
original document.
The technique mentioned above accounts for STYLE elements as well. I
don't know if they are necessary to the OP, but that's why I gave at
least an option for it, saying that it's fairly tricky to use.
-- Scott
> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> Scott Sauyet wrote:
>>>>> But this is more difficult than you might like, because of
>>>>> even greater than usual inconsistencies between browsers.
>>>> The only known inconsistency is that MSHTML provides the `rules'
>>>> property instead of the standards-compliant `cssRules' property,
>>>> which can be easily feature-tested for.
>>> I was assuming that the OP would then go on to use the rules in the
>>> style sheet, and then run into the addRule/insertRule differences as
>>> well, especially the bit about IE's version taking separate strings
>>> for the selector and the style, whereas FF and others put them into
>>> a single string. Or that the OP might run into some of the oddities
>>> of cssText.
>> What are you talking about? One iterates over the `styleSheets' list
>> and where there is a non-empty `href' property value one adds the
>> corresponding LINK element to the target document, perhaps adapting the
>> path.
>
> This was what I was suggesting by using the LINK elements in the
> original document.
>
> The technique mentioned above accounts for STYLE elements as well.
True. This would allow for considering @import-ed stylesheets as well.
> I don't know if they are necessary to the OP, but that's why I gave at
> least an option for it, saying that it's fairly tricky to use.
But you are wrong. It is not always necessary to iterate over rules.
Anyhow, you will, hopefully, agree that it is generally more efficient to
filter an existing list of objects than one that needs to be created first,
especially when at least one method call and word matching is involved with
the latter.
>> I don't know if they are necessary to the OP, but that's why I gave at
>> least an option for it, saying that it's fairly tricky to use.
>
> But you are wrong. It is not always necessary to iterate over rules.
No, not always. But when it is necessary, the code is still rather
ugly. This is all I was saying.
> Anyhow, you will, hopefully, agree that it is generally more efficient to
> filter an existing list of objects than one that needs to be created first,
> especially when at least one method call and word matching is involved with
> the latter.
Absolutely. However, run-time efficiency is not always high on my
priority list. I usually only bother looking for this sort of
optimizations if I've profiled some slow code and found the sections
causing the bottlenecks.
To help the OP, would the following be a reasonable algorithm?:
iterate over document.styleSheets, and for each sheet:
if the sheet has href, create a LINK element with that href
otherwise, create a STYLE element with contents copied from
the sheet?
I think there might be additional complexities if any of the sheets
have imports, as the algorithm would probably need to be recursive,
but the OP may not need to deal with that.
-- Scott
> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> I don't know if they are necessary to the OP, but that's why I gave at
>>> least an option for it, saying that it's fairly tricky to use.
>> But you are wrong. It is not always necessary to iterate over rules.
>
> No, not always. But when it is necessary, the code is still rather
> ugly. This is all I was saying.
Reviewing this, in this case it is not even necessary if you want to
consider @import rules.
>> Anyhow, you will, hopefully, agree that it is generally more efficient
>> to filter an existing list of objects than one that needs to be created
>> first, especially when at least one method call and word matching is
>> involved with the latter.
>
> Absolutely. However, run-time efficiency is not always high on my
> priority list. I usually only bother looking for this sort of
> optimizations if I've profiled some slow code and found the sections
> causing the bottlenecks.
Apply KISS then. A list of stylesheets is available, why reinvent the
wheel?
> To help the OP, would the following be a reasonable algorithm?:
>
> iterate over document.styleSheets, and for each sheet:
> if the sheet has href, create a LINK element with that href
> otherwise, create a STYLE element with contents copied from
> the sheet?
Roughly, yes.
>>> Anyhow, you will, hopefully, agree that it is generally more efficient
>>> to filter an existing list of objects than one that needs to be created
>>> first, especially when at least one method call and word matching is
>>> involved with the latter.
>
>> Absolutely. However, run-time efficiency is not always high on my
>> priority list. I usually only bother looking for this sort of
>> optimizations if I've profiled some slow code and found the sections
>> causing the bottlenecks.
>
> Apply KISS then. A list of stylesheets is available, why reinvent the
> wheel?
Yes, if this works to get everything the OP needs and is as simple as
you imply, it's clearly the best bet.
>> To help the OP, would the following be a reasonable algorithm?:
>
>> iterate over document.styleSheets, and for each sheet:
>> if the sheet has href, create a LINK element with that href
>> otherwise, create a STYLE element with contents copied from
>> the sheet?
>
> Roughly, yes.
I'm probably missing something obvious, but I don't know of a simple
cross-browser technique to copy the content of one stylesheet into a
new STYLE element. Obviously in IE, we can just copy in
styleSheet.cssText. But I don't think the other browsers support
cssText on the whole sheet, just on the individual rules. Is there
some simpler method to do this?
-- Scott
> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> To help the OP, would the following be a reasonable algorithm?:
>>> iterate over document.styleSheets, and for each sheet:
>>> if the sheet has href, create a LINK element with that href
>>> otherwise, create a STYLE element with contents copied from
>>> the sheet?
>> Roughly, yes.
>
> I'm probably missing something obvious, but I don't know of a simple
> cross-browser technique to copy the content of one stylesheet into a
> new STYLE element. Obviously in IE, we can just copy in
> styleSheet.cssText. But I don't think the other browsers support
> cssText on the whole sheet, just on the individual rules. Is there
> some simpler method to do this?
Suppose !styleSheet.href and you are right about `cssText', in a nutshell:
var
s1 = styleSheet,
s2 = document.createElement("style");
if (s1 && s2)
{
s2.type = "text/css";
s2.appendChild(
s2.createTextNode(s1.cssText || s1.ownerNode.textContent));
document.getElementsByTagName("head")[0].appendChild(s2);
}
The `ownerNode' attribute/property is provided by the StyleSheet interface
of W3C DOM Level 2 Style Sheets (and implemented at least by Geckos);
MSHTML has `owningElement.innerText' instead, but, as you say, `cssText'
appears to suffice.
<http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-
StyleSheet>
<http://msdn.microsoft.com/en-us/library/ms534316%28VS.85%29.aspx>
<http://msdn.microsoft.com/en-us/library/ms533698%28VS.85%29.aspx>
PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)
>> I'm probably missing something obvious, but I don't know of a simple
>> cross-browser technique to copy the content of one stylesheet into a
>> new STYLE element. Obviously in IE, we can just copy in
>> styleSheet.cssText. But I don't think the other browsers support
>> cssText on the whole sheet, just on the individual rules. Is there
>> some simpler method to do this?
>
> Suppose !styleSheet.href and you are right about `cssText', in a nutshell:
>
> var
> s1 = styleSheet,
> s2 = document.createElement("style");
>
> if (s1 && s2)
> {
> s2.type = "text/css";
> s2.appendChild(
> s2.createTextNode(s1.cssText || s1.ownerNode.textContent));
>
> document.getElementsByTagName("head")[0].appendChild(s2);
> }
Ahh, very nice. I hadn't run across ownerNode before. This is
clearly the simplest solution.
Thank you for taking the time to post it.
-- Scott
> Thomas 'PointedEars' Lahn wrote:
>> Scott Sauyet wrote:
>>> I'm probably missing something obvious, but I don't know of a simple
>>> cross-browser technique to copy the content of one stylesheet into a
>>> new STYLE element. Obviously in IE, we can just copy in
>>> styleSheet.cssText. But I don't think the other browsers support
>>> cssText on the whole sheet, just on the individual rules. Is there
>>> some simpler method to do this?
>>
>> Suppose !styleSheet.href and you are right about `cssText', in a
>> nutshell:
>>
>> var
>> s1 = styleSheet,
>> s2 = document.createElement("style");
>>
>> if (s1 && s2)
>> {
>> s2.type = "text/css";
>> s2.appendChild(
>> s2.createTextNode(s1.cssText || s1.ownerNode.textContent));
Should be document.createTextNode(...), of course.
>> document.getElementsByTagName("head")[0].appendChild(s2);
>> }
>
> Ahh, very nice. I hadn't run across ownerNode before. This is
> clearly the simplest solution.
>
> Thank you for taking the time to post it.
You are welcome.
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
"ownerNode of type Node, readonly (...) For style sheets that are
included by other style sheets, the value of this attribute is null."
"parentStyleSheet of type StyleSheet, readonly
For style sheet languages that support the concept of style sheet
inclusion, this attribute represents the including style sheet, if one
exists.(...)"
Therefore, me thinks:
IZ s1.ownerNode ?
YARLY
s1.ownerNode.textContent
NOWAI
s1.parentStyleSheet.ownerNode.textContent
KTHX
--
Jorge.
> Thomas 'PointedEars' Lahn wrote:
>> (...)
>> s2.createTextNode(s1.cssText || s1.ownerNode.textContent));
>> (...)
>
> "ownerNode of type Node, readonly (...) For style sheets that are
> included by other style sheets, the value of this attribute is null."
>
> "parentStyleSheet of type StyleSheet, readonly
> For style sheet languages that support the concept of style sheet
> inclusion, this attribute represents the including style sheet, if one
> exists.(...)"
>
> Therefore, me thinks:
>
> IZ s1.ownerNode ?
> YARLY
> s1.ownerNode.textContent
> NOWAI
> s1.parentStyleSheet.ownerNode.textContent
> KTHX
Think again.
PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$8300...@news.demon.co.uk>
Hmm, that would be the parent styleSheet not the child, therefore...
NOWAY
BTW WAZZUP ?
KTHX
Copy rule by rule ?
--
Jorge.
> Jorge wrote:
>> (...)
>> NOWAI
>> s1.parentStyleSheet.ownerNode.textContent
>> KTHX
>
> Hmm, that would be the parent styleSheet not the child, therefore...
>
> NOWAY
> BTW WAZZUP ?
> KTHX
>
> Copy rule by rule ?
I have a fair idea now why you are continually running into walls.
Another thought: if the iframe's src references a significantly
different path than the main page and the stylesheet in a STYLE
element contains relative URLS is there a simple way to deal with
them?
For example,
main document at http://example.com/path/
iframe document at http://example.com/path/subpath/
<style type="text/css">
@import "../css/fancy.css";
body {background: url("../images/myPic.png");}
</style>
I'm wondering if the best answer is simply "Don't do that." Or is
there a simple enhancement to this technique that would gracefully
handle such a scenario?
-- Scott
-- Scott
> Thomas 'PointedEars' Lahn wrote:
>> Suppose !styleSheet.href and you are right about `cssText', in a
>> nutshell:
>>
>> var
>> s1 = styleSheet,
>> s2 = document.createElement("style");
>>
>> if (s1 && s2)
>> {
>> s2.type = "text/css";
>> s2.appendChild(
> ---- s2.createTextNode(s1.cssText || s1.ownerNode.textContent));
> ++++ document.createTextNode(s1.cssText ||
> s1.ownerNode.textContent));
Yes, as I wrote in <news:9951811.d...@PointedEars.de>.
>> document.getElementsByTagName("head")[0].appendChild(s2);
>> }
>
> Another thought: if the iframe's src references a significantly
> different path than the main page and the stylesheet in a STYLE
> element contains relative URLS is there a simple way to deal with
> them?
>
> For example,
>
> main document at http://example.com/path/
> iframe document at http://example.com/path/subpath/
>
> <style type="text/css">
> @import "../css/fancy.css";
> body {background: url("../images/myPic.png");}
> </style>
>
> I'm wondering if the best answer is simply "Don't do that."
Yes, don't do that. To avoid confusion and path dependency, always refer
relative to the document root (`/') in stylesheets. (IMHO, a local
development server is a must anyway.)
> Or is there a simple enhancement to this technique that would gracefully
> handle such a scenario?
Depends on what you call simple and what the scenario is (your example is
unclear). It is certainly possible to compute the absolute path for a
relative one.
Ok. Here: http://jorgechamorro.com/cljs/091/
we've got 4 stylesheets:
1.- "a.css" in a <link> tag
2.- "b.css" imported from a rule @import in a.css
3.- into a <style> tag.
2.- "d.css" imported from a rule @import in the <style> stylesheet
.ownerNode.textContent is "" for #1 (document.styleSheets[0]), and
neither b.css nor d.css are in the document.styleSheets collection...
therefore you've got to walk the rules of the #1 stylesheet, or ...
¿ what else could you do instead ?
TIA,
--
Jorge.
Oops, I see:
On Jan 11, 3:29 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
> (...) One iterates over the `styleSheets' list and
> where there is a non-empty `href' property value one adds the corresponding
> LINK element to the target document, perhaps adapting the path.
IZ stylesheet.href ?
YARLY
BTW create <link> element and set href ~= stylesheet.href
NOWAI
BTW create <style> element and set .textContent =
stylesheet.ownerNode.textContent
KTHX
Yes ?
TIA,
--
Jorge.
> Oops, I see:
>
> On Jan 11, 3:29 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
> wrote:
>> (...) One iterates over the `styleSheets' list and
>> where there is a non-empty `href' property value one adds the
>> corresponding LINK element to the target document, perhaps adapting the
>> path.
>
> IZ stylesheet.href ?
> YARLY
> BTW create <link> element and set href ~= stylesheet.href
> NOWAI
> BTW create <style> element and set .textContent =
> stylesheet.ownerNode.textContent
> KTHX
>
> Yes ?
<http://www.catb.org/~esr/faqs/smart-questions.html#writewell>
No, Thomas is correct here. Ignoring the question of relative URLs,
which will arise whether you walk the rules or copy the stylesheets
intact, this should copy the *text* that represents the import along
with the rest of the rule text. The browser will then request that
url in the linked document.
I modified your example here, using Thomas' code, modified to put the
elements in the document of the inner frame:
http://scott.sauyet.com/Javascript/Demo/2010-01-12a/
This has an error in IE which I haven't chased down. Anyone know why
IE reports an "Unexpected call to method or property access" on the
append child call for the style element?
-- Scott
In IE (from about version 5) elements have a boolean - canHaveChildren
- property, which is false for some types of elements, including
SCRIPT and STYLE elements. Elements with false - canHaveChildren -
properties cannot have children and so attempts to append children to
them throw exceptions. Obviously this condition is testable, so
changing relevant section of your function to:-
var s2 = frameDoc.createElement("style");
if (s1 && s2){
frameHead.appendChild(s2);
s2.type = "text/css";
if(
(typeof s2.canHaveChildren != 'boolean')||
(s2.canHaveChildren)
){
s2.appendChild(
frameDoc.createTextNode(
s1.cssText || s1.ownerNode.textContent
)
);
}else if(
(typeof s2.styleSheet == 'object')&&
(typeof s2.styleSheet.cssText == 'string')
){
s2.styleSheet.cssText = (
s1.cssText || s1.ownerNode.textContent
);
}
}
- seems to work OK with IE, and should not change anything for
browsers without - canHaveChildren - properties. Note, however, that
it was necessary to move the appending of the new STYLE element to the
HEAD to prior to any attempts to give it rules as otherwise IE either
has not fully set up the elements - styleSheet - object, or it is
fatally confused by trying to apply the rules to the owner document
(which is either non-existent or a document fragment at that point)
(the symptoms of failure prior to moving the point of appending the
element being a browser crash).
Richard.
Thank you very much. This works well. A new example is here:
http://scott.sauyet.com/Javascript/Demo/2010-01-12b/
I have no idea if the OP is still paying attention, but I think this
covers the original request pretty well.
-- Scott
Yep. Clear as an unmuddied lake, Scott. As clear as an azure sky of
deepest summer. :-)
Thank you very much.
--
Jorge.
BTW, there has to be a (good) reason for not including imported (by an
@import rule) stylesheets in the document.styleSheets collection.
Which one is it ?
--
Jorge.
Talking to yourself again Jorge? Judging from the context (a thank
you), it's hard to say, isn't it? You really have got me this time. :)
Which what is what? Do you mean what reason is there to not include
such style sheets in the styleSheets collection? Scientifically
speaking, because it would be stupid? It's another one of those
no-brainers (your specialty) near as I can tell.
Thanks David. Yes, my question might be reworded as *why* would it be
stupid to include them ?
--
Jorge.
Aren't you the inquisitive little sod today? Because it's a collection,
not a hierarchy. Think. And I hope you get a good grade on your
homework. :(
I still don't get it. Sorry. Could you please enlighten me ?
--
Jorge.
You certainly are sorry. :) What does the styleSheets collection
abstract? What is it typically used for? How could it possibly make
sense to include imports _inside_ the specified style sheets in this
collection?
Get a tutor, Jorge.
In what sense are imported stylesheets "less than" stylesheets
obtained/applied by a <link> or a <style> ?
--
Jorge.
Are you in the middle of a test or something? I'm looking at my quote
and I don't see "less than". I assume you mean one or more of the
former may be included in the latter. It follows that an abstraction
that would include the latter would have to be hierarchical. Clear?
Good luck, Jorge!
Yes you've got to digg deep inside the collection hierarchy to access
the imported ones, but an imported stylesheet is as stylesheet as any
other and equally important so ISTM that it would have made perfect
sense to have them all included at the same level in the collection of
styleSheet*s* of the document -regardless of its origin-. Or not ? And
if not, why ?
--
Jorge.
There is no "collection hierarchy". The document.styleSheets collection
is just that. But you are sort of on the right track. Why not just
read the manual and realize there are other abstractions for tracking
down imports.
http://msdn.microsoft.com/en-us/library/ms535871(VS.85).aspx
> the imported ones, but an imported stylesheet is as stylesheet as any
> other and equally important so ISTM that it would have made perfect
> sense to have them all included at the same level in the collection of
> styleSheet*s* of the document -regardless of its origin-. Or not ? And
> if not, why ?
Because it doesn't make any sense at all? If you can't visualize the
various abstractions and how your proposition would be tangling them up
for no practical reason, then I can't help you.
Well, there would be some oddities if you tried to flatten the list in
this manner. In almost every case I've ever seen of flattening a
hierarchy, the parent node is included before its children. But if
you did that here, the stylesheets would be in the wrong order for the
CSS cascade. CSS says that @import rules have to come first in the
stylesheet, and even if they're not properly placed, must be processed
before other rules in the sheet.
So if you have sheet a importing b followed by c importing d, the only
practical order of flattening them is the counter-intuitive [b, a, d,
c].
Besides, it would make much more difficult the sort of text-based
manipulation described earlier in this thread!
-- Scott
`typeof ... == "object"` is a somewhat unsafe existence test.
In Internet Explorer (at least 8), there's "Enable DOM Storage" option.
When that option is unchecked, `window.localStorage` evaluates to
`null`. Obviously, `typeof window.localStorage` then evaluates to
"object" (and `"localStorage" in window` evaluates to `true`, although
this is unrelated to example at hand).
It seems unlikely that IE is to ever introduce such possibility, but if
they do (or for whatever other reason), there's a chance of
`s2.styleSheet` being `null` and `typeof s2.styleSheet == 'object'`
evaluating to `true` in your example. In that case, following line would
result in an error.
Alternatives that come to mind:
// direct test for `null` value
if (typeof s2.styleSheet == "object" && s2.styleSheet !== null)
// boolean type conversion with typeof check before, to avoid type
converting "unknown" objects
if (typeof s2.styleSheet == "object" && s2.styleSheet)
// or just boolean type conversion (probably most unsafe one)
if (s2.styleSheet)
> (typeof s2.styleSheet.cssText == 'string')
> ){
> s2.styleSheet.cssText = (
> s1.cssText || s1.ownerNode.textContent
> );
> }
> }
[...]
--
kangax
In retrospect I was thinking that the order here probably was not a
good idea. That is, it probably would be better to assign the - type -
prior to appending the element to the DOM.
>> if(
>> (typeof s2.canHaveChildren != 'boolean')||
>> (s2.canHaveChildren)
>> ){
>> s2.appendChild(
>> frameDoc.createTextNode(
>> s1.cssText || s1.ownerNode.textContent
>> )
>> );
>> }else if(
>> (typeof s2.styleSheet == 'object')&&
>
> `typeof ... == "object"` is a somewhat unsafe existence test.
That would depend on what you know at the point of making the test. It
isn't a great test here but we know that it is not going to be
executed unless the environment in question either is a known IE 5+ or
is trying pretty hard to imitate one.
> In Internet Explorer (at least 8), there's "Enable DOM Storage"
> option. When that option is unchecked, `window.localStorage`
> evaluates to `null`. Obviously, `typeof window.localStorage`
> then evaluates to "object" (and `"localStorage" in window`
> evaluates to `true`, although this is unrelated to example
> at hand).
>
> It seems unlikely that IE is to ever introduce such possibility,
> but if they do (or for whatever other reason), there's a chance
> of `s2.styleSheet` being `null` and
> `typeof s2.styleSheet == 'object'` evaluating to `true` in your
> example. In that case, following line would result in an error.
Yes it would, unless in the meanwhile Microsoft change IE such that
the STYLE elements accept the setting of their content via the
insertion of a Text Node, in which case the value of - canHaveChildren
- changes to true and the browser never uses that second branch. That
seems quite a plausible change as people really do seem to like the
idea of creating SCRIPT and STYLE elements using DOM creation methods
(though I always note that it is TextNodes that get appended rather
than CDATASection Nodes getting any consideration (maybe a reflection
of the fact that there is not nearly as much XHTML in existence as the
impression that may be gained from looking at mark-up)).
> Alternatives that come to mind:
>
> // direct test for `null` value
> if (typeof s2.styleSheet == "object" && s2.styleSheet !== null)
>
> // boolean type conversion with typeof check before, to avoid type
> converting "unknown" objects
> if (typeof s2.styleSheet == "object" && s2.styleSheet)
>
> // or just boolean type conversion (probably most unsafe one)
> if (s2.styleSheet)
>
>> (typeof s2.styleSheet.cssText == 'string')
>> ){
<snip>
Yes, there are alternatives, all more complex. In a general sense I
don't like the need to repeat this test when the thing that is being
tested is not going to change while the document is loaded. Re-
designing the code so that it only tested once and branched to, say,
assign one of two STYLE Element content assigning functions for later
use would make more elaborate testing more appealing.
But there is minimal worth in devoting time to this code. It is, after
all (and as has been pointed out), solving the problem in the worst
way possible (or solving the wrong problem).
Richard.