[8] Add screenshot button to capture each panel
Screenshot button is added as a camera icon at the top right corner of each panel (e.g. WindowManagerTrace, SurfaceFlingerDump). Upon clicking this button, an image is downloaded to the user's computer (Downloads folder), showing the whole panel - Hierarchy, Properties etc. Added dependency: html2canvas library Screenshot: https://screenshot.googleplex.com/5rRzqKcEVsJRW2K.png Bug: 236226833 Test: manual on local build of Winscope Change-Id: Idd476017a780288c0e5ae09ce62334333fb9a652
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"cross-env": "^7.0.3",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jszip": "^3.6.0",
|
||||
"kotlin": "^1.5.21",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
>
|
||||
<md-icon>save_alt</md-icon>
|
||||
</md-button>
|
||||
<md-button @click="takeScreenshot" class="md-icon-button">
|
||||
<md-icon>camera_alt</md-icon>
|
||||
</md-button>
|
||||
</md-card-header>
|
||||
<AccessibilityTraceView
|
||||
v-if="showInAccessibilityTraceView(file) && isShowFileType(file.type)"
|
||||
@@ -103,6 +106,7 @@ import FileType from '@/mixins/FileType.js';
|
||||
import FlatCard from '@/components/FlatCard.vue';
|
||||
|
||||
import {TRACE_ICONS} from '@/decode.js';
|
||||
import html2canvas from 'html2canvas';
|
||||
|
||||
export default {
|
||||
name: 'dataview',
|
||||
@@ -121,7 +125,7 @@ export default {
|
||||
return true;
|
||||
} else {
|
||||
for (let i = 0; i < component.$children.length; i++) {
|
||||
var child = component.$children[i];
|
||||
const child = component.$children[i];
|
||||
if (this.depthFirstSearchArrowUp(child)) {
|
||||
return true;
|
||||
}
|
||||
@@ -135,10 +139,10 @@ export default {
|
||||
depthFirstSearchArrowDown(component) {
|
||||
if (component.arrowDown) {
|
||||
component.arrowDown();
|
||||
return true
|
||||
return true;
|
||||
} else {
|
||||
for (let i = 0; i < component.$children.length; i++) {
|
||||
var child = component.$children[i];
|
||||
const child = component.$children[i];
|
||||
if (this.depthFirstSearchArrowDown(child)) {
|
||||
return true;
|
||||
}
|
||||
@@ -148,8 +152,8 @@ export default {
|
||||
},
|
||||
arrowUp() {
|
||||
for (let i = 0; i < this.$children.length; i++) {
|
||||
var child = this.$children[i];
|
||||
let done = this.depthFirstSearchArrowUp(child);
|
||||
const child = this.$children[i];
|
||||
const done = this.depthFirstSearchArrowUp(child);
|
||||
if (done) {
|
||||
return true;
|
||||
}
|
||||
@@ -158,8 +162,8 @@ export default {
|
||||
},
|
||||
arrowDown() {
|
||||
for (let i = 0; i < this.$children.length; i++) {
|
||||
var child = this.$children[i];
|
||||
let done = this.depthFirstSearchArrowDown(child);
|
||||
const child = this.$children[i];
|
||||
const done = this.depthFirstSearchArrowDown(child);
|
||||
if (done) {
|
||||
return true;
|
||||
}
|
||||
@@ -174,8 +178,8 @@ export default {
|
||||
/** Filter data view files by current show settings */
|
||||
updateShowFileTypes() {
|
||||
this.store.showFileTypes = this.dataViewFiles
|
||||
.filter((file) => file.show)
|
||||
.map(file => file.type);
|
||||
.filter((file) => file.show)
|
||||
.map((file) => file.type);
|
||||
},
|
||||
/** Expand or collapse data view */
|
||||
toggleView() {
|
||||
@@ -184,7 +188,24 @@ export default {
|
||||
},
|
||||
/** Check if data view file should be shown */
|
||||
isShowFileType(type) {
|
||||
return this.store.showFileTypes.find(fileType => fileType===type);
|
||||
return this.store.showFileTypes.find((fileType) => fileType===type);
|
||||
},
|
||||
takeScreenshot() {
|
||||
html2canvas(this.$el)
|
||||
.then((canvas) => {
|
||||
const uri = canvas.toDataURL();
|
||||
const filename = 'Winscope-' + this.file.type + '-Screenshot.png';
|
||||
const link = document.createElement('a');
|
||||
if (typeof link.download === 'string') {
|
||||
link.href = uri;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
} else {
|
||||
window.open(uri);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
props: ['store', 'file', 'presentTags', 'presentErrors', 'dataViewFiles'],
|
||||
|
||||
@@ -1707,6 +1707,11 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
base64-arraybuffer@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
|
||||
integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
|
||||
|
||||
base64-js@^1.0.2:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
@@ -2556,6 +2561,13 @@ css-declaration-sorter@^4.0.1:
|
||||
postcss "^7.0.1"
|
||||
timsort "^0.3.0"
|
||||
|
||||
css-line-break@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0"
|
||||
integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
|
||||
dependencies:
|
||||
utrie "^1.0.2"
|
||||
|
||||
css-loader@^5.2.7:
|
||||
version "5.2.7"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae"
|
||||
@@ -3966,6 +3978,14 @@ html-webpack-plugin@4.5.2:
|
||||
tapable "^1.1.3"
|
||||
util.promisify "1.0.0"
|
||||
|
||||
html2canvas@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.4.1.tgz#7cef1888311b5011d507794a066041b14669a543"
|
||||
integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
|
||||
dependencies:
|
||||
css-line-break "^2.1.0"
|
||||
text-segmentation "^1.0.3"
|
||||
|
||||
htmlparser2@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
|
||||
@@ -7288,6 +7308,13 @@ terser@^4.1.2, terser@^4.6.3:
|
||||
source-map "~0.6.1"
|
||||
source-map-support "~0.5.12"
|
||||
|
||||
text-segmentation@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943"
|
||||
integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
|
||||
dependencies:
|
||||
utrie "^1.0.2"
|
||||
|
||||
text-table@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
@@ -7626,6 +7653,13 @@ utils-merge@1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
||||
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
|
||||
|
||||
utrie@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/utrie/-/utrie-1.0.2.tgz#d42fe44de9bc0119c25de7f564a6ed1b2c87a645"
|
||||
integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
|
||||
dependencies:
|
||||
base64-arraybuffer "^1.0.2"
|
||||
|
||||
uuid@^3.3.2, uuid@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
|
||||
Reference in New Issue
Block a user