Skip to content

Commit

Permalink
feat: Support Vue.js 3
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Drop support for Vue.js 2.
  • Loading branch information
wolfgangwalther committed Dec 7, 2024
1 parent 814def4 commit ddb9080
Show file tree
Hide file tree
Showing 10 changed files with 512 additions and 694 deletions.
8 changes: 0 additions & 8 deletions .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@
"matchUpdateTypes": ["patch", "minor"],
"groupName": "devDependencies"
},
{
"matchPackageNames": ["@vue/test-utils"],
"allowedVersions": "<2.0.0"
},
{
"matchPackageNames": ["vue"],
"allowedVersions": "<3.0.0"
},
{
"matchUpdateTypes": ["minor", "patch", "pin", "digest"],
"automerge": true
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Dependabot](https://img.shields.io/badge/dependabot-enabled-success)](https://github.com/technowledgy/vue-h5p/blob/main/package.json)
[![License](https://img.shields.io/npm/l/vue-h5p)](https://github.com/technowledgy/vue-h5p/blob/main/LICENSE)
[![npm](https://img.shields.io/npm/v/vue-h5p)](https://www.npmjs.com/package/vue-h5p)
![vue](https://img.shields.io/badge/vue-2.x-brightgreen)
![vue](https://img.shields.io/badge/vue-3.x-brightgreen)

</div>

Expand Down
10 changes: 4 additions & 6 deletions example/main.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import Vue from 'vue'
import { createApp, h } from 'vue'
import Example from './Example.vue'

Vue.config.productionTip = false

new Vue({
render: h => h(Example)
}).$mount('#app')
createApp({
render: () => h(Example)
}).mount('#app')
3 changes: 2 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default {
],
testEnvironment: 'jsdom',
testEnvironmentOptions: {
customExportConditions: ['node', 'node-addons'],
resources: new LocalFileLoader(),
runScripts: 'dangerously'
},
Expand All @@ -50,7 +51,7 @@ export default {
],
transform: {
'/frame/': '<rootDir>/jest-raw-loader.js',
'^.+\\.vue$': '@vue/vue2-jest',
'^.+\\.vue$': '@vue/vue3-jest',
'^.+\\.js$': 'babel-jest'
},
watchPlugins: [
Expand Down
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
"devDependencies": {
"@babel/eslint-parser": "7.25.9",
"@babel/preset-env": "7.26.0",
"@vitejs/plugin-vue": "5.2.1",
"@vue/eslint-config-standard": "8.0.1",
"@vue/test-utils": "1.3.6",
"@vue/vue2-jest": "29.2.6",
"@vue/test-utils": "2.4.6",
"@vue/vue3-jest": "29.2.6",
"babel-jest": "29.7.0",
"core-js": "3.39.0",
"coveralls": "3.1.1",
Expand All @@ -45,9 +46,7 @@
"rollup-plugin-string": "3.0.0",
"semantic-release": "24.2.0",
"vite": "6.0.3",
"vite-plugin-vue2": "2.0.3",
"vue": "2.7.16",
"vue-template-compiler": "2.7.16"
"vue": "3.5.13"
},
"resolutions": {
"whatwg-url": "14.1.0"
Expand Down
13 changes: 12 additions & 1 deletion src/h5p.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ export default {
validator: (val) => val ? ['mail,name', 'homePage,name'].includes(Object.keys(val).sort().join(',')) : true
}
},
emits: [
'height-changed',
'ready',
// h5p events from https://h5p.org/events
'xapi',
'resize',
'enterfullscreen',
'exitfullscreen',
'focus',
'domchanged'
],
data () {
return {
loading: true,
Expand All @@ -98,7 +109,7 @@ export default {
this.$emit('height-changed', newHeight)
}
},
beforeDestroy () {
beforeUnmount () {
window.removeEventListener('message', this.onMessage)
this.resizeObserver?.disconnect()
},
Expand Down
12 changes: 6 additions & 6 deletions tests/unit/__snapshots__/h5p.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1005,25 +1005,25 @@ exports[`Component iframe without version in library paths 1`] = `
`;
exports[`Component renders default slot content while loading: should have default slot content on top of iframe content 1`] = `
<div><iframe allow="fullscreen none" style="width: 100%; height: 100%;"></iframe>
<!---->
<div><iframe style="width: 100%; height: 100%;" allow="fullscreen none"></iframe>
<!--v-if-->
</div>
`;
exports[`Component renders default slot content while loading: should have only default slot content 1`] = `
<div>
<!----> hello from the DEFAULT slot
<!--v-if-->hello from the DEFAULT slot
</div>
`;
exports[`Component renders default slot content while loading: should have only iframe content 1`] = `
<div><iframe allow="fullscreen none" style="width: 100%; height: 100%;"></iframe>
<!---->
<div><iframe style="width: 100%; height: 100%;" allow="fullscreen none"></iframe>
<!--v-if-->
</div>
`;
exports[`Component renders error slot on fetch-errors and provides response object: should have error slot content 1`] = `
<div>
<!----> hello from the ERROR slot: FetchError: Not Found
<!--v-if-->hello from the ERROR slot: FetchError: Not Found
</div>
`;
76 changes: 39 additions & 37 deletions tests/unit/h5p.spec.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import Vue from 'vue'
import { shallowMount } from '@vue/test-utils'
import flushPromises from 'flush-promises'

const warnHandler = jest.fn()
Vue.config.warnHandler = (msg) => warnHandler(msg)

const resizeObserver = jest.fn()
const observe = jest.fn()
const disconnect = jest.fn()
Expand All @@ -14,53 +11,58 @@ global.ResizeObserver = resizeObserver.mockImplementation(() => ({
disconnect
}))

jest.doMock('../frame/style?raw', () => {
return '/* MOCKED_FRAME_CSS */'
}, {
virtual: true
})

jest.doMock('../frame/script.cjs?raw', () => {
return `
var callback;
H5P.externalDispatcher = { on: (_, cb) => { callback = cb }, trigger: (type, data) => callback({ type, data }) };
window.top.postMessage({ context: "h5p", action: "hello" }, "*");
H5P.instances = [Symbol("instance")];
var lastTrigger;
H5P.trigger = (instance, action) => { lastTrigger = { instance, action }};
`
}, {
virtual: true
})

function sleep (ms = 1000) {
return new Promise((resolve) => {
setTimeout(resolve, ms)
})
}

function createComponent (props) {
const h5p = require('@/h5p.vue').default
return shallowMount(h5p, {
attachTo: document.body,
propsData: props,
scopedSlots: {
default: () => 'hello from the DEFAULT slot',
error: ({ error }) => `hello from the ERROR slot: ${error}`
}
})
}

describe('Component', () => {
const h5p = require('@/h5p.vue').default
let wrapper

function createComponent (props) {
return shallowMount(h5p, {
attachTo: document.body,
props,
slots: {
default: () => 'hello from the DEFAULT slot',
error: ({ error }) => `hello from the ERROR slot: ${error}`
},
global: {
config: {
warnHandler: (msg) => warnHandler(msg)
}
}
})
}

beforeEach(() => {
// just reset .mock data, but not .mockResponse
fetch.mockClear()

jest.doMock('../frame/style?raw', () => {
return '/* MOCKED_FRAME_CSS */'
}, {
virtual: true
})

jest.doMock('../frame/script.cjs?raw', () => {
return `
var callback;
H5P.externalDispatcher = { on: (_, cb) => { callback = cb }, trigger: (type, data) => callback({ type, data }) };
window.top.postMessage({ context: "h5p", action: "hello" }, "*");
H5P.instances = [Symbol("instance")];
var lastTrigger;
H5P.trigger = (instance, action) => { lastTrigger = { instance, action }};
`
}, {
virtual: true
})
})

afterEach(() => {
wrapper.destroy()
wrapper.unmount()
jest.resetModules()
})

Expand Down Expand Up @@ -100,7 +102,7 @@ describe('Component', () => {
await flushPromises()
await sleep()
expect(fetch).toHaveBeenCalledWith('/hello-world/h5p.json', expect.anything())
wrapper.destroy()
wrapper.unmount()
fetch.mockClear()

wrapper = createComponent({
Expand Down Expand Up @@ -137,7 +139,7 @@ describe('Component', () => {
})
await flushPromises()
await sleep()
wrapper.destroy()
wrapper.unmount()
expect(disconnect).toHaveBeenCalledTimes(1)
})

Expand Down
4 changes: 2 additions & 2 deletions vite.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { fileURLToPath } from 'url'
import { dirname, resolve } from 'path'
import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import vue from '@vitejs/plugin-vue'
import copy from 'rollup-plugin-copy'
import del from 'rollup-plugin-delete'

Expand Down Expand Up @@ -61,7 +61,7 @@ const defaultConfig = defineConfig({
sourcemap: true
},
plugins: [
createVuePlugin(),
vue(),
copy({
targets: [
{ src: 'package.json.cjs', dest: 'dist/cjs', rename: 'package.json' }
Expand Down
Loading

0 comments on commit ddb9080

Please sign in to comment.