feat(接口定义): 版本对比

--user=郭雨琦 接口定义版本对比第一版
This commit is contained in:
guoyuqi 2021-12-30 19:26:44 +08:00 committed by song-tianyang
parent 51fbe8e2d5
commit dab9c08ee6
3 changed files with 589 additions and 21 deletions

View File

@ -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];

View File

@ -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>

View File

@ -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)