diff --git a/package.json b/package.json index 214a72b..059106c 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,10 @@ ], "scripts": { "dev": "vite", - "build": "yarn run esbuild:ts && yarn run build:ts", + "build": "yarn run esbuild:ts && yarn run build:ts && yarn build:widgets", "build:ts": "yarn tsc --build tsconfig-all.json", - "build:vite": "vite build", - "build:widgets": "bin/build-widget", + "build:vite": "vite build && yarn build:widgets", + "build:widgets": "node ./tasks/build-widgets.js", "esbuild:ts": "node ./tasks/esbuild-packages.js", "format": "npm run format:prettier", "format:prettier": "prettier \"**/*.{cjs,html,js,json,md,ts}\" --write" diff --git a/src/components/grid-container/container-style.ts b/src/components/grid-container/container-style.ts index c9c69c6..907601a 100644 --- a/src/components/grid-container/container-style.ts +++ b/src/components/grid-container/container-style.ts @@ -4,8 +4,8 @@ export default css` :host { position: relative; display: block; - margin-top: var(--container-margin-top); - margin-left: var(--container-margin-left); + margin-top: var(--container-margin-top, 0px); + margin-left: var(--container-margin-left, 0px); width: 100%; height: 100%; @@ -31,11 +31,8 @@ export default css` ::slotted(.gaia-container-page) { display: grid; - grid-template-columns: repeat( - var(--columns, 4), - calc(100% / var(--columns, 4)) - ); - grid-template-rows: repeat(var(--rows, 6), calc(100% / var(--rows, 6))); + grid-template-columns: repeat(var(--columns, 4), var(--grid-width)); + grid-template-rows: repeat(var(--rows, 6), var(--grid-height)); grid-auto-flow: row dense; grid-auto-rows: 33%; diff --git a/src/components/grid-container/container.ts b/src/components/grid-container/container.ts index 83c77a6..bb7c126 100644 --- a/src/components/grid-container/container.ts +++ b/src/components/grid-container/container.ts @@ -95,7 +95,9 @@ const cubic_bezier = ( class GaiaContainer extends StarBaseElement { name: string = 'gaia-container' row: number = 6 + _row: number = this.row column: number = 4 + _column: number = this.column _frozen: boolean = false ready: boolean = false _pendingStateChanges: Function[] = [] @@ -225,8 +227,8 @@ class GaiaContainer extends StarBaseElement { exchangeTimer: number | undefined constructor(row = 6, column = 4) { super() - this.row = row - this.column = column + this.row = this._row = row + this.column = this._column = column this.exchangeStratege = new ExchangeStrategy(this) this.startGestureDetector({ panThreshold: 0, @@ -501,12 +503,25 @@ class GaiaContainer extends StarBaseElement { // TODO:用于适应旋转屏幕时,改变行数与列数,需要配合row、column属性 changeLayout = () => { // this.styleDom.innerHTML = this.shadowStyle; + // 更新位置与高度信息 const {height, width, top, left} = this.getBoundingClientRect() this.height = height this.width = width this.top = top this.left = left + if (screen.orientation.type.includes('portrait')) { + this.style.setProperty('--columns', String(this._column)) + this.style.setProperty('--rows', String(this._row)) + this.row = this._row + this.column = this._column + } else { + this.style.setProperty('--rows', String(this._column)) + this.style.setProperty('--columns', String(this._row)) + this.row = this._column + this.column = this._row + } + this.pageWidth = this.pages.length ? this.pages[0].offsetWidth : 0 this.pageHeight = this.pages.length ? this.pages[0].offsetHeight : 0 this.gridHeight = this.pageHeight / this.row @@ -516,13 +531,6 @@ class GaiaContainer extends StarBaseElement { this.style.setProperty('--page-height', this.pageHeight + 'px') this.style.setProperty('--grid-height', this.gridHeight + 'px') this.style.setProperty('--grid-width', this.gridWidth + 'px') - if (screen.orientation.type.includes('portrait')) { - this.style.setProperty('--columns', String(this.column)) - this.style.setProperty('--rows', String(this.row)) - } else { - this.style.setProperty('--rows', String(this.column)) - this.style.setProperty('--columns', String(this.row)) - } // this._children.forEach((child) => child.changeSize()) this.synchronise() @@ -674,18 +682,18 @@ class GaiaContainer extends StarBaseElement { if (!page) { page = this.addPage() } - const shadowPage = this.pages._shadowPagesMap.get(page) let proto = HTMLElement.prototype.appendChild let func Array.prototype.forEach.call(args, (element) => { + const retainAfterRotate = this.appendShadowPage(element, page) func = proto.call(page, element) - proto.call(shadowPage, this.getChildByElement(element)?.shadowContainer!) // 判断插入节点后是否会越界 - if (page.offsetHeight < page.scrollHeight) { + if (page.offsetHeight < page.scrollHeight || !retainAfterRotate) { // 越界后判断是否需要重新拿出来放入下一个页面 if (this._status & STATUS.DRAG) { // 如果是拖拽中的元素,则返回原位,同时记录本页面无法插入 + // TODO: 拖拽中的元素应该强制放入 if (!this._staticElements.includes(page)) { this._staticElements.push(page) } @@ -711,6 +719,8 @@ class GaiaContainer extends StarBaseElement { let func Array.from(args).forEach((element) => { const target = element.parentNode + const child = this.getChildByElement(element) + child?.shadowContainer?.remove() let proto = HTMLElement.prototype.removeChild func = proto.call(target, element) @@ -727,8 +737,12 @@ class GaiaContainer extends StarBaseElement { const nodes = args as unknown as [HTMLElement, HTMLElement] let proto = HTMLElement.prototype.insertBefore let func = proto.apply(targetParent, nodes) + const retainAfterRotate = this.appendShadowPage(nodes[0], targetParent) // 判断插入节点后是否会越界 - if (targetParent.offsetHeight < targetParent.scrollHeight) { + if ( + targetParent.offsetHeight < targetParent.scrollHeight || + !retainAfterRotate + ) { this.insertCrossBorder(...nodes) } return func @@ -745,14 +759,18 @@ class GaiaContainer extends StarBaseElement { if (!targetParent) throw new Error('parentElement does not exist!') let func if (targetParent.lastChild == args[1]) { - func = append.call(targetParent, arguments[0]) + func = append.call(targetParent, args[0]) } else { - func = insert.call(targetParent, arguments[0], arguments[1].nextSibling) + func = insert.call(targetParent, args[0], args[1].nextSibling) } + const retainAfterRotate = this.appendShadowPage(args[0], targetParent) // 判断插入节点后是否会越界 - if (targetParent.offsetHeight < targetParent.scrollHeight) { - this.insertCrossBorder(...arguments) + if ( + targetParent.offsetHeight < targetParent.scrollHeight || + !retainAfterRotate + ) { + this.insertCrossBorder(...args) } return func @@ -791,6 +809,26 @@ class GaiaContainer extends StarBaseElement { return this.realAppendChild(this.pagination + 1, args[0]) } + /** + * 为影子页面添加子节点,若越界,则表示旋转屏幕后也会越界 + * @returns boolean + */ + appendShadowPage(element: HTMLElement, page: HTMLElement) { + const shadowPage = this.pages._shadowPagesMap.get(page)! + const shadowChild = this.getChildByElement(element)?.shadowContainer! + if (!shadowPage || !shadowChild) { + return false + } + + shadowPage.appendChild(shadowChild) + if (shadowPage.offsetHeight < shadowPage.scrollHeight) { + shadowPage.removeChild(shadowChild) + return false + } else { + return true + } + } + realReplaceChild(...args: [HTMLElement, HTMLElement]) { let proto = HTMLElement.prototype.replaceChild let func = proto.apply(this, args) @@ -918,11 +956,6 @@ class GaiaContainer extends StarBaseElement { this.pageHeight = page.offsetHeight this.gridHeight = this.pageHeight / this.row this.gridWidth = this.pageWidth / this.column - - this.style.setProperty('--page-width', this.pageWidth + 'px') - this.style.setProperty('--page-height', this.pageHeight + 'px') - this.style.setProperty('--grid-height', this.gridHeight + 'px') - this.style.setProperty('--grid-width', this.gridWidth + 'px') } return page } @@ -1699,10 +1732,8 @@ class GaiaContainer extends StarBaseElement { gridId: number ) { let resolve!: Function - let reject!: Function - let promise = new Promise((res, rej) => { + let promise = new Promise((res) => { resolve = res - reject = rej }) for (let row = 0; row < child.row; row++) { @@ -1712,7 +1743,6 @@ class GaiaContainer extends StarBaseElement { this.childCoordinate[pagination][targetId] != undefined && this.childCoordinate[pagination][targetId] != child ) { - reject() return false } promise.then(() => { @@ -2262,9 +2292,6 @@ class GaiaContainer extends StarBaseElement { child.synchroniseMaster() // } } - if (Object.keys(this.folders).length) { - // debugger - } for (let i = 0; i < children.length; i++) { child = children[i] @@ -2274,6 +2301,7 @@ class GaiaContainer extends StarBaseElement { if (!child.synchroniseContainer(isActive)) { return } + child.anchor() // 越界 // if (!isActive) { diff --git a/src/components/grid-container/gaia-container-child.ts b/src/components/grid-container/gaia-container-child.ts index 7337b6f..5a424b7 100644 --- a/src/components/grid-container/gaia-container-child.ts +++ b/src/components/grid-container/gaia-container-child.ts @@ -169,7 +169,7 @@ export default class GaiaContainerChild { * 按记录的锚固坐标,将元素锚固到 Grid 网格中 */ anchor(type: anchorType = 'recorder') { - const area = this.getArea(type) + const area = this.setArea(type) if (!area) return const [rowStart, columnStart] = area @@ -194,14 +194,12 @@ export default class GaiaContainerChild { return this.anchorCoordinate[orientation] } - const unitHeight = this.master.offsetHeight / this.row - const unitWidth = this.master.offsetWidth / this.column const offsetTop = Math.abs(this.master.offsetTop) const offsetLeft = Math.abs( this.master.offsetLeft - this.pagination * this.manager.pageHeight ) - const rowStart = Math.floor(offsetTop / unitHeight) + 1 - const columnStart = Math.floor(offsetLeft / unitWidth) + 1 + const rowStart = Math.floor(offsetTop / this.manager.gridHeight) + 1 + const columnStart = Math.floor(offsetLeft / this.manager.gridWidth) + 1 return [rowStart, columnStart] } @@ -220,8 +218,8 @@ export default class GaiaContainerChild { * 解除元素的锚固 */ loosen() { - const orientation = screen.orientation.type.split('-')[0] - this.anchorCoordinate[orientation] = null + // const orientation = screen.orientation.type.split('-')[0] + // this.anchorCoordinate[orientation] = null this.master.style.gridArea = 'unset' this.master.style.gridRowStart = `span ${this.row}` this.master.style.gridColumnStart = `span ${this.column}` diff --git a/tasks/build-widgets.js b/tasks/build-widgets.js new file mode 100644 index 0000000..ab63ef0 --- /dev/null +++ b/tasks/build-widgets.js @@ -0,0 +1,77 @@ +import fs from 'fs' +import {build} from 'vite' +const PWD = process.cwd() + +const clearDir = (path, exclude) => { + var files = [] + + if (fs.existsSync(path)) { + files = fs.readdirSync(path) + + for (const file of files) { + if (file === exclude) continue + var curPath = path + '/' + file + + if (fs.statSync(curPath).isDirectory()) { + clearDir(curPath) + fs.rmdirSync(curPath) + } else { + fs.unlinkSync(curPath) + } + } + } +} + +const fun = async (widgetName, entryName) => { + await build({ + build: { + lib: { + entry: `src/widgets/${widgetName}/${entryName}.ts`, + formats: ['es'], + fileName: `${widgetName}`, + }, + outDir: `dist/widgets/${widgetName}/`, + }, + }) + + clearDir(`dist/widgets/${widgetName}`, `${widgetName}.js`) +} + +const safeReadDirSync = (path) => { + let dirData = {} + try { + dirData = fs.readdirSync(path) + } catch (ex) { + if (ex.code == 'EACCES' || ex.code == 'EPERM') { + // 无权访问该文件夹,跳过 + return null + } else { + throw ex + } + } + + return dirData +} + +const buildAll = () => { + const widgetsFilePath = `${PWD}/src/widgets` + const dirData = safeReadDirSync(widgetsFilePath) + + dirData?.forEach((fileName) => { + const widgetPath = `${widgetsFilePath}/${fileName}` + const stats = fs.statSync(widgetPath) + + if (stats.isDirectory()) { + const files = safeReadDirSync(widgetPath) + if (files.includes(`${fileName}.ts`)) { + fun(fileName, fileName) + } else if (files.includes(`index.ts`)) { + fun(fileName, 'index') + } else { + throw new Error(`Entry file of ${fileName} widget dose not exist!`) + } + } + }) +} + +buildAll() diff --git a/widgets.config.ts b/widgets.config.ts deleted file mode 100644 index 76d456b..0000000 --- a/widgets.config.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {defineConfig} from 'vite' - -// https://vitejs.dev/config/ -export default defineConfig({ - build: { - lib: { - entry: `src/widgets/${process.env.WIDGET_FILE_NAME}/${process.env.WIDGET_FILE_NAME}.ts`, - formats: ['es'], - fileName: `${process.env.WIDGET_FILE_NAME}`, - }, - outDir: `dist/widgets/${process.env.WIDGET_FILE_NAME}/`, - }, -})