DropHarHandler.js (3323B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const { 8 Component, 9 } = require("resource://devtools/client/shared/vendor/react.mjs"); 10 const { 11 findDOMNode, 12 } = require("resource://devtools/client/shared/vendor/react-dom.mjs"); 13 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs"); 14 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); 15 const { 16 L10N, 17 } = require("resource://devtools/client/netmonitor/src/utils/l10n.js"); 18 19 loader.lazyRequireGetter( 20 this, 21 "HarMenuUtils", 22 "resource://devtools/client/netmonitor/src/har/har-menu-utils.js", 23 true 24 ); 25 26 const { div } = dom; 27 28 const DROP_HAR_FILES = L10N.getStr("netmonitor.label.dropHarFiles"); 29 30 /** 31 * Helper component responsible for handling and importing 32 * dropped *.har files. 33 */ 34 class DropHarHandler extends Component { 35 static get propTypes() { 36 return { 37 // List of actions passed to HAR importer. 38 actions: PropTypes.object.isRequired, 39 // Child component. 40 children: PropTypes.element.isRequired, 41 // Callback for opening split console. 42 openSplitConsole: PropTypes.func, 43 }; 44 } 45 46 constructor(props) { 47 super(props); 48 49 // Drag and drop event handlers. 50 this.onDragEnter = this.onDragEnter.bind(this); 51 this.onDragOver = this.onDragOver.bind(this); 52 this.onDragLeave = this.onDragLeave.bind(this); 53 this.onDrop = this.onDrop.bind(this); 54 } 55 56 // Drag Events 57 58 onDragEnter(event) { 59 event.preventDefault(); 60 if (event.dataTransfer.files.length === 0) { 61 return; 62 } 63 64 startDragging(findDOMNode(this)); 65 } 66 67 onDragLeave(event) { 68 const node = findDOMNode(this); 69 if (!node.contains(event.relatedTarget)) { 70 stopDragging(node); 71 } 72 } 73 74 onDragOver(event) { 75 event.preventDefault(); 76 event.dataTransfer.dropEffect = "copy"; 77 } 78 79 onDrop(event) { 80 event.preventDefault(); 81 stopDragging(findDOMNode(this)); 82 83 const { files } = event.dataTransfer; 84 if (!files) { 85 return; 86 } 87 88 const { actions, openSplitConsole } = this.props; 89 90 // Import only the first dragged file for now 91 // See also: 92 // https://bugzilla.mozilla.org/show_bug.cgi?id=1438792 93 if (files.length) { 94 const file = files[0]; 95 readFile(file).then(har => { 96 if (har) { 97 HarMenuUtils.appendPreview(har, actions, openSplitConsole); 98 } 99 }); 100 } 101 } 102 103 // Rendering 104 105 render() { 106 return div( 107 { 108 onDragEnter: this.onDragEnter, 109 onDragOver: this.onDragOver, 110 onDragLeave: this.onDragLeave, 111 onDrop: this.onDrop, 112 }, 113 this.props.children, 114 div({ className: "dropHarFiles" }, div({}, DROP_HAR_FILES)) 115 ); 116 } 117 } 118 119 // Helpers 120 121 function readFile(file) { 122 return new Promise(resolve => { 123 const fileReader = new FileReader(); 124 fileReader.onloadend = () => { 125 resolve(fileReader.result); 126 }; 127 fileReader.readAsText(file); 128 }); 129 } 130 131 function startDragging(node) { 132 node.setAttribute("dragging", "true"); 133 } 134 135 function stopDragging(node) { 136 node.removeAttribute("dragging"); 137 } 138 139 // Exports 140 141 module.exports = DropHarHandler;