@@ -410,6 +410,86 @@ async function getImgData(blob: Blob): Promise<string> {
410410 } ) ;
411411}
412412
413+ /**
414+ * A setting for how to behave when an unsupported API is used. Updated via
415+ * `Ext-UnsupportedApiBehavior` message. It is a preference (see `preferences.service`)
416+ * and updated in the Preferences tab.
417+ */
418+ let unsupportedApiBehavior = 'off' ;
419+
420+ /**
421+ * Returns the names of every property of an object that is a function.
422+ * @param object An object with methods and optionally fields
423+ */
424+ function getMethodsOfObject ( object : Record < string , Function > ) {
425+ const properties = Object . getOwnPropertyNames ( object ) ;
426+ return properties . filter ( p => typeof object [ p ] === 'function' ) ;
427+ }
428+
429+ /**
430+ * Adds an Interactive Canvas warning to the specific method.
431+ * @param fn Function that should have additional warning
432+ * @param binder The object to which this function belongs
433+ */
434+ // eslint-disable-next-line
435+ function addMethodWarning ( fn : ( ...args : any [ ] ) => unknown , binder : Record < string , Function > ) {
436+ const boundFunction = fn . bind ( binder ) ;
437+ const methodName = fn . name ;
438+ const msg =
439+ `The method "${ methodName } " will not execute in an Interactive ` +
440+ 'Canvas environment. See ' +
441+ 'https://developers.google.com/assistant/interactivecanvas/web-apps#guidelines_and_restrictions ' +
442+ 'to learn more.' ;
443+ binder [ methodName ] = ( ...args : unknown [ ] ) => {
444+ if ( unsupportedApiBehavior === 'warn' ) {
445+ console . warn ( msg ) ;
446+ } else if ( unsupportedApiBehavior === 'error' ) {
447+ throw new Error ( msg ) ;
448+ }
449+ boundFunction ( ...args ) ;
450+ } ;
451+ }
452+
453+ /**
454+ * Adds an Interactive Canvas warning to the specific property.
455+ * @param readOnlyField String-based name of the property
456+ * @param owner The object to which the field belongs
457+ */
458+ // eslint-disable-next-line
459+ function addPropertyWarning ( readOnlyField : string , owner : any ) {
460+ const msg =
461+ `The field "${ readOnlyField } " will not execute in an Interactive ` +
462+ 'Canvas environment. See ' +
463+ 'https://developers.google.com/assistant/interactivecanvas/web-apps#guidelines_and_restrictions ' +
464+ 'to learn more.' ;
465+ const boundProperty = owner [ readOnlyField ] ;
466+ Object . defineProperty ( owner , readOnlyField , {
467+ get : ( ) => {
468+ if ( unsupportedApiBehavior === 'warn' ) {
469+ console . warn ( msg ) ;
470+ } else if ( unsupportedApiBehavior === 'error' ) {
471+ throw new Error ( msg ) ;
472+ }
473+ return boundProperty ;
474+ } ,
475+ } ) ;
476+ }
477+
478+ /**
479+ * Add handler to every API method that will not work in Interactive Canvas.
480+ * This will result in either a warning or throw an error depending on
481+ * preference.
482+ * @see https://developers.google.com/assistant/interactivecanvas/web-apps#guidelines_and_restrictions
483+ */
484+ function addUnsupportedApiWarnings ( ) {
485+ addPropertyWarning ( 'localStorage' , window ) ;
486+ addPropertyWarning ( 'geolocation' , window . navigator ) ;
487+ addPropertyWarning ( 'mediaDevices' , window . navigator ) ;
488+ addPropertyWarning ( 'cookie' , document ) ;
489+ addPropertyWarning ( 'indexedDB' , window ) ;
490+ addPropertyWarning ( 'webkitSpeechRecognition' , window ) ;
491+ }
492+
413493window . requestAnimationFrame ( ( ) => {
414494 const hasInteractiveCanvas = window . interactiveCanvas !== undefined ;
415495
@@ -447,6 +527,7 @@ window.requestAnimationFrame(() => {
447527 } ;
448528
449529 window . interactiveCanvasProcessSdk = processSdk ;
530+ addUnsupportedApiWarnings ( ) ;
450531} ) ;
451532
452533document . addEventListener ( 'message' , ( e : Event ) => {
@@ -472,5 +553,9 @@ document.addEventListener('message', (e: Event) => {
472553 window . interactiveCanvasProcessSdk ( ) ;
473554 break ;
474555 }
556+ case 'Ext-UnsupportedApiBehavior' : {
557+ const { data} = eventData ;
558+ unsupportedApiBehavior = data ;
559+ }
475560 }
476561} ) ;
0 commit comments