parent
51fbe8e2d5
commit
dab9c08ee6
|
@ -134,6 +134,32 @@
|
|||
|
||||
<ms-change-history ref="changeHistory"/>
|
||||
|
||||
<el-dialog
|
||||
:fullscreen="true"
|
||||
:visible.sync="dialogVisible"
|
||||
width="100%"
|
||||
>
|
||||
<http-api-version-diff
|
||||
:old-data="httpForm"
|
||||
:show-follow="showFollow"
|
||||
:new-data="newData"
|
||||
:new-show-follow="newShowFollow"
|
||||
:old-mock-url="getUrlPrefix"
|
||||
:new-mock-url="newMockUrl"
|
||||
:rule="rule"
|
||||
:maintainer-options="maintainerOptions"
|
||||
:module-options="moduleOptions"
|
||||
:request="request"
|
||||
:old-request="oldRequest"
|
||||
:response="response"
|
||||
:old-response="oldResponse"
|
||||
></http-api-version-diff>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible=false">取 消</el-button>
|
||||
<el-button type="primary" >确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -151,6 +177,11 @@ import MsChangeHistory from "../../../../history/ChangeHistory";
|
|||
import {getCurrentProjectID, getCurrentUser, getUUID, hasLicense} from "@/common/js/utils";
|
||||
import MsFormDivider from "@/business/components/common/components/MsFormDivider";
|
||||
import ApiOtherInfo from "@/business/components/api/definition/components/complete/ApiOtherInfo";
|
||||
import HttpApiVersionDiff from "./version/HttpApiVersionDiff"
|
||||
import {createComponent } from ".././jmeter/components";
|
||||
import { TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
|
||||
|
||||
const {Body} = require("@/business/components/api/definition/model/ApiTestModel");
|
||||
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const versionHistory = requireComponent.keys().length > 0 ? requireComponent("./version/VersionHistory.vue") : {};
|
||||
|
@ -161,7 +192,8 @@ export default {
|
|||
'MsVersionHistory': versionHistory.default,
|
||||
ApiOtherInfo,
|
||||
MsFormDivider,
|
||||
MsJsr233Processor, MsResponseText, MsApiRequestForm, MsInputTag, MsSelectTree, MsChangeHistory
|
||||
MsJsr233Processor, MsResponseText, MsApiRequestForm, MsInputTag, MsSelectTree, MsChangeHistory,
|
||||
HttpApiVersionDiff
|
||||
},
|
||||
data() {
|
||||
let validateURL = (rule, value, callback) => {
|
||||
|
@ -185,8 +217,11 @@ export default {
|
|||
status: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
||||
},
|
||||
httpForm: {environmentId: "", path: "", tags: []},
|
||||
newData:{environmentId: "", path: "", tags: []},
|
||||
dialogVisible:false,
|
||||
isShowEnable: true,
|
||||
showFollow: false,
|
||||
newShowFollow:false,
|
||||
maintainerOptions: [],
|
||||
currentModule: {},
|
||||
reqOptions: REQ_METHOD,
|
||||
|
@ -197,8 +232,11 @@ export default {
|
|||
label: 'name',
|
||||
},
|
||||
mockBaseUrl: "",
|
||||
newMockBaseUrl: "",
|
||||
count: 0,
|
||||
versionData: [],
|
||||
oldRequest:{},
|
||||
oldResponse:{}
|
||||
};
|
||||
},
|
||||
props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array, projectId: String},
|
||||
|
@ -314,6 +352,39 @@ export default {
|
|||
}
|
||||
return this.mockBaseUrl + path;
|
||||
}
|
||||
},
|
||||
newMockUrl() {
|
||||
if (this.newData.path == null) {
|
||||
return this.newMockBaseUrl;
|
||||
} else {
|
||||
let path = this.newData.path;
|
||||
let protocol = this.newData.method;
|
||||
if (protocol === 'GET' || protocol === 'DELETE') {
|
||||
if (this.newData.request != null && this.newData.request.rest != null) {
|
||||
let pathUrlArr = path.split("/");
|
||||
let newPath = "";
|
||||
pathUrlArr.forEach(item => {
|
||||
if (item !== "") {
|
||||
let pathItem = item;
|
||||
if (item.indexOf("{") === 0 && item.indexOf("}") === (item.length - 1)) {
|
||||
let paramItem = item.substr(1, item.length - 2);
|
||||
for (let i = 0; i < this.newData.request.rest.length; i++) {
|
||||
let param = this.newData.request.rest[i];
|
||||
if (param.name === paramItem) {
|
||||
pathItem = param.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
newPath += "/" + pathItem;
|
||||
}
|
||||
});
|
||||
if (newPath !== "") {
|
||||
path = newPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.newMockBaseUrl + path;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -428,6 +499,7 @@ export default {
|
|||
conditions.forEach(condition => {
|
||||
if (condition.type === httpType) {
|
||||
this.mockBaseUrl = condition.protocol + "://" + condition.socket;
|
||||
this.newMockBaseUrl = this.mockBaseUrl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -466,7 +538,95 @@ export default {
|
|||
});
|
||||
},
|
||||
compare(row) {
|
||||
// console.log(row);
|
||||
this.$get('/api/definition/get/' + row.id+"/"+this.httpForm.refId, response => {
|
||||
this.$get('/api/definition/get/' + response.data.id, res => {
|
||||
if (res.data) {
|
||||
this.newData = res.data;
|
||||
this.$get('/api/definition/follow/' + response.data.id, resp => {
|
||||
if(resp.data&&resp.data.follows){
|
||||
for (let i = 0; i <resp.data.follows.length; i++) {
|
||||
if(resp.data.follows[i]===this.currentUser().id){
|
||||
this.newShowFollow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
this.setRequest(res.data)
|
||||
if (!this.setRequest(res.data)) {
|
||||
this.oldRequest = createComponent("HTTPSamplerProxy");
|
||||
}
|
||||
this.formatApi(res.data)
|
||||
}
|
||||
});
|
||||
});
|
||||
if(this.newData){
|
||||
this.dialogVisible = true;
|
||||
}
|
||||
},
|
||||
setRequest(api) {
|
||||
if (api.request !== undefined) {
|
||||
if (Object.prototype.toString.call(api.request).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') {
|
||||
this.oldRequest = api.request;
|
||||
} else {
|
||||
this.oldRequest = JSON.parse(api.request);
|
||||
}
|
||||
if (!this.oldRequest.headers) {
|
||||
this.oldRequest.headers = [];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
formatApi(api) {
|
||||
if (api.response != null && api.response !== 'null' && api.response !== undefined) {
|
||||
if (Object.prototype.toString.call(api.response).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') {
|
||||
this.oldResponse = api.response;
|
||||
} else {
|
||||
this.oldResponse = JSON.parse(api.response);
|
||||
}
|
||||
} else {
|
||||
this.oldResponse = {headers: [], body: new Body(), statusCode: [], type: "HTTP"};
|
||||
}
|
||||
if (!this.oldRequest.hashTree) {
|
||||
this.oldRequest.hashTree = [];
|
||||
}
|
||||
if (this.oldRequest.body && !this.oldRequest.body.binary) {
|
||||
this.oldRequest.body.binary = [];
|
||||
}
|
||||
// 处理导入数据缺失问题
|
||||
if (this.oldResponse.body) {
|
||||
let body = new Body();
|
||||
Object.assign(body, this.oldResponse.body);
|
||||
if (!body.binary) {
|
||||
body.binary = [];
|
||||
}
|
||||
if (!body.kvs) {
|
||||
body.kvs = [];
|
||||
}
|
||||
if (!body.binary) {
|
||||
body.binary = [];
|
||||
}
|
||||
this.oldResponse.body = body;
|
||||
}
|
||||
this.oldRequest.clazzName = TYPE_TO_C.get(this.oldRequest.type);
|
||||
|
||||
this.sort(this.oldRequest.hashTree);
|
||||
},
|
||||
sort(stepArray) {
|
||||
if (stepArray) {
|
||||
for (let i in stepArray) {
|
||||
if (!stepArray[i].clazzName) {
|
||||
stepArray[i].clazzName = TYPE_TO_C.get(stepArray[i].type);
|
||||
}
|
||||
if (stepArray[i].type === "Assertions" && !stepArray[i].document) {
|
||||
stepArray[i].document = {type: "JSON", data: {xmlFollowAPI: false, jsonFollowAPI: false, json: [], xml: []}};
|
||||
}
|
||||
if (stepArray[i].hashTree && stepArray[i].hashTree.length > 0) {
|
||||
this.sort(stepArray[i].hashTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
checkout(row) {
|
||||
let api = this.versionData.filter(v => v.versionId === row.id)[0];
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
<template>
|
||||
<div class="compare-class">
|
||||
<el-card style="width: 50%;" ref="old">
|
||||
<el-form :model="oldData" :rules="rule" ref="httpForm" label-width="80px" label-position="right">
|
||||
<!-- 操作按钮 -->
|
||||
<div style="float: right;margin-right: 20px" class="ms-opt-btn">
|
||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!showFollow">
|
||||
<i class="el-icon-star-off"
|
||||
style="color: #783987; font-size: 25px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "/>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="showFollow">
|
||||
<i class="el-icon-star-on"
|
||||
style="color: #783987; font-size: 28px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<br/>
|
||||
<ms-form-divider :title="$t('test_track.plan_view.base_info')"/>
|
||||
|
||||
<!-- 基础信息 -->
|
||||
<div class="base-info">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input class="ms-http-input" size="small" v-model="oldData.name"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-form-item :label="$t('api_report.request')" prop="path">
|
||||
<el-input :placeholder="$t('api_test.definition.request.path_info')" v-model="oldData.path"
|
||||
class="ms-http-input" size="small" style="margin-top: 5px" >
|
||||
<el-select v-model="oldData.method" slot="prepend" style="width: 100px" size="small">
|
||||
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="userId">
|
||||
<el-select v-model="oldData.userId"
|
||||
:placeholder="$t('api_test.definition.request.responsible')" filterable size="small"
|
||||
class="ms-http-select">
|
||||
<el-option
|
||||
v-for="item in maintainerOptions"
|
||||
:key="item.id"
|
||||
:label="item.name + ' (' + item.id + ')'"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
||||
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="oldData.moduleId"
|
||||
:obj="moduleObj" clearable checkStrictly/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('commons.status')" prop="status">
|
||||
<el-select class="ms-http-select" size="small" v-model="oldData.status">
|
||||
<el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('commons.tag')" prop="tag">
|
||||
<ms-input-tag :currentScenario="oldData" ref="tag" v-model="oldData.tags"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('commons.description')" prop="description">
|
||||
<el-input class="ms-http-textarea"
|
||||
v-model="oldData.description"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1, maxRows: 10}"
|
||||
:rows="1" size="small"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- MOCK信息 -->
|
||||
<ms-form-divider :title="$t('test_track.plan_view.mock_info')"/>
|
||||
<div class="base-info mock-info">
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
Mock地址:
|
||||
<el-link :href="oldMockUrl" target="_blank" style="color: black"
|
||||
type="primary">{{ this.oldMockUrl }}
|
||||
</el-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 请求参数 -->
|
||||
<div>
|
||||
<ms-form-divider :title="$t('api_test.definition.request.req_param')"/>
|
||||
<ms-api-request-form :showScript="false" :request="request" :headers="request.headers"
|
||||
:isShowEnable="isShowEnable"/>
|
||||
</div>
|
||||
|
||||
</el-form>
|
||||
|
||||
<!-- 响应内容-->
|
||||
<ms-form-divider :title="$t('api_test.definition.request.res_param')"/>
|
||||
<ms-response-text :response="response"/>
|
||||
|
||||
<api-other-info :api="oldData"/>
|
||||
|
||||
</el-card>
|
||||
<el-card style="width: 50%;" ref="new">
|
||||
<el-form :model="newData" :rules="rule" ref="httpForm" label-width="80px" label-position="right">
|
||||
<!-- 操作按钮 -->
|
||||
<div style="float: right;margin-right: 20px" class="ms-opt-btn">
|
||||
<el-tooltip :content="$t('commons.follow')" placement="bottom" effect="dark" v-if="!newShowFollow">
|
||||
<i class="el-icon-star-off"
|
||||
style="color: #783987; font-size: 25px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "/>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('commons.cancel')" placement="bottom" effect="dark" v-if="newShowFollow">
|
||||
<i class="el-icon-star-on"
|
||||
style="color: #783987; font-size: 28px; margin-right: 5px; position: relative; top: 5px; cursor: pointer "/>
|
||||
</el-tooltip>
|
||||
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<ms-form-divider :title="$t('test_track.plan_view.base_info')"/>
|
||||
|
||||
<!-- 基础信息 -->
|
||||
<div class="base-info">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input class="ms-http-input" size="small" v-model="newData.name"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-form-item :label="$t('api_report.request')" prop="path">
|
||||
<el-input :placeholder="$t('api_test.definition.request.path_info')" v-model="newData.path"
|
||||
class="ms-http-input" size="small" style="margin-top: 5px" >
|
||||
<el-select v-model="newData.method" slot="prepend" style="width: 100px" size="small">
|
||||
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="userId">
|
||||
<el-select v-model="newData.userId"
|
||||
:placeholder="$t('api_test.definition.request.responsible')" filterable size="small"
|
||||
class="ms-http-select">
|
||||
<el-option
|
||||
v-for="item in maintainerOptions"
|
||||
:key="item.id"
|
||||
:label="item.name + ' (' + item.id + ')'"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
||||
<ms-select-tree size="small" :data="moduleOptions" :defaultKey="newData.moduleId"
|
||||
:obj="moduleObj" clearable checkStrictly/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('commons.status')" prop="status">
|
||||
<el-select class="ms-http-select" size="small" v-model="newData.status">
|
||||
<el-option v-for="item in options" :key="item.id" :label="$t(item.label)" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('commons.tag')" prop="tag">
|
||||
<ms-input-tag :currentScenario="newData" ref="tag" v-model="newData.tags"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('commons.description')" prop="description">
|
||||
<el-input class="ms-http-textarea"
|
||||
v-model="newData.description"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1, maxRows: 10}"
|
||||
:rows="1" size="small"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- MOCK信息 -->
|
||||
<ms-form-divider :title="$t('test_track.plan_view.mock_info')"/>
|
||||
<div class="base-info mock-info">
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
Mock地址:
|
||||
<el-link :href="newMockUrl" target="_blank" style="color: black"
|
||||
type="primary">{{ this.newMockUrl }}
|
||||
</el-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 请求参数 -->
|
||||
<div>
|
||||
<ms-form-divider :title="$t('api_test.definition.request.req_param')"/>
|
||||
<ms-api-request-form :showScript="false" :request="oldRequest" :headers="oldRequest.headers"
|
||||
:isShowEnable="isShowEnable"/>
|
||||
</div>
|
||||
|
||||
</el-form>
|
||||
|
||||
<!-- 响应内容-->
|
||||
<ms-form-divider :title="$t('api_test.definition.request.res_param')"/>
|
||||
<ms-response-text :response="oldResponse"/>
|
||||
|
||||
<api-other-info :api="newData"/>
|
||||
</el-card>
|
||||
<button @click="getDiff"></button>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {API_STATUS, REQ_METHOD} from "../../../model/JsonData";
|
||||
import MsFormDivider from "@/business/components/common/components/MsFormDivider";
|
||||
import ApiOtherInfo from "@/business/components/api/definition/components/complete/ApiOtherInfo";
|
||||
import MsResponseText from "../../response/ResponseText";
|
||||
import MsApiRequestForm from "../../request/http/ApiHttpRequestForm";
|
||||
import MsSelectTree from "../../../../../common/select-tree/SelectTree";
|
||||
import MsInputTag from "@/business/components/api/automation/scenario/MsInputTag";
|
||||
|
||||
const {diff} = require("@/business/components/performance/v_node_diff");
|
||||
|
||||
export default{
|
||||
name: "HttpApiVersionDiff",
|
||||
components: {
|
||||
ApiOtherInfo,
|
||||
MsFormDivider,
|
||||
MsResponseText,
|
||||
MsApiRequestForm,
|
||||
MsInputTag,
|
||||
MsSelectTree,
|
||||
},
|
||||
props:{
|
||||
oldData:{
|
||||
type:Object
|
||||
},
|
||||
newData:{
|
||||
type:Object
|
||||
},
|
||||
showFollow:{
|
||||
type:Boolean
|
||||
},
|
||||
newShowFollow:{
|
||||
type:Boolean
|
||||
},
|
||||
rule:{
|
||||
type:Object
|
||||
},
|
||||
maintainerOptions:{
|
||||
type:Array
|
||||
},
|
||||
moduleOptions:{},
|
||||
oldMockUrl:{
|
||||
},
|
||||
newMockUrl:{
|
||||
},
|
||||
request: {},
|
||||
oldRequest:{},
|
||||
response: {},
|
||||
oldResponse:{}
|
||||
},
|
||||
|
||||
data(){
|
||||
return{
|
||||
reqOptions: REQ_METHOD,
|
||||
options: API_STATUS,
|
||||
moduleObj: {
|
||||
id: 'id',
|
||||
label: 'name',
|
||||
},
|
||||
isShowEnable: true,
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getDiff(){
|
||||
let oldVnode = this.$refs.old
|
||||
let vnode = this.$refs.new
|
||||
//oldVnode.style.backgroundColor = "rgb(241,200,196)";
|
||||
console.log(this.$refs.old)
|
||||
console.log(this.$refs.new)
|
||||
diff(oldVnode,vnode);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.compare-class{
|
||||
display: flex;
|
||||
justify-content:space-between;
|
||||
}
|
||||
</style>
|
|
@ -70,24 +70,32 @@ function changeStyle(diffNode){
|
|||
console.log(diffNode.oldNodeArray);
|
||||
console.log(diffNode.nodeArray);
|
||||
for (let i = 0; i < diffNode.oldNodeArray.length; i++) {
|
||||
if(diffNode.oldNodeArray[i]==='comment'||isUndef(diffNode.oldNodeArray[i].style)){
|
||||
if(diffNode.oldNodeArray[i]==='comment'||diffNode.oldNodeArray[i].nodeName==="#comment"){
|
||||
continue
|
||||
}
|
||||
if(diffNode.oldNodeArray[i].className==='cell'){
|
||||
let rowVnodeElm = findRowVnodeElm(diffNode.oldNodeArray[i]);
|
||||
if(isDef(rowVnodeElm.style)){
|
||||
rowVnodeElm.style.setProperty("background-color","rgb(241,200,196)",'important')
|
||||
}else if(isDef(rowVnodeElm.parentNode.style)&&rowVnodeElm!=='comment'){
|
||||
rowVnodeElm.parentNode.style.setProperty("background-color","rgb(241,200,196)",'important')
|
||||
}
|
||||
}else{
|
||||
changeStyleBySubset(diffNode.oldNodeArray[i],"rgb(241,200,196)");
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < diffNode.nodeArray.length; i++) {
|
||||
if(diffNode.nodeArray[i]==='comment'||isUndef(diffNode.nodeArray[i].style)){
|
||||
if(diffNode.nodeArray[i]==='comment'||diffNode.nodeArray[i].nodeName==="#comment"){
|
||||
continue
|
||||
}
|
||||
if(diffNode.nodeArray[i].className==='cell'){
|
||||
let rowVnodeElm = findRowVnodeElm(diffNode.nodeArray[i]);
|
||||
if(isDef(rowVnodeElm.style)){
|
||||
rowVnodeElm.style.setProperty("background-color","rgb(215, 243, 215)",'important')
|
||||
}else if(isDef(rowVnodeElm.parentNode.style)&&rowVnodeElm!=='comment'){
|
||||
rowVnodeElm.parentNode.style.setProperty("background-color","rgb(215, 243, 215)",'important')
|
||||
}
|
||||
}else{
|
||||
changeStyleBySubset(diffNode.nodeArray[i],"rgb(215, 243, 215)");
|
||||
}
|
||||
|
@ -98,6 +106,8 @@ function changeStyleBySubset(vnodeElm,color){
|
|||
if(isDef(vnodeElm.children)&&vnodeElm.children.length>0){
|
||||
if(isDef(vnodeElm.style)){
|
||||
vnodeElm.style.setProperty("background-color",color,'important')
|
||||
}else if(isDef(vnodeElm.parentNode.style)&&vnodeElm!=='comment'){
|
||||
vnodeElm.parentNode.style.setProperty("background-color",color,'important')
|
||||
}
|
||||
for (let i = 0; i < vnodeElm.children.length; i++) {
|
||||
changeStyleBySubset(vnodeElm.children[i],color);
|
||||
|
@ -105,7 +115,7 @@ function changeStyleBySubset(vnodeElm,color){
|
|||
}else {
|
||||
if(isDef(vnodeElm.style)){
|
||||
vnodeElm.style.setProperty("background-color",color,'important')
|
||||
}else {
|
||||
}else if(isDef(vnodeElm.parentNode.style)&&vnodeElm!=='comment'){
|
||||
vnodeElm.parentNode.style.setProperty("background-color",color,'important')
|
||||
}
|
||||
}
|
||||
|
@ -164,12 +174,12 @@ function diffChildren(oldChildren,newChildren,diffNode,isCompareChildren){
|
|||
let newVnode = newChildren[i]
|
||||
diffDetail(oldVnode,newVnode,diffNode)
|
||||
}
|
||||
for (let i = childrenLength; i <= (oldLength - childrenLength); i++) {
|
||||
for (let i = childrenLength; i < oldLength; i++) {
|
||||
if(oldChildren[i]){
|
||||
diffNode.oldNodeArray.push(oldChildren[i].elm);
|
||||
}
|
||||
}
|
||||
for (let i = childrenLength; i <= (newLength - childrenLength); i++) {
|
||||
for (let i = childrenLength; i < newLength; i++) {
|
||||
if(newChildren[i]){
|
||||
diffNode.nodeArray.push(newChildren[i].elm);
|
||||
}
|
||||
|
@ -236,7 +246,6 @@ function sameDetail(oldVnode,newVnode,sameNode){
|
|||
|
||||
}
|
||||
|
||||
|
||||
function diffDetail(oldVnode,newVnode,diffNode){
|
||||
if(isDef(oldVnode.child)&&isUndef(newVnode.child)){
|
||||
diffNode.oldNodeArray.push(oldVnode.child._vnode.elm);
|
||||
|
@ -268,21 +277,15 @@ function diffDetail(oldVnode,newVnode,diffNode){
|
|||
}
|
||||
diffChildren(oldVnode.children,newVnode.children,diffNode,isCompareChildren)
|
||||
}
|
||||
//剩最后的子节点的时候,分类型做判断
|
||||
//剩最后的子节点的时候,分类型做判断(注意,最后的子节点的真实dom里可能还有dom节点)
|
||||
if(isUndef(oldVnode.child)&&isUndef(newVnode.child)&&isUndef(oldVnode.children)&&isUndef(newVnode.children)){
|
||||
//比较真实的dom
|
||||
diffRealNode(oldVnode.elm,newVnode.elm,diffNode);
|
||||
|
||||
if(isDef(oldVnode.text)&&isDef(newVnode.text)){
|
||||
if(oldVnode.text!==newVnode.text){
|
||||
if(isDef(oldVnode.elm.style)){
|
||||
diffNode.oldNodeArray.push(oldVnode.elm);
|
||||
}else {
|
||||
diffNode.oldNodeArray.push(oldVnode.elm.parentNode);
|
||||
}
|
||||
if(isDef(newVnode.elm.style)){
|
||||
diffNode.nodeArray.push(newVnode.elm);
|
||||
}else {
|
||||
diffNode.nodeArray.push(newVnode.elm.parentNode);
|
||||
}
|
||||
}
|
||||
}else if(isDef(oldVnode.tag)&&isDef(newVnode.tag)){
|
||||
if(oldVnode.tag==='input'&&newVnode.tag==='input'){
|
||||
|
@ -309,6 +312,86 @@ function diffDetail(oldVnode,newVnode,diffNode){
|
|||
|
||||
}
|
||||
|
||||
function diffRealNode(oldNode,newNode,diffNode){
|
||||
let oldNodeLength = oldNode.childNodes.length;
|
||||
let newNodeLength = newNode.childNodes.length;
|
||||
let childrenLength = Math.min(oldNodeLength, newNodeLength);
|
||||
for (let i = 0; i < childrenLength; i++) {
|
||||
let oldnode = oldNode.childNodes[i]
|
||||
let newnode = newNode.childNodes[i]
|
||||
if(oldnode.childNodes.length>0&&newnode.childNodes.length>0){
|
||||
diffRealNode(oldnode,newnode,diffNode)
|
||||
}else {
|
||||
diffRealNodeDetail(oldnode,newnode,diffNode);
|
||||
}
|
||||
}
|
||||
for (let i = childrenLength; i < oldNodeLength; i++) {
|
||||
if(oldNode.childNodes[i]){
|
||||
if(isDef(oldNode.childNodes[i].data)){
|
||||
if(oldNode.childNodes[i].data!=="\n"){
|
||||
diffNode.oldNodeArray.push(oldNode.childNodes[i]);
|
||||
}
|
||||
}else {
|
||||
diffNode.oldNodeArray.push(oldNode.childNodes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i = childrenLength; i < newNodeLength; i++) {
|
||||
if(newNode.childNodes[i]){
|
||||
if(isDef(newNode.childNodes[i].data)){
|
||||
if(newNode.childNodes[i].data!=="\n"){
|
||||
diffNode.nodeArray.push(newNode.childNodes[i]);
|
||||
}
|
||||
}else {
|
||||
diffNode.nodeArray.push(newNode.childNodes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function diffRealNodeDetail(oldNode,newNode,diffNode){
|
||||
if(!sameNode(oldNode,newNode)){
|
||||
if(isDef(oldNode.data)){
|
||||
if(oldNode.data!=="\n"){
|
||||
diffNode.oldNodeArray.push(oldNode);
|
||||
}
|
||||
}else {
|
||||
diffNode.oldNodeArray.push(oldNode);
|
||||
}
|
||||
if(isDef(newNode.data)){
|
||||
if(newNode.data!=="\n"){
|
||||
diffNode.nodeArray.push(newNode);
|
||||
}
|
||||
}else {
|
||||
diffNode.nodeArray.push(newNode);
|
||||
}
|
||||
}else{
|
||||
//如果是相同的,但是这时候新旧节点有一个的length一定为0,所以要处理剩下的
|
||||
if(oldNode.childNodes.length>0){
|
||||
for (let i = 0; i < oldNode.childNodes.length; i++){
|
||||
if(isDef(oldNode.childNodes[i].data)){
|
||||
if(oldNode.childNodes[i].data!=="\n"){
|
||||
diffNode.oldNodeArray.push(oldNode.childNodes[i]);
|
||||
}
|
||||
}else {
|
||||
diffNode.oldNodeArray.push(oldNode.childNodes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(newNode.childNodes.length>0){
|
||||
for (let i = 0; i < newNode.childNodes.length; i++){
|
||||
if(isDef(newNode.childNodes[i].data)){
|
||||
if(newNode.childNodes[i].data!=="\n"){
|
||||
diffNode.nodeArray.push(newNode.childNodes[i]);
|
||||
}
|
||||
}else {
|
||||
diffNode.nodeArray.push(newNode.childNodes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sameVnode (a, b) {
|
||||
return (
|
||||
a.key === b.key &&
|
||||
|
@ -326,6 +409,15 @@ function sameVnode (a, b) {
|
|||
)
|
||||
}
|
||||
|
||||
function sameNode (a, b) {
|
||||
return (
|
||||
(isDef(a.data) === isDef(b.data) &&a.data===b.data&&isDef(a.nodeValue) === isDef(b.nodeValue) &&a.nodeValue===b.nodeValue)||(
|
||||
isUndef(a.data)&&isUndef(b.data)&&isUndef(a.nodeValue)&&isUndef(b.nodeValue)&&
|
||||
isDef(a.textContent) === isDef(b.textContent)&&a.textContent===b.textContent
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
function findRowVnodeElm(nodeElm){
|
||||
if(nodeElm.localName==="td"||nodeElm.className==="cell"){
|
||||
return findRowVnodeElm(nodeElm.parentNode)
|
||||
|
|
Loading…
Reference in New Issue