inspector.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. window.onload = function () {
  2. // Use menu API to show context menu.
  3. window.InspectorFrontendHost.showContextMenuAtPoint = createMenu
  4. // Use dialog API to override file chooser dialog.
  5. // Note: It will be moved to UI after Chrome 57.
  6. window.Bindings.createFileSelectorElement = createFileSelectorElement
  7. }
  8. window.confirm = function (message, title) {
  9. const {dialog} = require('electron').remote
  10. if (title == null) {
  11. title = ''
  12. }
  13. return !dialog.showMessageBox({
  14. message: message,
  15. title: title,
  16. buttons: ['OK', 'Cancel'],
  17. cancelId: 1
  18. })
  19. }
  20. const convertToMenuTemplate = function (items) {
  21. return items.map(function (item) {
  22. const transformed = item.type === 'subMenu' ? {
  23. type: 'submenu',
  24. label: item.label,
  25. enabled: item.enabled,
  26. submenu: convertToMenuTemplate(item.subItems)
  27. } : item.type === 'separator' ? {
  28. type: 'separator'
  29. } : item.type === 'checkbox' ? {
  30. type: 'checkbox',
  31. label: item.label,
  32. enabled: item.enabled,
  33. checked: item.checked
  34. } : {
  35. type: 'normal',
  36. label: item.label,
  37. enabled: item.enabled
  38. }
  39. if (item.id != null) {
  40. transformed.click = function () {
  41. window.DevToolsAPI.contextMenuItemSelected(item.id)
  42. return window.DevToolsAPI.contextMenuCleared()
  43. }
  44. }
  45. return transformed
  46. })
  47. }
  48. const createMenu = function (x, y, items) {
  49. const {remote} = require('electron')
  50. const {Menu} = remote
  51. let template = convertToMenuTemplate(items)
  52. if (useEditMenuItems(x, y, template)) {
  53. template = getEditMenuItems()
  54. }
  55. const menu = Menu.buildFromTemplate(template)
  56. // The menu is expected to show asynchronously.
  57. setTimeout(function () {
  58. menu.popup({window: remote.getCurrentWindow()})
  59. })
  60. }
  61. const useEditMenuItems = function (x, y, items) {
  62. return items.length === 0 && document.elementsFromPoint(x, y).some(function (element) {
  63. return element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA' || element.isContentEditable
  64. })
  65. }
  66. const getEditMenuItems = function () {
  67. return [
  68. {
  69. role: 'undo'
  70. },
  71. {
  72. role: 'redo'
  73. },
  74. {
  75. type: 'separator'
  76. },
  77. {
  78. role: 'cut'
  79. },
  80. {
  81. role: 'copy'
  82. },
  83. {
  84. role: 'paste'
  85. },
  86. {
  87. role: 'pasteAndMatchStyle'
  88. },
  89. {
  90. role: 'delete'
  91. },
  92. {
  93. role: 'selectAll'
  94. }
  95. ]
  96. }
  97. const showFileChooserDialog = function (callback) {
  98. const {dialog} = require('electron').remote
  99. const files = dialog.showOpenDialog({})
  100. if (files != null) {
  101. callback(pathToHtml5FileObject(files[0]))
  102. }
  103. }
  104. const pathToHtml5FileObject = function (path) {
  105. const fs = require('fs')
  106. const blob = new Blob([fs.readFileSync(path)])
  107. blob.name = path
  108. return blob
  109. }
  110. const createFileSelectorElement = function (callback) {
  111. const fileSelectorElement = document.createElement('span')
  112. fileSelectorElement.style.display = 'none'
  113. fileSelectorElement.click = showFileChooserDialog.bind(this, callback)
  114. return fileSelectorElement
  115. }