DevTools.hx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package hide.view;
  2. class DevTools extends hide.ui.View<{ profileFilePath : String }> {
  3. var devtools : Element.HTMLElement;
  4. public function new( ?state ) {
  5. super(state);
  6. }
  7. override function onDisplay() {
  8. new Element('
  9. <div class="devtools">
  10. <webview id="webview-blank" src="blank.html" partition="persist:trusted"></webview>
  11. <webview id="webview-devtools" src="about:blank" partition="persist:trusted"></webview>
  12. </div>').appendTo(element);
  13. var blank = element.find("#webview-blank").get(0);
  14. devtools = element.find("#webview-devtools").get(0);
  15. var openCalled = false;
  16. var blankLoaded = false;
  17. var devtoolsLoaded = false;
  18. function tryOpen() {
  19. if( openCalled || !blankLoaded || !devtoolsLoaded )
  20. return;
  21. openCalled = true;
  22. showDevTools(blank, true, devtools);
  23. // wait for devTools ready
  24. haxe.Timer.delay(() -> openProfile(), 500);
  25. }
  26. blank.addEventListener("contentload", function() {
  27. blankLoaded = true;
  28. tryOpen();
  29. });
  30. devtools.addEventListener("contentload", function() {
  31. devtoolsLoaded = true;
  32. tryOpen();
  33. });
  34. }
  35. override function buildTabMenu():Array<hide.comp.ContextMenu.MenuItem> {
  36. var menu = super.buildTabMenu();
  37. menu.push({isSeparator: true});
  38. menu.push({label: "Debug", click: () -> {
  39. showDevTools(devtools, true);
  40. }});
  41. return menu;
  42. }
  43. public function openProfile() {
  44. if( this.state.profileFilePath == null )
  45. return;
  46. try {
  47. var unsafeContent = sys.io.File.getContent(this.state.profileFilePath);
  48. // ensure that it's really a json
  49. var fileContent = haxe.Json.stringify(haxe.Json.parse(unsafeContent));
  50. unsafeExecuteScript('
  51. var tmp = {};
  52. tmp.fileContent = `${fileContent}`;
  53. tmp.dataT = new DataTransfer();
  54. tmp.dataT.items.add(new File([tmp.fileContent], "profile.json", {type: "application/json"}))
  55. document.elementFromPoint(0, 0).shadowRoot.getElementById("tab-timeline").dispatchEvent(new MouseEvent("mousedown", {isTrusted: true, button: 0}));
  56. setTimeout(function() {
  57. document.getElementsByClassName("timeline")[0].dispatchEvent(new DragEvent("dragover", {dataTransfer: tmp.dataT}));
  58. document.getElementsByClassName("timeline")[0].lastChild.dispatchEvent(new DragEvent("drop", {dataTransfer: tmp.dataT}));
  59. }, 100);
  60. ');
  61. } catch( e ) {
  62. ide.error("Unable to open profile: " + e.message);
  63. this.state.profileFilePath = null;
  64. saveState();
  65. syncTitle();
  66. }
  67. }
  68. inline function showDevTools( webview : Element.HTMLElement, show : Bool, ?container : Element.HTMLElement ) {
  69. js.Syntax.code("{0}.showDevTools({1}, {2});", webview, show, container);
  70. }
  71. inline function unsafeExecuteScript( script : String ) {
  72. js.Syntax.code("{0}.executeScript({ code: {1}, mainWorld: false });", devtools, script);
  73. }
  74. override function getTitle() {
  75. if( this.state.profileFilePath != null ) {
  76. var file = haxe.io.Path.withoutDirectory(this.state.profileFilePath);
  77. return "DevTools:" + file;
  78. }
  79. return "DevTools";
  80. }
  81. static var _ = hide.ui.View.register(DevTools);
  82. }