@@ -73,8 +73,18 @@ class Interface {
7373
7474 const global = utils . getExtAttr ( this . idl . extAttrs , "Global" ) ;
7575 this . isGlobal = Boolean ( global ) ;
76- if ( global && ! global . rhs ) {
77- throw new Error ( `[Global] must take an identifier or an identifier list in interface ${ this . name } ` ) ;
76+ if ( global ) {
77+ if ( ! global . rhs || ( global . rhs . type !== "identifier" && global . rhs . type !== "identifier-list" ) ) {
78+ throw new Error ( `[Global] must take an identifier or an identifier list in interface ${ this . name } ` ) ;
79+ }
80+
81+ if ( global . rhs . type === "identifier" ) {
82+ this . globalNames = new Set ( [ global . rhs . value ] ) ;
83+ } else {
84+ this . globalNames = new Set ( global . rhs . value . map ( token => token . value ) ) ;
85+ }
86+ } else {
87+ this . globalNames = null ;
7888 }
7989
8090 const exposed = utils . getExtAttr ( this . idl . extAttrs , "Exposed" ) ;
@@ -1193,6 +1203,37 @@ class Interface {
11931203 return obj;
11941204 };
11951205 ` ;
1206+
1207+ if ( this . isGlobal ) {
1208+ const bundleEntry = this . requires . addRelative ( "./webidl2js-globals.js" ) ;
1209+
1210+ this . str += `
1211+ const globalNames = new Set([
1212+ ` ;
1213+
1214+ for ( const globalName of this . globalNames ) {
1215+ this . str += `"${ globalName } ",\n` ;
1216+ }
1217+
1218+ this . str += `
1219+ ]);
1220+
1221+ /**
1222+ * Initialises the passed obj as a new global.
1223+ *
1224+ * The obj is expected to contain all the global object properties
1225+ * as specified in the ECMAScript specification.
1226+ */
1227+ exports.setupGlobal = (obj, constructorArgs = [], privateData = {}` ;
1228+
1229+ this . str += `) => {
1230+ ${ bundleEntry } .setupGlobal(obj, globalNames);
1231+
1232+ Object.setPrototypeOf(obj, obj[interfaceName].prototype);
1233+ obj = exports.setup(obj, obj, constructorArgs, privateData);
1234+ };
1235+ ` ;
1236+ }
11961237 }
11971238
11981239 addConstructor ( ) {
@@ -1463,7 +1504,47 @@ class Interface {
14631504 const { idl, name } = this ;
14641505
14651506 this . str += `
1466- exports.install = (globalObject, globalName) => {
1507+ const exposed = new Set([
1508+ ` ;
1509+
1510+ for ( const globalName of this . exposed ) {
1511+ this . str += `"${ globalName } ",\n` ;
1512+ }
1513+
1514+ this . str += `
1515+ ]);
1516+
1517+ exports.install = (globalObject, globalNames) => {
1518+ let isExposed = false;
1519+ ` ;
1520+
1521+ if ( this . legacyWindowAliases ) {
1522+ this . str += "let isWindow = false;\n" ;
1523+ }
1524+
1525+ this . str += `
1526+ for (const globalName of globalNames) {
1527+ if (exposed.has(globalName)) {
1528+ isExposed = true;
1529+ ` ;
1530+
1531+ if ( this . legacyWindowAliases ) {
1532+ this . str += `
1533+ if (globalName === "Window") {
1534+ isWindow = true;
1535+ }
1536+ ` ;
1537+ } else {
1538+ this . str += "break;" ;
1539+ }
1540+
1541+ this . str += `
1542+ }
1543+ }
1544+
1545+ if (!isExposed) {
1546+ return;
1547+ }
14671548 ` ;
14681549
14691550 if ( idl . inheritance ) {
@@ -1500,7 +1581,7 @@ class Interface {
15001581
15011582 if ( this . legacyWindowAliases ) {
15021583 this . str += `
1503- if (globalName === "Window" ) {
1584+ if (isWindow ) {
15041585 ` ;
15051586
15061587 for ( const legacyWindowAlias of this . legacyWindowAliases ) {
0 commit comments