@@ -76,6 +76,49 @@ class Interface {
7676 if ( global && ! global . rhs ) {
7777 throw new Error ( `[Global] must take an identifier or an identifier list in interface ${ this . name } ` ) ;
7878 }
79+
80+ const exposed = utils . getExtAttr ( this . idl . extAttrs , "Exposed" ) ;
81+ if ( exposed ) {
82+ if ( ! exposed . rhs || ( exposed . rhs . type !== "identifier" && exposed . rhs . type !== "identifier-list" ) ) {
83+ throw new Error ( `[Exposed] must take an identifier or an identifier list in interface ${ this . name } ` ) ;
84+ }
85+
86+ if ( exposed . rhs . type === "identifier" ) {
87+ this . exposed = new Set ( [ exposed . rhs . value ] ) ;
88+ } else {
89+ this . exposed = new Set ( exposed . rhs . value . map ( token => token . value ) ) ;
90+ }
91+ } else {
92+ this . exposed = new Set ( ) ;
93+ }
94+
95+ if ( ! exposed && ! utils . getExtAttr ( this . idl . extAttrs , "NoInterfaceObject" ) ) {
96+ throw new Error ( `Interface ${ this . name } has neither [Exposed] nor [NoInterfaceObject]` ) ;
97+ }
98+
99+ const legacyWindowAlias = utils . getExtAttr ( this . idl . extAttrs , "LegacyWindowAlias" ) ;
100+ if ( legacyWindowAlias ) {
101+ if ( utils . getExtAttr ( this . idl . extAttrs , "NoInterfaceObject" ) ) {
102+ throw new Error ( `Interface ${ this . name } has [LegacyWindowAlias] and [NoInterfaceObject]` ) ;
103+ }
104+
105+ if ( ! this . exposed . has ( "Window" ) ) {
106+ throw new Error ( `Interface ${ this . name } has [LegacyWindowAlias] without [Exposed=Window]` ) ;
107+ }
108+
109+ if ( ! legacyWindowAlias . rhs ||
110+ ( legacyWindowAlias . rhs . type !== "identifier" && legacyWindowAlias . rhs . type !== "identifier-list" ) ) {
111+ throw new Error ( `[LegacyWindowAlias] must take an identifier or an identifier list in interface ${ this . name } ` ) ;
112+ }
113+
114+ if ( legacyWindowAlias . rhs . type === "identifier" ) {
115+ this . legacyWindowAliases = new Set ( [ legacyWindowAlias . rhs . value ] ) ;
116+ } else {
117+ this . legacyWindowAliases = new Set ( legacyWindowAlias . rhs . value . map ( token => token . value ) ) ;
118+ }
119+ } else {
120+ this . legacyWindowAliases = null ;
121+ }
79122 }
80123
81124 // whence is either "instance" or "prototype"
@@ -1420,7 +1463,7 @@ class Interface {
14201463 const { idl, name } = this ;
14211464
14221465 this . str += `
1423- exports.install = function install (globalObject) {
1466+ exports.install = (globalObject, globalName) => {
14241467 ` ;
14251468
14261469 if ( idl . inheritance ) {
@@ -1444,12 +1487,39 @@ class Interface {
14441487 globalObject[ctorRegistrySymbol] = Object.create(null);
14451488 }
14461489 globalObject[ctorRegistrySymbol][interfaceName] = ${ name } ;
1490+ ` ;
14471491
1492+ if ( ! utils . getExtAttr ( this . idl . extAttrs , "NoInterfaceObject" ) ) {
1493+ this . str += `
14481494 Object.defineProperty(globalObject, interfaceName, {
14491495 configurable: true,
14501496 writable: true,
14511497 value: ${ name }
14521498 });
1499+ ` ;
1500+
1501+ if ( this . legacyWindowAliases ) {
1502+ this . str += `
1503+ if (globalName === "Window") {
1504+ ` ;
1505+
1506+ for ( const legacyWindowAlias of this . legacyWindowAliases ) {
1507+ this . str += `
1508+ Object.defineProperty(globalObject, "${ legacyWindowAlias } ", {
1509+ configurable: true,
1510+ writable: true,
1511+ value: ${ name }
1512+ });
1513+ ` ;
1514+ }
1515+
1516+ this . str += `
1517+ }
1518+ ` ;
1519+ }
1520+ }
1521+
1522+ this . str += `
14531523 };
14541524 ` ;
14551525 }
0 commit comments