web-frame.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import { EventEmitter } from 'events';
  2. import deprecate from '@electron/internal/common/api/deprecate';
  3. const binding = process._linkedBinding('electron_renderer_web_frame');
  4. class WebFrame extends EventEmitter {
  5. constructor (public context: Window) {
  6. super();
  7. // Lots of webview would subscribe to webFrame's events.
  8. this.setMaxListeners(0);
  9. }
  10. findFrameByRoutingId (...args: Array<any>) {
  11. return getWebFrame(binding._findFrameByRoutingId(this.context, ...args));
  12. }
  13. getFrameForSelector (...args: Array<any>) {
  14. return getWebFrame(binding._getFrameForSelector(this.context, ...args));
  15. }
  16. findFrameByName (...args: Array<any>) {
  17. return getWebFrame(binding._findFrameByName(this.context, ...args));
  18. }
  19. get opener () {
  20. return getWebFrame(binding._getOpener(this.context));
  21. }
  22. get parent () {
  23. return getWebFrame(binding._getParent(this.context));
  24. }
  25. get top () {
  26. return getWebFrame(binding._getTop(this.context));
  27. }
  28. get firstChild () {
  29. return getWebFrame(binding._getFirstChild(this.context));
  30. }
  31. get nextSibling () {
  32. return getWebFrame(binding._getNextSibling(this.context));
  33. }
  34. get routingId () {
  35. return binding._getRoutingId(this.context);
  36. }
  37. }
  38. const contextIsolation = binding.getWebPreference(window, 'contextIsolation');
  39. const worldSafeExecuteJavaScript = binding.getWebPreference(window, 'worldSafeExecuteJavaScript');
  40. const worldSafeJS = worldSafeExecuteJavaScript || !contextIsolation;
  41. // Populate the methods.
  42. for (const name in binding) {
  43. if (!name.startsWith('_')) { // some methods are manually populated above
  44. // TODO(felixrieseberg): Once we can type web_frame natives, we could
  45. // use a neat `keyof` here
  46. (WebFrame as any).prototype[name] = function (...args: Array<any>) {
  47. if (!worldSafeJS && name.startsWith('executeJavaScript')) {
  48. deprecate.log(`Security Warning: webFrame.${name} was called without worldSafeExecuteJavaScript enabled. This is considered unsafe. worldSafeExecuteJavaScript will be enabled by default in Electron 12.`);
  49. }
  50. return binding[name](this.context, ...args);
  51. };
  52. // TODO(MarshallOfSound): Remove once the above deprecation is removed
  53. if (name.startsWith('executeJavaScript')) {
  54. (WebFrame as any).prototype[`_${name}`] = function (...args: Array<any>) {
  55. return binding[name](this.context, ...args);
  56. };
  57. }
  58. }
  59. }
  60. // Helper to return WebFrame or null depending on context.
  61. // TODO(zcbenz): Consider returning same WebFrame for the same frame.
  62. function getWebFrame (context: Window) {
  63. return context ? new WebFrame(context) : null;
  64. }
  65. const _webFrame = new WebFrame(window);
  66. export default _webFrame;