How to link CSS(s) already linked to parent frame into child iframeusing javascript

S

Scott Sauyet

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));
    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." Or is
there a simple enhancement to this technique that would gracefully
handle such a scenario?

-- Scott

-- Scott
 
T

Thomas 'PointedEars' Lahn

Scott said:
---- s2.createTextNode(s1.cssText || s1.ownerNode.textContent));
++++ document.createTextNode(s1.cssText ||
s1.ownerNode.textContent));

Yes said:
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.


PointedEars
 
J

Jorge

I have a fair idea now why you are continually running into walls.

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,
 
J

Jorge

I have a fair idea now why you are continually running into walls.

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 ?

Oops, I see:

(...) 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,
 
S

Scott Sauyet

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 ?

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
 
R

Richard Cornford

On Jan 12, 3:20 pm, Scott Sauyet wrote:
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?

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.
 
S

Scott Sauyet

On Jan 12, 3:20 pm, Scott Sauyet wrote: [ ... ]
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?

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:-
[ ... ]

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
 
J

Jorge

On Jan 12, 3:20 pm, Scott Sauyet wrote: [ ... ]
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?
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:-
[ ... ]

Thank you very much.  This works well.  A new example is here:

   http://scott.sauyet.com/Javascript/Demo/2010-01-12b/

Yep. Clear as an unmuddied lake, Scott. As clear as an azure sky of
deepest summer. :)

Thank you very much.
 
J

Jorge

Thank you very much.

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 ?
 
D

David Mark

Jorge said:
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 ?

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.
 
J

Jorge

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 ?
 
D

David Mark

Jorge said:
Thanks David. Yes, my question might be reworded as *why* would it be
stupid to include them ?

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. :(
 
D

David Mark

Yoda said:
I still don't get it. Sorry. Could you please enlighten me ?

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.
 
J

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?

In what sense are imported stylesheets "less than" stylesheets
obtained/applied by a <link> or a <style> ?
 
D

David Mark

Jorge said:
In what sense are imported stylesheets "less than" stylesheets
obtained/applied by a <link> or a <style> ?

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!
 
J

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?

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 ?
 
D

David Mark

Jorge said:
Yes you've got to digg deep inside the collection hierarchy to access

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.
 
S

Scott Sauyet

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 ?

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top