From e4045b49e4c6d4e8f6a7f49f9f1c7b07ff3a5c44 Mon Sep 17 00:00:00 2001 From: zealotchen Date: Fri, 23 Aug 2024 17:20:23 +0800 Subject: [PATCH 1/4] feat(vue-next): fix beforeLoadStyle not work --- .../hippy-vue-next-demo/src/main-native.ts | 19 +++++++++++++++++++ .../src/style-match/css-map.ts | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/examples/hippy-vue-next-demo/src/main-native.ts b/examples/hippy-vue-next-demo/src/main-native.ts index c5a252d7d96..5e08b03b921 100644 --- a/examples/hippy-vue-next-demo/src/main-native.ts +++ b/examples/hippy-vue-next-demo/src/main-native.ts @@ -47,6 +47,25 @@ const app: HippyApp = createApp(App, { * default is true, if set false, it will follow vue-loader compilerOptions whitespace setting */ trimWhitespace: true, + styleOptions: { + beforeLoadStyle: (decl) => { + let { value } = decl; + // 比如可以对 rem 单位进行处理 + if (typeof value === 'string' && /rem$/.test(value)) { + // get the numeric value of rem + + const { screen } = Native.Dimensions; + // 比如可以对 rem 单位进行处理 + if (typeof value === 'string' && /rem$/.test(value)) { + const { width, height } = screen; + // 防止hippy 旋转后,宽度发生变化 + const realWidth = width > height ? width : height; + value = Number(parseFloat(`${(realWidth * 100 * Number(value.replace('rem', ''))) / 844}`).toFixed(2)); + } + } + return { ...decl, value }; + }, + }, }); // create router const router = createRouter(); diff --git a/packages/hippy-vue-next-style-parser/src/style-match/css-map.ts b/packages/hippy-vue-next-style-parser/src/style-match/css-map.ts index 1d4f0373abc..29e021fa60a 100644 --- a/packages/hippy-vue-next-style-parser/src/style-match/css-map.ts +++ b/packages/hippy-vue-next-style-parser/src/style-match/css-map.ts @@ -220,7 +220,7 @@ export function getCssMap( * Here is a secret startup option: beforeStyleLoadHook. * Usage for process the styles while styles loading. */ - const cssRules = fromAstNodes(styleCssMap); + const cssRules = fromAstNodes(styleCssMap, beforeLoadStyle); if (globalCssMap) { globalCssMap.append(cssRules); } else { From 55b4d7a50010e7406ec74848b695a367f8147596 Mon Sep 17 00:00:00 2001 From: zealotchen Date: Wed, 23 Oct 2024 11:19:53 +0800 Subject: [PATCH 2/4] fix(web): fix webrender listview item relayout --- packages/hippy-web-renderer/src/component/list-view.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/hippy-web-renderer/src/component/list-view.ts b/packages/hippy-web-renderer/src/component/list-view.ts index 84a2b825cc6..0bcb4639293 100644 --- a/packages/hippy-web-renderer/src/component/list-view.ts +++ b/packages/hippy-web-renderer/src/component/list-view.ts @@ -570,7 +570,8 @@ export class ListViewItem extends HippyWebView { public handleReLayout(entries: ResizeObserverEntry[]) { const [entry] = entries; const { height } = entry.contentRect; - if ((height === 0 && Math.round(height) !== this.height) || Math.round(height) !== this.dom?.clientHeight) { + if ((Math.round(height) === this.height) && Math.round(height) === this.dom?.clientHeight) { + // no need to relayout ListViewItem when height is not changed return; } this.height = Math.round(height); From 8f8aae3f8ad592bbfca99eb7b48cc5e0500663fc Mon Sep 17 00:00:00 2001 From: zealotchen Date: Wed, 23 Oct 2024 11:28:09 +0800 Subject: [PATCH 3/4] fix(web): fix webrender not show when length is 1 --- .../src/third-lib/size-position-manager.js | 57 ++++++++----------- .../src/third-lib/virtual-list.js | 2 +- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/packages/hippy-web-renderer/src/third-lib/size-position-manager.js b/packages/hippy-web-renderer/src/third-lib/size-position-manager.js index 2775e8526ed..ddc01e6c990 100644 --- a/packages/hippy-web-renderer/src/third-lib/size-position-manager.js +++ b/packages/hippy-web-renderer/src/third-lib/size-position-manager.js @@ -24,7 +24,7 @@ export const ALIGN_START = 'start'; export const ALIGN_CENTER = 'center'; export const ALIGN_END = 'end'; -export default class SizePositionManager { +export default class SizeAndPositionManager { constructor({ itemCount, itemSizeGetter, @@ -50,20 +50,17 @@ export default class SizePositionManager { * It just-in-time calculates (or used cached values) for items leading up to the index. */ getSizeAndPositionForIndex(index) { - if (index < 0 || index >= this._itemCount&& this._itemCount!==0) { + if (index < 0 || index >= this._itemCount) { throw Error(`Requested index ${index} is outside of range 0..${this._itemCount}`); } - if(index === 0 && this._itemCount===0){ - return 0; - } if (index > this._lastMeasuredIndex) { - let lastMeasuredSizeAndPosition = this.getSizeAndPositionOfLastMeasuredItem(); - let offset = lastMeasuredSizeAndPosition.offset + - lastMeasuredSizeAndPosition.size; + const lastMeasuredSizeAndPosition = this.getSizeAndPositionOfLastMeasuredItem(); + let offset = lastMeasuredSizeAndPosition.offset + + lastMeasuredSizeAndPosition.size; for (let i = this._lastMeasuredIndex + 1; i <= index; i++) { - let size = this._itemSizeGetter({index: i}); + const size = this._itemSizeGetter({ index: i }); if (size == null || isNaN(size)) { throw Error(`Invalid size returned for index ${i} of value ${size}`); @@ -86,7 +83,7 @@ export default class SizePositionManager { getSizeAndPositionOfLastMeasuredItem() { return this._lastMeasuredIndex >= 0 ? this._itemSizeAndPositionData[this._lastMeasuredIndex] - : {offset: 0, size: 0}; + : { offset: 0, size: 0 }; } /** @@ -96,9 +93,7 @@ export default class SizePositionManager { */ getTotalSize() { const lastMeasuredSizeAndPosition = this.getSizeAndPositionOfLastMeasuredItem(); - if(this._lastMeasuredIndex === this._itemCount){ - return lastMeasuredSizeAndPosition.offset + lastMeasuredSizeAndPosition.size; - } + return lastMeasuredSizeAndPosition.offset + lastMeasuredSizeAndPosition.size + (this._itemCount - this._lastMeasuredIndex - 1) * this._estimatedItemSize; } @@ -107,7 +102,6 @@ export default class SizePositionManager { * * @param align Desired alignment within container; one of "start" (default), "center", or "end" * @param containerSize Size (width or height) of the container viewport - * @param targetIndex index target item * @return Offset to use to ensure the specified item is visible */ getUpdatedOffsetForIndex({ @@ -142,11 +136,11 @@ export default class SizePositionManager { return Math.max(0, Math.min(totalSize - containerSize, idealOffset)); } - getVisibleRange({containerSize, offset, overScanCount}) { + getVisibleRange({ containerSize, offset, overscanCount }) { const totalSize = this.getTotalSize(); if (totalSize === 0) { - return {start:0,stop:0}; + return {}; } const maxOffset = offset + containerSize; @@ -161,9 +155,9 @@ export default class SizePositionManager { offset += this.getSizeAndPositionForIndex(stop).size; } - if (overScanCount) { - start = Math.max(0, start - overScanCount); - stop = Math.min(stop + overScanCount, this._itemCount-1); + if (overscanCount) { + start = Math.max(0, start - overscanCount); + stop = Math.min(stop + overscanCount, this._itemCount); } return { @@ -181,7 +175,7 @@ export default class SizePositionManager { this._lastMeasuredIndex = Math.min(this._lastMeasuredIndex, index - 1); } - _binarySearch({low, high, offset}) { + _binarySearch({ low, high, offset }) { let middle; let currentOffset; @@ -191,7 +185,7 @@ export default class SizePositionManager { if (currentOffset === offset) { return middle; - } else if (currentOffset < offset) { + } if (currentOffset < offset) { low = middle + 1; } else if (currentOffset > offset) { high = middle - 1; @@ -203,12 +197,12 @@ export default class SizePositionManager { } } - _exponentialSearch({index, offset}) { + _exponentialSearch({ index, offset }) { let interval = 1; while ( - index < this._itemCount && - this.getSizeAndPositionForIndex(index).offset < offset + index < this._itemCount + && this.getSizeAndPositionForIndex(index).offset < offset ) { index += interval; interval *= 2; @@ -246,14 +240,13 @@ export default class SizePositionManager { low: 0, offset, }); - } else { - // If we haven't yet measured this high, fallback to an exponential search with an inner binary search. - // The exponential search avoids pre-computing sizes for the full set of items as a binary search would. - // The overall complexity for this approach is O(log n). - return this._exponentialSearch({ - index: lastMeasuredIndex, - offset, - }); } + // If we haven't yet measured this high, fallback to an exponential search with an inner binary search. + // The exponential search avoids pre-computing sizes for the full set of items as a binary search would. + // The overall complexity for this approach is O(log n). + return this._exponentialSearch({ + index: lastMeasuredIndex, + offset, + }); } } diff --git a/packages/hippy-web-renderer/src/third-lib/virtual-list.js b/packages/hippy-web-renderer/src/third-lib/virtual-list.js index 356cd1ba59a..f79ef38d06c 100644 --- a/packages/hippy-web-renderer/src/third-lib/virtual-list.js +++ b/packages/hippy-web-renderer/src/third-lib/virtual-list.js @@ -173,7 +173,7 @@ export class VirtualizedList { }); const fragment = document.createDocumentFragment(); - for (let index = start; index <= stop&&stop>0; index++) { + for (let index = start; index <= stop; index++) { fragment.appendChild(renderRow(index)); } From 62002b7c890a6ee97e0ff284efbd797943f5d342 Mon Sep 17 00:00:00 2001 From: zealotchen Date: Wed, 23 Oct 2024 11:28:49 +0800 Subject: [PATCH 4/4] feat(web): add web render demo build script --- .../scripts/hippy-webpack.web-renderer.dev.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/hippy-react-demo/scripts/hippy-webpack.web-renderer.dev.js b/examples/hippy-react-demo/scripts/hippy-webpack.web-renderer.dev.js index 90a38933fb0..1855f0483a0 100644 --- a/examples/hippy-react-demo/scripts/hippy-webpack.web-renderer.dev.js +++ b/examples/hippy-react-demo/scripts/hippy-webpack.web-renderer.dev.js @@ -111,6 +111,17 @@ module.exports = { console.warn('* Using the @hippy/react defined in package.json'); } + // If @hippy/web-renderer was built exist in packages directory then make an alias + // Remove the section if you don't use it + const webRendererPath = path.resolve(__dirname, '../../../packages/hippy-web-renderer/dist'); + if (fs.existsSync(path.resolve(webRendererPath, 'index.js'))) { + console.warn(`* Using the @hippy/web-renderer in ${webRendererPath} as @hippy/web-renderer alias`); + aliases['@hippy/web-renderer'] = webRendererPath; + } else { + console.warn('* Using the @hippy/web-renderer defined in package.json'); + } + + return aliases; })(), },