Splitting interop support so `dart_support.js` is no longer required.

R=jakemac@google.com

Review URL: https://codereview.chromium.org//644163002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/web_components@41081 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3057a70..65aed82 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
   * Updated to platform version 0.4.2, internally a deprecated API was removed,
     hence the bump in the version number.
 
+  * split dart_support.js in two. dart_support.js only contains what is
+    necessary in order to use platform.js,
+    interop_support.js/interop_support.html can be imported separately when
+    providing Dart APIs for js custom elements.
+
 #### Pub version 0.8.0
   * Re-apply changes from 0.7.1+1 and also cherry pick 
     [efdbbc](https://github.com/polymer/CustomElements/commit/efdbbc) to fix
diff --git a/lib/dart_support.js b/lib/dart_support.js
index 7ce882c..3f712ef 100644
--- a/lib/dart_support.js
+++ b/lib/dart_support.js
@@ -66,123 +66,3 @@
     }
   });
 })();
-
-// Updates document.registerElement so Dart can see when Javascript custom
-// elements are created, and wrap them to provide a Dart friendly API.
-(function (doc) {
-  var upgraders = {};       // upgrader associated with a custom-tag.
-  var unpatchableTags = {}; // set of custom-tags that can't be patched.
-  var pendingElements = {}; // will upgrade when/if an upgrader is installed.
-  var upgradeOldElements = true;
-
-  var originalRegisterElement = doc.registerElement;
-  if (!originalRegisterElement) {
-    throw new Error('document.registerElement is not present.');
-  }
-
-  function reportError(name) {
-    console.error("Couldn't patch prototype to notify Dart when " + name +
-        " elements are created. This can be fixed by making the " +
-        "createdCallback in " + name + " a configurable property.");
-  }
-
-  function registerElement(name, options) {
-    var proto, extendsOption;
-    if (options !== undefined) {
-      proto = options.prototype;
-    } else {
-      proto = Object.create(HTMLElement.prototype);
-      options = {protoptype: proto};
-    }
-
-    var original = proto.createdCallback;
-    var newCallback = function() {
-      original.call(this);
-      var name = (this.getAttribute('is') || this.localName).toLowerCase();
-      var upgrader = upgraders[name];
-      if (upgrader) {
-        upgrader(this);
-      } else if (upgradeOldElements) {
-        // Save this element in case we can upgrade it later when an upgrader is
-        // registered.
-        var list = pendingElements[name];
-        if (!list) {
-          list = pendingElements[name] = [];
-        }
-        list.push(this);
-      }
-    };
-
-    var descriptor = Object.getOwnPropertyDescriptor(proto, 'createdCallback');
-    if (!descriptor || descriptor.writable) {
-      proto.createdCallback = newCallback;
-    } else if (descriptor.configurable) {
-      descriptor['value'] = newCallback;
-      Object.defineProperty(proto, 'createdCallback', descriptor);
-    } else {
-      unpatchableTags[name] = true;
-      if (upgraders[name]) reportError(name);
-    }
-    return originalRegisterElement.call(this, name, options);
-  }
-
-  function registerDartTypeUpgrader(name, upgrader) {
-    if (!upgrader) return;
-    name = name.toLowerCase();
-    var existing = upgraders[name];
-    if (existing) {
-      console.error('Already have a Dart type associated with ' + name);
-      return;
-    }
-    upgraders[name] = upgrader;
-    if (unpatchableTags[name]) reportError(name);
-    if (upgradeOldElements) {
-      // Upgrade elements that were created before the upgrader was registered.
-      var list = pendingElements[name];
-      if (list) {
-        for (var i = 0; i < list.length; i++) {
-          upgrader(list[i]);
-        }
-      }
-      delete pendingElements[name];
-    } else {
-      console.warn("Didn't expect more Dart types to be registered. '" + name
-          + "' elements that already exist in the page might not be wrapped.");
-    }
-  }
-
-  function onlyUpgradeNewElements() {
-    upgradeOldElements = false;
-    pendingElements = null;
-  }
-
-  // Native custom elements outside the app in Chrome have constructor
-  // names like "x-tag", which need to be translated to the DOM
-  // element they extend.  When using the shadow dom polyfill this is
-  // take care of above.
-  var ShadowDOMPolyfill = window.ShadowDOMPolyfill;
-  if (!ShadowDOMPolyfill) {
-    // dartNativeDispatchHooksTransformer is described on initHooks() in
-    // sdk/lib/_internal/lib/native_helper.dart.
-    if (typeof window.dartNativeDispatchHooksTransformer == 'undefined')
-    window.dartNativeDispatchHooksTransformer = [];
-
-    window.dartNativeDispatchHooksTransformer.push(function(hooks) {
-      var originalGetUnknownTag = hooks.getUnknownTag;
-      hooks.getUnknownTag = function(o, tag) {
-        if (/-/.test(tag)) {  // "x-tag"
-          var s = Object.prototype.toString.call(o);
-          var match = s.match(/^\[object ([A-Za-z]*Element)\]$/);
-          if (match) {
-            return match[1];
-	  }
-          return originalGetUnknownTag(o, tag);
-        }
-      };
-    });
-  }
-
-  doc._registerDartTypeUpgrader = registerDartTypeUpgrader;
-  doc._onlyUpgradeNewElements = onlyUpgradeNewElements;
-  doc.registerElement = registerElement;
-})(document);
diff --git a/lib/interop.dart b/lib/interop.dart
index de1ef2f..1766850 100644
--- a/lib/interop.dart
+++ b/lib/interop.dart
@@ -23,8 +23,8 @@
   if (!isSupported) {
     throw new UnsupportedError("Couldn't find "
         "`document._registerDartTypeUpgrader`. Please make sure that "
-        "`packages/web_components/dart_support.js` is loaded and available "
-        "before calling this function.");
+        "`packages/web_components/interop_support.html` is loaded and "
+        "available before calling this function.");
   }
 
   var upgrader = document.createElementUpgrader(
diff --git a/lib/interop_support.html b/lib/interop_support.html
new file mode 100644
index 0000000..469510c
--- /dev/null
+++ b/lib/interop_support.html
@@ -0,0 +1,6 @@
+<!--
+ Copyright 2014 The Dart project authors. All rights reserved.
+ Use of this source code is governed by a BSD-style
+ license that can be found in the LICENSE file.
+-->
+<script src="interop_support.js"></script>
diff --git a/lib/interop_support.js b/lib/interop_support.js
new file mode 100644
index 0000000..790f828
--- /dev/null
+++ b/lib/interop_support.js
@@ -0,0 +1,126 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Updates document.registerElement so Dart can see when Javascript custom
+// elements are created, and wrap them to provide a Dart friendly API.
+(function (doc) {
+  if (window._dart_register_element_interop_support) return;
+  window._dart_register_element_interop_support = true;
+
+  var upgraders = {};       // upgrader associated with a custom-tag.
+  var unpatchableTags = {}; // set of custom-tags that can't be patched.
+  var pendingElements = {}; // will upgrade when/if an upgrader is installed.
+  var upgradeOldElements = true;
+
+  var originalRegisterElement = doc.registerElement;
+  if (!originalRegisterElement) {
+    throw new Error('document.registerElement is not present.');
+  }
+
+  function reportError(name) {
+    console.error("Couldn't patch prototype to notify Dart when " + name +
+        " elements are created. This can be fixed by making the " +
+        "createdCallback in " + name + " a configurable property.");
+  }
+
+  function registerElement(name, options) {
+    var proto, extendsOption;
+    if (options !== undefined) {
+      proto = options.prototype;
+    } else {
+      proto = Object.create(HTMLElement.prototype);
+      options = {protoptype: proto};
+    }
+
+    var original = proto.createdCallback;
+    var newCallback = function() {
+      original.call(this);
+      var name = (this.getAttribute('is') || this.localName).toLowerCase();
+      var upgrader = upgraders[name];
+      if (upgrader) {
+        upgrader(this);
+      } else if (upgradeOldElements) {
+        // Save this element in case we can upgrade it later when an upgrader is
+        // registered.
+        var list = pendingElements[name];
+        if (!list) {
+          list = pendingElements[name] = [];
+        }
+        list.push(this);
+      }
+    };
+
+    var descriptor = Object.getOwnPropertyDescriptor(proto, 'createdCallback');
+    if (!descriptor || descriptor.writable) {
+      proto.createdCallback = newCallback;
+    } else if (descriptor.configurable) {
+      descriptor['value'] = newCallback;
+      Object.defineProperty(proto, 'createdCallback', descriptor);
+    } else {
+      unpatchableTags[name] = true;
+      if (upgraders[name]) reportError(name);
+    }
+    return originalRegisterElement.call(this, name, options);
+  }
+
+  function registerDartTypeUpgrader(name, upgrader) {
+    if (!upgrader) return;
+    name = name.toLowerCase();
+    var existing = upgraders[name];
+    if (existing) {
+      console.error('Already have a Dart type associated with ' + name);
+      return;
+    }
+    upgraders[name] = upgrader;
+    if (unpatchableTags[name]) reportError(name);
+    if (upgradeOldElements) {
+      // Upgrade elements that were created before the upgrader was registered.
+      var list = pendingElements[name];
+      if (list) {
+        for (var i = 0; i < list.length; i++) {
+          upgrader(list[i]);
+        }
+      }
+      delete pendingElements[name];
+    } else {
+      console.warn("Didn't expect more Dart types to be registered. '" + name
+          + "' elements that already exist in the page might not be wrapped.");
+    }
+  }
+
+  function onlyUpgradeNewElements() {
+    upgradeOldElements = false;
+    pendingElements = null;
+  }
+
+  // Native custom elements outside the app in Chrome have constructor
+  // names like "x-tag", which need to be translated to the DOM
+  // element they extend.  When using the shadow dom polyfill this is
+  // taken care of in dart_support.js.
+  var ShadowDOMPolyfill = window.ShadowDOMPolyfill;
+  if (!ShadowDOMPolyfill) {
+    // dartNativeDispatchHooksTransformer is described on initHooks() in
+    // sdk/lib/_internal/lib/native_helper.dart.
+    if (typeof window.dartNativeDispatchHooksTransformer == 'undefined')
+    window.dartNativeDispatchHooksTransformer = [];
+
+    window.dartNativeDispatchHooksTransformer.push(function(hooks) {
+      var originalGetUnknownTag = hooks.getUnknownTag;
+      hooks.getUnknownTag = function(o, tag) {
+        if (/-/.test(tag)) {  // "x-tag"
+          var s = Object.prototype.toString.call(o);
+          var match = s.match(/^\[object ([A-Za-z]*Element)\]$/);
+          if (match) {
+            return match[1];
+          }
+          return originalGetUnknownTag(o, tag);
+        }
+      };
+    });
+  }
+
+  doc._registerDartTypeUpgrader = registerDartTypeUpgrader;
+  doc._onlyUpgradeNewElements = onlyUpgradeNewElements;
+  doc.registerElement = registerElement;
+})(document);
diff --git a/test/interop_test.html b/test/interop_test.html
index d49dcb9..289fe5c 100644
--- a/test/interop_test.html
+++ b/test/interop_test.html
@@ -11,6 +11,7 @@
      .unittest-error { background: #a11;}
   </style>
   <script src="/packages/web_components/platform.js"></script>
+  <link rel="import" href="/packages/web_components/interop_support.html">
   <script src="/packages/web_components/dart_support.js"></script>
 </head>
 <body>