nmbug.js: Third attempt at robustly loading the dialog polyfill
authorW. Trevor King <wking@tremily.us>
Mon, 22 Sep 2014 02:46:27 +0000 (19:46 -0700)
committerW. Trevor King <wking@tremily.us>
Mon, 22 Sep 2014 14:08:51 +0000 (07:08 -0700)
It seems like onload is firing after the browser finishes *fetching*
the target, but before it finishes *parsing* the target.  That's
giving me ReferenceErrors for dialogPolyfill.  This new approach
attacks that directly, and just spins until dialogPolyfill has been
setup (with a bonus wait before using it, just for good measure).  Not
very pretty, but more robust ;).

I also simplified the check that avoids reloading the polyfills.
Instead of looking at the document's head, I just check for
dialogPolyfill.  If we've got native dialogs or dialogPolyfill, don't
bother (re)loading the polyfill scripts.

nmbug.js

index ec33a362ea6dad0f12b51ece367900e57803e3c2..417ce4200c95df553bb8799a98deb7c84d33a269 100644 (file)
--- a/nmbug.js
+++ b/nmbug.js
@@ -52,68 +52,48 @@ nmbug = {
                request.send();
        },
        _edit_tags: function (frame, available_tags, message_id, tags) {
-               if (frame.document.createElement('dialog').show) {
+               var have_dialog_polyfill;
+               try {
+                       have_dialog_polyfill = frame.dialogPolyfill !== undefined;
+               } catch (error) {
+                       if (error.name == 'ReferenceError') {
+                               have_dialog_polyfill = false;
+                       }
+               }
+               if (frame.document.createElement('dialog').show || have_dialog_polyfill) {
                        this._x_edit_tags(frame, available_tags, message_id, tags);
                } else {
-                       var _this = this;
-                       var needed = [];
+                       var script = frame.document.createElement('script');
+                       script.type = 'text/javascript';
+                       script.src = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.js';
+                       script.async = false;
+                       console.log('nmbug: loading dialog-polyfill.js');
+                       frame.document.head.appendChild(script);
 
-                       function basename (element) {
-                               var url;
-                               if (!element.tagName) {
-                                       return;
-                               } else if (element.tagName.toLowerCase() == 'script') {
-                                       url = element.src;
-                               } else if (element.tagName.toLowerCase() == 'link') {
-                                       url = element.href;
-                               } else {
-                                       return;
-                               }
-                               return url.replace(/.*\//, '');
-                       }
-
-                       function onload () {
-                               var name = basename(this);
-                               console.log('nmbug: loaded ' + name, this);
-                               var index = needed.indexOf(name);
-                               if (index !== -1) {
-                                       needed.splice(index, 1);
-                               }
-                               if (needed.length == 0) {
-                                       _this._x_edit_tags(frame, available_tags, message_id, tags);
-                               }
-                       }
+                       var link = frame.document.createElement('link');
+                       link.rel = 'stylesheet';
+                       link.type = 'text/css';
+                       link.href = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.css';
+                       link.async = false;
+                       console.log('nmbug: loading dialog-polyfill.css');
+                       frame.document.head.appendChild(link);
 
-                       function has_header (name) {
-                               var nodes = frame.document.head.childNodes;
-                               for (var i = 0; i < nodes.length; i++) {
-                                       if (basename(nodes[i]) == name) {
-                                               return true;
+                       var _this = this;
+                       function edit_tags_after_dialog_polyfill () {
+                               try {
+                                       have_dialog_polyfill = frame.dialogPolyfill !== undefined;
+                                       console.log('have dialogPolyfill');
+                                       window.setTimeout(
+                                                       _this._x_edit_tags.bind(_this), 200,
+                                                       frame, available_tags, message_id, tags);
+                               } catch (error) {
+                                       if (error.name == 'ReferenceError') {
+                                               console.log('waiting for dialogPolyfill');
+                                               window.setTimeout(edit_tags_after_dialog_polyfill, 200);
                                        }
                                }
-                               return false;
-                       }
-
-                       if (!has_header('dialog-polyfill.js')) {
-                               needed.push('dialog-polyfill.js');
-                               var script = frame.document.createElement('script');
-                               script.type = 'text/javascript';
-                               script.src = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.js';
-                               script.onload = onload;
-                               console.log('nmbug: loading dialog-polyfill.js');
-                               frame.document.head.appendChild(script);
-                       }
-
-                       if (!has_header('dialog-polyfill.css')) {
-                               needed.push('dialog-polyfill.css');
-                               var link = frame.document.createElement('link');
-                               link.rel = 'stylesheet';
-                               link.type = 'text/css';
-                               link.href = nmbug_server + '/static/dialog-polyfill/dialog-polyfill.css';
-                               link.onload = onload;
-                               console.log('nmbug: loading dialog-polyfill.css');
-                               frame.document.head.appendChild(link);
                        }
+                       edit_tags_after_dialog_polyfill();
                }
        },
        _x_edit_tags: function (frame, available_tags, message_id, tags) {