Browse Source

Inspector: Add "Copy All" button to Console tab. (#32825)

Co-authored-by: sunag <sunagbrasil@gmail.com>
sean tai 1 month ago
parent
commit
3ce02ccc40
2 changed files with 64 additions and 6 deletions
  1. 39 5
      examples/jsm/inspector/tabs/Console.js
  2. 25 1
      examples/jsm/inspector/ui/Style.js

+ 39 - 5
examples/jsm/inspector/tabs/Console.js

@@ -33,8 +33,14 @@ class Console extends Tab {
 
 		} );
 
-		const filtersGroup = document.createElement( 'div' );
-		filtersGroup.className = 'console-filters-group';
+		const copyButton = document.createElement( 'button' );
+		copyButton.className = 'console-copy-button';
+		copyButton.title = 'Copy all';
+		copyButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';
+		copyButton.addEventListener( 'click', () => this.copyAll( copyButton ) );
+
+		const buttonsGroup = document.createElement( 'div' );
+		buttonsGroup.className = 'console-buttons-group';
 
 		Object.keys( this.filters ).forEach( type => {
 
@@ -53,11 +59,11 @@ class Console extends Tab {
 			label.appendChild( checkbox );
 			label.appendChild( checkmark );
 			label.append( type.charAt( 0 ).toUpperCase() + type.slice( 1 ) );
-			filtersGroup.appendChild( label );
+			buttonsGroup.appendChild( label );
 
 		} );
 
-		filtersGroup.addEventListener( 'change', ( e ) => {
+		buttonsGroup.addEventListener( 'change', ( e ) => {
 
 			const type = e.target.dataset.type;
 			if ( type in this.filters ) {
@@ -69,8 +75,10 @@ class Console extends Tab {
 
 		} );
 
+		buttonsGroup.appendChild( copyButton );
+
 		header.appendChild( filterInput );
-		header.appendChild( filtersGroup );
+		header.appendChild( buttonsGroup );
 		this.content.appendChild( header );
 
 	}
@@ -92,6 +100,32 @@ class Console extends Tab {
 
 	}
 
+	copyAll( button ) {
+
+		const win = this.logContainer.ownerDocument.defaultView;
+		const selection = win.getSelection();
+		const selectedText = selection.toString();
+		const textInConsole = selectedText && this.logContainer.contains( selection.anchorNode );
+
+		let text;
+		if ( textInConsole ) {
+
+			text = selectedText;
+
+		} else {
+
+			const messages = this.logContainer.querySelectorAll( '.log-message:not(.hidden)' );
+			text = Array.from( messages ).map( msg => msg.dataset.rawText ).join( '\n' );
+
+		}
+
+		navigator.clipboard.writeText( text );
+
+		button.classList.add( 'copied' );
+		setTimeout( () => button.classList.remove( 'copied' ), 350 );
+
+	}
+
 	_getIcon( type, subType ) {
 
 		let icon;

+ 25 - 1
examples/jsm/inspector/ui/Style.js

@@ -1057,7 +1057,7 @@ export class Style {
 	justify-content: space-between;
 }
 
-.console-filters-group {
+.console-buttons-group {
 	display: flex;
 	gap: 20px;
 }
@@ -1074,6 +1074,28 @@ export class Style {
 	border-radius: 15px;
 }
 
+.console-copy-button {
+	background: transparent;
+	border: none;
+	color: var(--text-secondary);
+	cursor: pointer;
+	padding: 4px;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	border-radius: 4px;
+	transition: color 0.2s, background-color 0.2s;
+}
+
+.console-copy-button:hover {
+	color: var(--text-primary);
+	background-color: var(--profiler-hover);
+}
+
+.console-copy-button.copied {
+	color: var(--color-green);
+}
+
 #console-log {
 	display: flex;
 	flex-direction: column;
@@ -1081,6 +1103,8 @@ export class Style {
 	padding: 10px;
 	overflow-y: auto;
 	flex-grow: 1;
+	user-select: text;
+	-webkit-user-select: text;
 }
 
 .log-message {

粤ICP备19079148号