Tuesday, April 16, 2013

Bugs. Web Bugs

‹prev | My Chain | next›

Some days it really sucks to be a web programmer.

(must… resist… urge… to wax poetic about Dart)

Today is one of those days. I have three different, weird little bugs in the ICE Code Editor. First, the embedded version is not showing code anymore. This seems a simple styling issue so I will work that last. Second, the side-by-side embedded version works, but displays oddly when loaded from cache. Third, the embedded version does not work at all in FireFox. I start with the last and work my way back.

The FireFox issue is that reading from the <script> tag is failing with the error:
Error: TypeError: this.script.innerText is undefined
Source File: http://localhost:3000/js/ice-embeded.js
Line: 45
This is an easy enough fix, because of course I should be using textContent instead of innerText (or innerHTML or text):
// Process the sourcecode from the `<script>` tag. This is ne...
Embedded.prototype.processSource = function() {
  return this.script.textContent.
    replace(/^-(\w+)(.*?)\s*\{([\s\S]+)-\}.*$/gm, "\n<$1$2>$3</$1>").
    replace(/^-(\w+)(.*)$/gm, "<$1$2></$1>").
    replace(/^\s+/, '').
    replace(/\s+$/, '');
Naturally, that is not the end of incompatible features: I replace insertAdjacentElement() with instertAdjacentHTML() elsewhere in the code. With that, I have the editor working in FireFox:

It still works in Chrome (since these DOM methods have better support everywhere).

That ended up being easier that I had thought. It was still good to get it done first since this bug would have affected the most potential readers

The next problem is a strange browser cache issue. Under certain circumstances, the preview pane ends up thinking that it is larger than it really is. The result is that the preview no longer fits in the preview area:

I never see this behavior when I first load the page or if I reload the page. I only see it if I return to the page with everything still in cache.

After a bit of investigation, I find that the <div> element that contains the preview layer in the page is not the problem. Nor is the <iframe> that is embedded into that the preview <div>. Both are the correct size (a little more than 600px wide). The problem is only the <canvas> tag that should fit the entire <iframe>. Instead of the 600px width that it should be, it is the size of the viewport:

Interestingly, setting a timeout has no effect. Even if I wait for a full second before displaying the renderer, I still see the same thing. Eventually, I track this down, not to the ICE Code Editor, but to the code that I am setting inside ICE:

For some odd reason, the innerWidth value is wrong for the frame that holds the preview. The code uses this width to set the size of the canvas and mayhem ensues. Actually, this is ultimately an ICE issue. I had been setting the <iframe> width and height to 100%, meaning 100% of the parent tag. But it seems that, when much of the code is coming from cache, Chrome miscalculates the width of the parent tag as being 100% of the viewport.

Anyhow, I have access to the preview element, so I can set the iframe element's width and height to the same value as the preview:
// Getter for the current preview iframe element. If no preview iframe
// exists, a new one will be created.
Editor.prototype.createPreviewIframe = function() {
  var iframe = document.createElement( 'iframe' );
  iframe.width = this.preview_el.clientWidth;
  iframe.height = this.preview_el.clientHeight;
  iframe.style.border = '0';
  this.preview_el.appendChild( iframe );

  return iframe;
Problem solved.

Day #724

No comments:

Post a Comment