html 的输出放至 iframe

This commit is contained in:
fofolee 2022-04-22 16:47:44 +08:00
parent 4957ba2030
commit 0909e76bbb
2 changed files with 124 additions and 100 deletions

View File

@ -16,45 +16,26 @@
> >
<q-btn flat round icon="close" color="negative" v-close-popup /> <q-btn flat round icon="close" color="negative" v-close-popup />
</q-toolbar> </q-toolbar>
<iframe <ResultArea
ref="iframe" v-if="isResultShow"
:srcdoc="frameStyle + runResult" @frameLoad="outputAutoHeight(fromUtools)"
:height="frameHeight" :enableHtml="enableHtml"
@load="frameLoad" :runResultStatus="runResultStatus"
frameborder="0" :runResult="runResult"
v-if="htmlOutput" :maxHeight="maxHeight"
></iframe> />
<q-card-section v-else class="row items-center">
<pre
:class="{
'text-red': !runResultStatus,
result: 1,
}"
v-text="runResult"
></pre>
</q-card-section>
</q-card> </q-card>
</q-dialog> </q-dialog>
</div> </div>
<div v-else> <div v-else>
<iframe <ResultArea
ref="iframe" v-if="isResultShow"
:srcdoc="frameStyle + runResult" @frameLoad="outputAutoHeight(fromUtools)"
:height="frameHeight" :enableHtml="enableHtml"
frameborder="0" :runResultStatus="runResultStatus"
@load="frameLoad" :runResult="runResult"
v-if="htmlOutput" :maxHeight="maxHeight"
></iframe> />
<pre
v-else
v-show="!!runResult"
:class="{
'text-red': !runResultStatus,
'q-pa-md': 1,
result: 1,
}"
v-text="runResult"
></pre>
</div> </div>
</div> </div>
</template> </template>
@ -64,30 +45,10 @@
import outputTypes from "../js/options/outputTypes.js"; import outputTypes from "../js/options/outputTypes.js";
import specialVars from "../js/options/specialVars.js"; import specialVars from "../js/options/specialVars.js";
import commandTypes from "../js/options/commandTypes.js"; import commandTypes from "../js/options/commandTypes.js";
import ResultArea from "components/ResultArea.vue";
const frameStyle = `<style>::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: rgba(194, 194, 194, 0.4);
}
::-webkit-scrollbar-track {
border-radius: 10px;
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
}
body {
margin: 0;
color: ${utools.isDarkColors() ? "white" : "unset"}
}
</style>
`;
export default { export default {
components: { ResultArea },
data() { data() {
return { return {
isResultShow: false, isResultShow: false,
@ -97,9 +58,7 @@ export default {
listener: null, listener: null,
history: [], history: [],
historyIdx: null, historyIdx: null,
htmlOutput: false, enableHtml: false,
frameHeight: 0,
frameStyle: frameStyle,
}; };
}, },
props: { props: {
@ -133,7 +92,7 @@ export default {
}, },
async fire(currentCommand) { async fire(currentCommand) {
currentCommand.cmd = this.assignSpecialVars(currentCommand.cmd); currentCommand.cmd = this.assignSpecialVars(currentCommand.cmd);
this.htmlOutput = currentCommand.output === "html"; this.enableHtml = currentCommand.output === "html";
let { hideWindow, outPlugin, action } = let { hideWindow, outPlugin, action } =
outputTypes[currentCommand.output]; outputTypes[currentCommand.output];
// //
@ -246,7 +205,6 @@ export default {
// //
showRunResult(content, isSuccess, action) { showRunResult(content, isSuccess, action) {
this.isResultShow = true; this.isResultShow = true;
this.frameInit();
this.runResultStatus = isSuccess; this.runResultStatus = isSuccess;
let contlength = content?.length || 0; let contlength = content?.length || 0;
if (contlength > this.resultMaxLength) if (contlength > this.resultMaxLength)
@ -258,11 +216,10 @@ export default {
content.slice(contlength - 100); content.slice(contlength - 100);
let pretreatment = action(content); let pretreatment = action(content);
pretreatment && (this.runResult += pretreatment); pretreatment && (this.runResult += pretreatment);
this.outputAutoHeight(); this.outputAutoHeight(this.fromUtools);
}, },
// utools // utools
outputAutoHeight(autoScroll = true, autoHeight = true) { outputAutoHeight(autoHeight = true, autoScroll = true) {
if (!this.fromUtools) return;
this.$nextTick(() => { this.$nextTick(() => {
let clientHeight = document.body.clientHeight; let clientHeight = document.body.clientHeight;
let pluginHeight = let pluginHeight =
@ -284,44 +241,9 @@ export default {
document.removeEventListener("keydown", this.listener, true); document.removeEventListener("keydown", this.listener, true);
} }
}, },
//
frameInit() {
this.$nextTick(() => {
let cfw = this.$refs?.iframe?.contentWindow;
if (!cfw) return;
let ctx = {
quickcommand,
utools,
parent: undefined,
};
Object.assign(cfw, _.cloneDeep(ctx));
});
},
//
frameLoad() {
let cfw = this.$refs?.iframe?.contentWindow;
this.frameHeight = Math.min(
cfw.document.body.scrollHeight,
this.maxHeight
);
this.outputAutoHeight();
},
}, },
unmounted() { unmounted() {
this.stopRun(); this.stopRun();
}, },
}; };
</script> </script>
<style scoped>
.result {
white-space: pre-wrap;
word-wrap: break-word;
max-width: 100%;
margin: 0;
}
iframe {
width: 100%;
display: block;
}
</style>

View File

@ -0,0 +1,102 @@
<template>
<div>
<iframe
ref="iframe"
sandbox="allow-scripts allow-forms"
:srcdoc="frameStyle + runResult"
:height="frameHeight"
frameborder="0"
@load="frameLoad"
v-if="showFrame"
></iframe>
<pre
v-else
v-show="!!runResult"
:class="{
'text-red': !runResultStatus,
'q-pa-md': 1,
result: 1,
}"
v-text="runResult"
></pre>
</div>
</template>
<script>
const frameStyle = `<style>::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: rgba(194, 194, 194, 0.4);
}
::-webkit-scrollbar-track {
border-radius: 10px;
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
}
body {
margin: 0;
padding: 10px 20px;
color: ${utools.isDarkColors() ? "white" : "unset"}
}
</style>
`;
export default {
data() {
return { frameStyle: frameStyle, frameHeight: 0 };
},
props: {
enableHtml: Boolean,
runResultStatus: Boolean,
runResult: String,
maxHeight: Number,
},
computed: {
cfw() {
return this.$refs?.iframe?.contentWindow;
},
showFrame() {
return this.enableHtml && this.runResultStatus;
},
},
methods: {
frameInit() {
if (!this.showFrame) return;
let ctx = {
quickcommand,
utools,
parent: undefined,
};
Object.assign(this.cfw, _.cloneDeep(ctx));
},
frameLoad() {
this.frameHeight = Math.min(
this.cfw.document.documentElement.getBoundingClientRect().height,
this.maxHeight
);
this.$emit("frameLoad");
},
},
mounted() {
this.frameInit();
},
};
</script>
<style scoped>
.result {
white-space: pre-wrap;
word-wrap: break-word;
max-width: 100%;
margin: 0;
}
iframe {
width: 100%;
display: block;
}
</style>