Community
Participate
Working Groups
Firefox 9 1. In the Navigator, click on some editable file to open it in the editor. 2. Press Back. 3. You end up at the editor again. My history stack shows: - myfile.js - Coding <- Why is this here? When I visit it, it redirects me to myfile.js - Navigator This doesn't happen in Chrome.
*** Bug 365125 has been marked as a duplicate of this bug. ***
In Chrome(15), if you go to another page from editor and come back again, the editor shows nothing. Not sure if the root cause is the same.
Hi Mihai, In TextView we wait for the load event in the frame element to access the frameDocument and write the html using (1): frameDocument.open(); frameDocument.write(self._getFrameHTML()); frameDocument.close(); Then we wait for the load event in the frame window (when all the styles are done loading) to create all the other elements (clientDiv, etc). In Firefox, for some reason, if we write the html (1) during the event then the load event in of frame window never comes. The workaround is to use a setTimeout(). But that causes Firefox to add a state to history causing this bug. Change the code (1) to: log (window.history.length); frameDocument.open(); frameDocument.write(self._getFrameHTML()); frameDocument.close(); log (window.history.length); With the timeout the result is N and N+1 Without the timeout the result is N and N Do you have any idea how to fix that. See 365125, there the load event in the frame window does not happen (on chrome) after back navigation. My current thinking is to get rid of the load event in the frame window (not reliable) and replace with a timer that checks the document is ready to proceed creating the rest of the elements. It is a bit tricky, but I see an alternative.
(In reply to comment #3) > Hi Mihai, > > In TextView we wait for the load event in the frame element to access the > frameDocument and write the html using (1): > frameDocument.open(); > frameDocument.write(self._getFrameHTML()); > frameDocument.close(); > > Then we wait for the load event in the frame window (when all the styles are > done loading) to create all the other elements (clientDiv, etc). > > In Firefox, for some reason, if we write the html (1) during the event then the > load event in of frame window never comes. The workaround is to use a > setTimeout(). > > But that causes Firefox to add a state to history causing this bug. Change the > code (1) to: > log (window.history.length); > frameDocument.open(); > frameDocument.write(self._getFrameHTML()); > frameDocument.close(); > log (window.history.length); > > With the timeout the result is N and N+1 > Without the timeout the result is N and N > > Do you have any idea how to fix that. > > See 365125, there the load event in the frame window does not happen (on > chrome) after back navigation. > > My current thinking is to get rid of the load event in the frame window (not > reliable) and replace with a timer that checks the document is ready to proceed > creating the rest of the elements. It is a bit tricky, but I see an > alternative. The above is expected. document.open(), write() then close() is almost equivalent to a new navigation in the given window (in this case, the iframe). We recommend you avoid the use of document.open/write/close. If that is not possible, then coalesce the two loads. Do document.open()/write()/close() without waiting for the first blank iframe load. Only wait for the load event post-document.close(). I hope this helps!
(In reply to comment #4) > The above is expected. document.open(), write() then close() is almost > equivalent to a new navigation in the given window (in this case, the iframe). I understand, but note that this only happens on Firefox. > We recommend you avoid the use of document.open/write/close. I tried that, The three methods I know to create the elements into the iframe are: 1) setting iframe.src = something.html -Need to have an something.html around -The content of something.html varies depending on ua -Need add styles after load (this approach seems very problematic and I never investigate it much) 2) document.open/write/close - Messes up the navigation history 3) allow iframe to navigate to about:blank and add all elements to it - the page gets set to quirks mode (I do not know how to stop that) > If that is not possible, then coalesce the two loads. Do > document.open()/write()/close() without waiting for the first blank iframe > load. Only wait for the load event post-document.close(). That is how it worked in the past (almost). But it we don't wait for the first load event we will again have problems when the parent is not connect to the dom or the parent is hidden ((Bug 337160, Bug 349627).
(In reply to comment #5) > > We recommend you avoid the use of document.open/write/close. > > I tried that, The three methods I know to create the elements into the iframe > are: > 1) setting iframe.src = something.html > -Need to have an something.html around > -The content of something.html varies depending on ua > -Need add styles after load > (this approach seems very problematic and I never investigate it much) > > 2) document.open/write/close > - Messes up the navigation history > > 3) allow iframe to navigate to about:blank and add all elements to it > - the page gets set to quirks mode (I do not know how to stop that) > > > If that is not possible, then coalesce the two loads. Do > > document.open()/write()/close() without waiting for the first blank iframe > > load. Only wait for the load event post-document.close(). > > That is how it worked in the past (almost). But it we don't wait for the first > load event we will again have problems when the parent is not connect to the > dom or the parent is hidden ((Bug 337160, Bug 349627). Ugly situation. Since this history thing only affects Firefox, can you use a data URI only in Firefox? When you create the iframe do iframe.src = 'data:text/html,<!DOCTYPE HTML><p>loading'. Then when the load event happens, instead of document.open/write/close, in Firefox you can use document.documentElement.innerHTML. Ugly workaround, but it should work. Let me know if it does.
(In reply to comment #6) > Ugly situation. > > Since this history thing only affects Firefox, can you use a data URI only in > Firefox? When you create the iframe do iframe.src = 'data:text/html,<!DOCTYPE > HTML><p>loading'. > > Then when the load event happens, instead of document.open/write/close, in > Firefox you can use document.documentElement.innerHTML. > > Ugly workaround, but it should work. Let me know if it does. The data URI hack works only for Firefox, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=349627#c5 https://bugs.eclipse.org/bugs/show_bug.cgi?id=349627#c8 The problem is that I still need a fix for Bug 365125. In the past we didn't use data URI because we want the same code that works on all browsers (minimize special cases). If I use data URI to fix this problem (special case), I will need a second special case for bug 365125. I was really hoping to find one solution for both problems... Yesterday I spent most my time trying to use DOMContentLoaded and readystatechange to find a solution for these two problems but it didn't really go anywhere. Basically we can't rely on these events for iframe. Today I'll try using load event for the frame and a timer for load of the css (in place of the frame window load event).
(In reply to comment #7) > (In reply to comment #6) > > The data URI hack works only for Firefox, see Yeah, I made the suggestion knowing that this history issue happens only on Firefox... > Today I'll try using load event for the frame and a timer for load of the css > (in place of the frame window load event). Can you use a load event listener on the <link> element of the stylesheet?
I think I'm going to give in and use data URI (plus the timer to fix Bug 365125). To prevent firefox from changing the window.history I have to call document.write during the handling of the frame load event. But if I do that then I put the iframe in a funny state: - no load event of any kind is sent - frameDocument.readyState == interactive (never changes) - frameDocument.styleSheets has everything in it (although some styleSheets are not really loaded). My problem is to detected that all style sheets are loaded so the text view can be created. But given the above restrictions the only way it worked was to test if a specific style on a specific element is set. For testing I used the backgroundColor in the body, which I know is not set initially and I know it gets set to gray when textview.css is loaded. This is not really a solution cause if textview.css is not used or it is changed then the code breaks. any suggestions for this problem ?
(In reply to comment #8) > Can you use a load event listener on the <link> element of the stylesheet? In my tests only IE send load events for <link> elements.
(In reply to comment #9) > I think I'm going to give in and use data URI (plus the timer to fix Bug > 365125). > > To prevent firefox from changing the window.history I have to call > document.write during the handling of the frame load event. > But if I do that then I put the iframe in a funny state: > - no load event of any kind is sent > - frameDocument.readyState == interactive (never changes) > - frameDocument.styleSheets has everything in it (although some styleSheets are > not really loaded). > > My problem is to detected that all style sheets are loaded so the text view can > be created. But given the above restrictions the only way it worked was to test > if a specific style on a specific element is set. For testing I used the > backgroundColor in the body, which I know is not set initially and I know it > gets set to gray when textview.css is loaded. This is not really a solution > cause if textview.css is not used or it is changed then the code breaks. You could use a timer to check the frameDocument.styleSheets count, and also if linkElement.sheet.cssRules.length > 0. This should work.
(In reply to comment #11) > You could use a timer to check the frameDocument.styleSheets count, and also if > linkElement.sheet.cssRules.length > 0. This should work. Awesome, that worked. If I touch the cssRules of an element that is not loaded firefox throws an exceptions: uncaught exception: [Exception... "A parameter or an operation is not supported by the underlying object" code: "15" nsresult: "0x8053000f (NS_ERROR_DOM_INVALID_ACCESS_ERR)" location: "http://127.0.0.2:8080/orion/textview/textView.js Line: 3677"] This what the code looks like: this._createViewTimer = function() { if (this._clientDiv) { return; } var loaded = false; if (frameDocument.readyState === "complete") { loaded = true; } else if (frameDocument.readyState === "interactive") { var styleSheets = frameDocument.styleSheets; var index = 0; while (index < styleSheets.length) { var count = 0; try { count = styleSheets.item(index).cssRules.length; } catch (ex) {} if (count === 0) { break; } index++; } loaded = index === styleSheets.length; } if (loaded) { self._createContent(); } else { setTimeout(self._createViewTimer, 20); } }; setTimeout(this._createViewTimer, 5); The only place I think can cause this code to fail is the a empty css is added to the view... (didn't try) I also have the code that uses data URI, it is not bad. The only hack is the base element, instead of what was said in https://bugs.eclipse.org/bugs/show_bug.cgi?id=349627#c8 The final code was changed to: html.push("<base href='"); html.push(window.location.protocol); html.push(window.location.host); html.push(window.location.pathname); html.push("' />"); As far as performance is concerned, wouldn't data URI be faster for Firefox ?
(In reply to comment #12) > (In reply to comment #11) > > You could use a timer to check the frameDocument.styleSheets count, and also if > > linkElement.sheet.cssRules.length > 0. This should work. > > Awesome, that worked. > If I touch the cssRules of an element that is not loaded firefox throws an > exceptions: > uncaught exception: [Exception... "A parameter or an operation is not supported > by the underlying object" code: "15" nsresult: "0x8053000f > (NS_ERROR_DOM_INVALID_ACCESS_ERR)" location: > "http://127.0.0.2:8080/orion/textview/textView.js Line: 3677"] Yeah, that is to be expected. Great it worked! > This what the code looks like: > > this._createViewTimer = function() { > [...] Code looks good to me! > The only place I think can cause this code to fail is the a empty css is added > to the view... (didn't try) > > I also have the code that uses data URI, it is not bad. The only hack is the > base element, instead of what was said in > https://bugs.eclipse.org/bugs/show_bug.cgi?id=349627#c8 > The final code was changed to: > html.push("<base href='"); > html.push(window.location.protocol); > html.push(window.location.host); > html.push(window.location.pathname); > html.push("' />"); > > > As far as performance is concerned, wouldn't data URI be faster for Firefox ? I doubt there's much of a difference, testing would be needed. I suggest keeping the approach that works cross different browsers, that requires least amount of special-casing / maintenance.
Fixed http://git.eclipse.org/c/orion/org.eclipse.orion.client.git/commit/?id=d5f7a27f92d227a798dc7a80a00031fe1000b006 I tested the cases: sync parent connected;sync parent disconnected;sync parent hidden;async parent connected;async parent disconnected;async parent hidden; on IE, Firefox, Chrome, and Safari. The only problem was Firefox for parent hidden (sync and async) because in this case document.write is called from DOMAttrModified, therefore messes up the navigation history. I'm closing this bug for now since I don't think this case is affecting anyone, if it does I'm afraid we will have to use data URI to fix. Mihai, thank you very much for bouncing ideas with me, it was your suggestion that solved problem!
(In reply to comment #14) > Mihai, thank you very much for bouncing ideas with me, it was your suggestion > that solved problem! Ah, no worries. I'm glad things work now!
Created attachment 208286 [details] dataURI hacks just in case we need to get back to this, here is where I stopped (still having problems with base uri).
I found a problem with the current code, when the stylesheet is not loaded a invalid access expection is thrown when the css rules is read. After the stylesheet is loaded, a network security exception is throw if accesing the css rules from a stylesheet loaded from a different domain. This bug is causing the view to never load in firefox when external cssfiles are used.
(In reply to comment #17) > I found a problem with the current code, when the stylesheet is not loaded a > invalid access expection is thrown when the css rules is read. After the > stylesheet is loaded, a network security exception is throw if accesing the css > rules from a stylesheet loaded from a different domain. > This bug is causing the view to never load in firefox when external cssfiles > are used. Fix: http://git.eclipse.org/c/orion/org.eclipse.orion.client.git/commit/?id=38b8e6769c8eb9f32a50822c7ac1b1c9abb99c3b hopefully this the end for this novel...
We hit something similar with an older version of the Orion editor (0.2M2) when we bring it inside the RTC Web UI. Back button would clear up the editor instead of taking the whole page back. That is caused by the call to document.open / write / close in textView.js. In our case, we could workaround that pb by replacing document.open() with document.open("text/html", "replace"). This had no visible adverse effect on other web browsers (IE, Chrome). "replace" is described at http://www.w3schools.com/jsref/met_doc_open.asp . Here's a backpointer to our RTC work item https://jazz.net/jazz/resource/itemName/com.ibm.team.workitem.WorkItem/192126 Discussed this with Felipe and Silenio, and writing this down just as a sidenote of what has been done and discussed in this work item :-)
Thank you very much Chris! I like your code better than mine, see: http://git.eclipse.org/c/orion/org.eclipse.orion.client.git/commit/?id=301f0eb9e6530835b5368fa80c9d6c9f8a431737