blob: d0e5a5457758a9e87d10d6c8931561382fc9f127 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import chai from 'chai'
const { expect } = chai
import {
createElement,
createBlock,
createBody,
attachTarget,
moveTarget,
removeTarget
} from '../../../../../runtime/frameworks/legacy/vm/dom-helper'
import { Document } from '../../../../../runtime/vdom'
import Listener from '../../../../../runtime/bridge/Listener'
describe('help create body', () => {
let vm
beforeEach(() => {
vm = {
_app: { doc: new Document('foo', null, null, Listener) }
}
})
afterEach(() => {
vm._app.doc.destroy()
vm = null
})
it('create body with type', () => {
const result = createBody(vm, 'bar')
expect(result).is.an.object
expect(result.type).eql('bar')
expect(result.ref).eql('_root')
expect(result.docId).is.not.ok
})
})
describe('help create element', () => {
let vm
beforeEach(() => {
vm = {
_app: { doc: new Document('foo', null, null, Listener) }
}
})
afterEach(() => {
vm._app.doc.destroy()
vm = null
})
it('create element with type', () => {
const result = createElement(vm, 'bar')
expect(result).is.an.object
expect(result.type).eql('bar')
expect(result.docId).is.not.ok
})
})
describe('help create block', () => {
let vm
beforeEach(() => {
vm = {
_app: { doc: new Document('foo', null, null, Listener) }
}
})
afterEach(() => {
vm._app.doc.destroy()
vm = null
})
it('create block with element', () => {
const element = vm._app.doc.createElement('bar')
const result = createBlock(vm, element)
expect(result).is.an.object
expect(result.start).is.an.object
expect(result.end).is.an.object
expect(result.start.type).eql('comment')
expect(result.end.type).eql('comment')
expect(result.start.value).eql('start')
expect(result.end.value).eql('end')
expect(result.element).equal(element)
expect(result.element.children).eql([result.start, result.end])
})
})
describe('help attach target', () => {
let vm
beforeEach(() => {
vm = {
_app: { doc: new Document('foo', null, null, Listener) }
}
})
afterEach(() => {
vm._app.doc.destroy()
vm = null
})
it('attach body to documentElement', () => {
const oriCallnative = global.callNative
global.callNative = function () {}
const target = createBody(vm, 'bar')
const dest = vm._app.doc.documentElement
attachTarget(vm, target, dest)
expect(dest.children).eql([target])
global.callNative = oriCallnative
})
it('attach element to body', () => {
const target = createElement(vm, 'bar')
const dest = createBody(vm, 'baz')
attachTarget(vm, target, dest)
expect(dest.children).eql([target])
})
it('attach element to element', () => {
const target = createElement(vm, 'bar')
const dest = createElement(vm, 'baz')
attachTarget(vm, target, dest)
expect(dest.children).eql([target])
})
it('attach block to element', () => {
const parent = createElement(vm, 'bar')
const target = createBlock(vm, parent)
const dest = createElement(vm, 'baz')
attachTarget(vm, target, dest)
// block can't attach to another element
expect(dest.children).eql([])
expect(parent.children).eql([target.start, target.end])
})
it('attach element to block', () => {
const target = createElement(vm, 'bar')
const parent = createElement(vm, 'baz')
const dest = createBlock(vm, parent)
attachTarget(vm, target, dest)
expect(parent.children).eql([dest.start, target, dest.end])
})
it('attach block to block', () => {
const element = createElement(vm, 'bar')
const target = createBlock(vm, element)
const parent = createElement(vm, 'baz')
const dest = createBlock(vm, parent)
attachTarget(vm, target, dest)
// block can't attach to another element
expect(parent.children).eql([dest.start, dest.end])
expect(element.children).eql([target.start, target.end])
})
it('attach element to block with an update mark', () => {
const target = createElement(vm, 'bar')
const parent = createElement(vm, 'baz')
const dest = createBlock(vm, parent)
const mark = createElement(vm, 'qux')
attachTarget(vm, target, dest)
attachTarget(vm, mark, dest)
expect(parent.children).eql([dest.start, target, mark, dest.end])
dest.updateMark = mark
attachTarget(vm, target, dest)
expect(parent.children).eql([dest.start, mark, target, dest.end])
expect(dest.updateMark).eql(target)
})
it('attach block to block with an update mark', () => {
const element = createElement(vm, 'bar')
const target = createBlock(vm, element)
const parent = createElement(vm, 'baz')
const dest = createBlock(vm, parent)
const mark = createElement(vm, 'qux')
attachTarget(vm, target, dest)
attachTarget(vm, mark, dest)
// block can't attach to another element
expect(parent.children).eql([dest.start, mark, dest.end])
expect(element.children).eql([target.start, target.end])
dest.updateMark = mark
attachTarget(vm, target, dest)
// block can't attach to another element
expect(parent.children).eql([dest.start, mark, dest.end])
expect(element.children).eql([target.start, target.end])
})
})
describe('help move target', () => {
let vm, parent, dest, target1, block1, target2, block2, target3, block3
beforeEach(() => {
vm = {
_app: { doc: new Document('foo', null, null, Listener) }
}
parent = createElement(vm, 'r')
dest = createBlock(vm, parent)
target1 = createElement(vm, 't1')
attachTarget(vm, target1, dest)
block1 = createBlock(vm, dest)
target2 = createElement(vm, 't2')
attachTarget(vm, target2, dest)
block2 = createBlock(vm, dest)
target3 = createElement(vm, 't3')
attachTarget(vm, target3, block2)
block3 = createBlock(vm, block2)
})
afterEach(() => {
vm._app.doc.destroy()
vm = null
})
it('move an element to an element mark', () => {
/* eslint-disable indent */
expect(parent.children).eql([
dest.start,
target1, block1.start, block1.end,
target2, block2.start,
target3, block3.start, block3.end,
block2.end,
dest.end])
/* eslint-enable indent */
const mark = target2
dest.updateMark = mark
moveTarget(vm, target1, mark)
/* eslint-disable indent */
expect(parent.children).eql([
dest.start,
block1.start, block1.end,
target2, target1, block2.start,
target3, block3.start, block3.end,
block2.end,
dest.end])
/* eslint-enable indent */
})
it('move an element to a block mark', () => {
const mark = block2.end
dest.updateMark = mark
moveTarget(vm, target1, mark)
/* eslint-disable indent */
expect(parent.children).eql([
dest.start,
block1.start, block1.end,
target2, block2.start,
target3, block3.start, block3.end,
block2.end, target1,
dest.end])
/* eslint-enable indent */
})
it('move a block to an element mark', () => {
const mark = target2
dest.updateMark = mark
moveTarget(vm, block1, mark)
/* eslint-disable indent */
expect(parent.children).eql([
dest.start,
target1,
target2, block1.start, block1.end,
block2.start,
target3, block3.start, block3.end,
block2.end,
dest.end])
/* eslint-enable indent */
})
it('move a block to a block mark', () => {
const mark = block2.end
dest.updateMark = mark
moveTarget(vm, block1, mark)
/* eslint-disable indent */
expect(parent.children).eql([
dest.start,
target1,
target2,
block2.start,
target3, block3.start, block3.end,
block2.end, block1.start, block1.end,
dest.end])
/* eslint-enable indent */
})
it('move a whole block to a block mark', () => {
const mark = block1.end
dest.updateMark = mark
moveTarget(vm, block2, mark)
/* eslint-disable indent */
expect(parent.children).eql([
dest.start,
target1, block1.start, block1.end,
block2.start,
target3, block3.start, block3.end,
block2.end,
target2,
dest.end])
/* eslint-enable indent */
})
})
describe('help remove target', () => {
let vm
beforeEach(() => {
vm = {
_app: { doc: new Document('foo', null, null, Listener) }
}
})
afterEach(() => {
vm._app.doc.destroy()
vm = null
})
it('remove body', () => {
const oriCallnative = global.callNative
global.callNative = function () {}
const parent = vm._app.doc.documentElement
const element = createBody(vm, 'baz')
parent.appendChild(element)
expect(parent.children).eql([element])
removeTarget(vm, element)
expect(parent.children).eql([])
global.callNative = oriCallnative
})
it('remove element', () => {
const parent = createElement(vm, 'bar')
const element = createElement(vm, 'baz')
parent.appendChild(element)
expect(parent.children).eql([element])
removeTarget(vm, element)
expect(parent.children).eql([])
})
it('remove block', () => {
const element = createElement(vm, 'baz')
const prevElement = createElement(vm, 'prev')
const nextElement = createElement(vm, 'next')
const parent = createElement(vm, 'bar')
attachTarget(vm, prevElement, parent)
const block = createBlock(vm, parent)
attachTarget(vm, element, block)
attachTarget(vm, nextElement, parent)
expect(parent.children).eql([
prevElement, block.start, element, block.end, nextElement])
removeTarget(vm, block)
expect(parent.children).eql([
prevElement, nextElement])
})
it('remove block but preserved itself', () => {
const element = createElement(vm, 'baz')
const prevElement = createElement(vm, 'prev')
const nextElement = createElement(vm, 'next')
const parent = createElement(vm, 'bar')
attachTarget(vm, prevElement, parent)
const block = createBlock(vm, parent)
attachTarget(vm, element, block)
attachTarget(vm, nextElement, parent)
expect(parent.children).eql([
prevElement, block.start, element, block.end, nextElement])
removeTarget(vm, block, true)
expect(parent.children).eql([
prevElement, block.start, block.end, nextElement])
})
})