0

I am using Google Closure and and I am trying to make a Chrome packaged app.

My call to goog.require causes an error:

Uncaught document.write() is not available in packaged apps.

The culprit is in base.js

goog.writeScriptTag_ = function(src) {
  if (goog.inHtmlDocument_()) {
    var doc = goog.global.document;

    // If the user tries to require a new symbol after document load,
    // something has gone terribly wrong. Doing a document.write would
    // wipe out the page.
    if (doc.readyState == 'complete') {
      // Certain test frameworks load base.js multiple times, which tries
      // to write deps.js each time. If that happens, just fail silently.
      // These frameworks wipe the page between each load of base.js, so this
      // is OK.
      var isDeps = /\bdeps.js$/.test(src);
      if (isDeps) {
        return false;
      } else {
        throw Error('Cannot write "' + src + '" after document load');
      }
    }

    doc.write(
        '<script type="text/javascript" src="' + src + '"></' + 'script>');
    return true;
  } else {
    return false;
  }
};

Is Google Closure incompatible with Google Chrome packaged apps? Closure has so many benefits for large Javascript projects it is really hard to give up such a valuable tool.

EDIT: I know that if the Closure Compiler is used in addition to the Closure libraries, there is no goog.require, but that clearly makes development and debugging much more difficult.

Kinlan
  • 16,315
  • 5
  • 56
  • 88
Paul Draper
  • 78,542
  • 46
  • 206
  • 285

1 Answers1

1

Closure Dev Mode & Chrome Packaged App -- "document.write() is not available in the sandbox of packaged apps"

As long as you run it uncompiled or don't compile with advanced compilation you have to re write the doc.write with document.createElement("script");

So replace te doc.write line with:

  var script = document.createElement('script');
  script.src = src;
  script.type = 'text/javascript';
  goog.global.document.getElementsByTagName("head")[0].appendChild(script);
  return true;

Advance compiled code should not need this as it puts all the used code together in one file.

Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
  • It this guaranteed to work? It seemed that when I tried this for dynamically loading Javascript on another project the scripts executed asynchronously in indeterminate order. – Paul Draper Jun 06 '13 at 14:49
  • I confirmed this observation. It may work for small files, or something else, but the javascript is loaded and evaluated non-sequentially. – Paul Draper Jun 06 '13 at 17:36
  • That must be the reason google uses document.write. You could try calcdeps.py and create – HMR Jun 06 '13 at 23:58
  • Yes, and this is what I wound up doing. It's not a pretty solution, and I hope eventually there is a better one, but calcdeps and inserting into the html works. – Paul Draper Jun 08 '13 at 05:22