diff --git a/driver/js/examples/hippy-react-demo/src/components/ListView/index.jsx b/driver/js/examples/hippy-react-demo/src/components/ListView/index.jsx
index eb57411f47b..6c50de00f2e 100644
--- a/driver/js/examples/hippy-react-demo/src/components/ListView/index.jsx
+++ b/driver/js/examples/hippy-react-demo/src/components/ListView/index.jsx
@@ -4,7 +4,6 @@ import {
View,
StyleSheet,
Text,
- Platform,
} from '@hippy/react';
const STYLE_LOADING = 100;
@@ -271,8 +270,7 @@ export default class ListExample extends React.Component {
return true;
}}
bounces={true}
- // horizontal ListView flag(only Android support)
- horizontal={horizontal}
+ horizontal={horizontal} // horizontal ListView flag
style={[{ backgroundColor: '#ffffff' }, horizontal ? { height: 50 } : { flex: 1 }]}
numberOfRows={dataSource.length}
renderRow={this.getRenderRow}
@@ -297,33 +295,32 @@ export default class ListExample extends React.Component {
onScroll={this.onScroll}
scrollEventThrottle={1000} // 1s
/>
- {Platform.OS === 'android'
- ? this.changeDirection()}
- style={{
- position: 'absolute',
- right: 20,
- bottom: 20,
- width: 67,
- height: 67,
- borderRadius: 30,
- boxShadowOpacity: 0.6,
- boxShadowRadius: 5,
- boxShadowOffsetX: 3,
- boxShadowOffsetY: 3,
- boxShadowColor: '#4c9afa' }}>
-
+ this.changeDirection()}
+ style={{
+ position: 'absolute',
+ right: 20,
+ bottom: 20,
+ width: 67,
+ height: 67,
+ borderRadius: 30,
+ boxShadowOpacity: 0.6,
+ boxShadowRadius: 5,
+ boxShadowOffsetX: 3,
+ boxShadowOffsetY: 3,
+ boxShadowColor: '#4c9afa' }}>
+
切换方向
- : null}
+
);
}
diff --git a/driver/js/examples/hippy-vue-demo/src/components/demos/demo-list.vue b/driver/js/examples/hippy-vue-demo/src/components/demos/demo-list.vue
index 853bda36ee8..24d2a913cb2 100644
--- a/driver/js/examples/hippy-vue-demo/src/components/demos/demo-list.vue
+++ b/driver/js/examples/hippy-vue-demo/src/components/demos/demo-list.vue
@@ -78,7 +78,6 @@
-import { type ListViewEvent, Native } from '@hippy/vue-next';
+import { type ListViewEvent } from '@hippy/vue-next';
import { defineComponent, ref, onMounted, type Ref } from '@vue/runtime-core';
const STYLE_LOADING = 100;
@@ -269,7 +268,6 @@ export default defineComponent({
list,
STYLE_LOADING,
horizontal,
- Platform: Native.Platform,
onAppear,
onDelete,
onDisappear,
diff --git a/driver/js/packages/hippy-vue-css-loader/src/css-loader.ts b/driver/js/packages/hippy-vue-css-loader/src/css-loader.ts
index 7bb3b17ee38..9544b8bd140 100644
--- a/driver/js/packages/hippy-vue-css-loader/src/css-loader.ts
+++ b/driver/js/packages/hippy-vue-css-loader/src/css-loader.ts
@@ -32,14 +32,17 @@ let sourceId = 0;
function hippyVueCSSLoader(this: any, source: any) {
const options = getOptions(this);
const parsed = parseCSS(source, { source: sourceId });
- const hash = crypto.createHash('shake256', { outputLength: 3 });
+
+ const majorNodeVersion = parseInt(process.versions.node.split('.')[0], 10);
+ const hashType = majorNodeVersion >= 17 ? 'md5' : 'md4';
+ const hash = crypto.createHash(hashType);
const contentHash = hash.update(source).digest('hex');
sourceId += 1;
- const rulesAst = parsed.stylesheet.rules.filter((n: any) => n.type === 'rule').map((n: any) => ([
- contentHash,
- n.selectors,
- // filter comment declaration and empty declaration
- n.declarations.filter(dec => dec.type !== 'comment').map((dec: any) => {
+ const rulesAst = parsed.stylesheet.rules.filter((n: any) => n.type === 'rule').map((n: any) => ({
+ hash: contentHash,
+ selectors: n.selectors,
+
+ declarations: n.declarations.map((dec: any) => {
let { value } = dec;
const isVariableColor = dec.property?.startsWith('-') && typeof value === 'string'
&& (
@@ -52,14 +55,18 @@ function hippyVueCSSLoader(this: any, source: any) {
if (dec.property && (dec.property.toLowerCase().indexOf('color') > -1 || isVariableColor)) {
value = translateColor(value);
}
- return [dec.property, value];
+ return {
+ type: dec.type,
+ property: dec.property,
+ value,
+ };
}),
- ])).filter(rule => rule[2].length > 0);
- const code = `(function(n) {
- if (!global[n]) {
- global[n] = [];
+ }));
+ const code = `(function() {
+ if (!global['${GLOBAL_STYLE_NAME}']) {
+ global['${GLOBAL_STYLE_NAME}'] = [];
}
- global[n] = global[n].concat(${JSON.stringify(rulesAst)});
+ global['${GLOBAL_STYLE_NAME}'] = global['${GLOBAL_STYLE_NAME}'].concat(${JSON.stringify(rulesAst)});
if(module.hot) {
module.hot.dispose(() => {
@@ -70,7 +77,7 @@ function hippyVueCSSLoader(this: any, source: any) {
global['${GLOBAL_DISPOSE_STYLE_NAME}'] = global['${GLOBAL_DISPOSE_STYLE_NAME}'].concat('${contentHash}');
})
}
- })('${GLOBAL_STYLE_NAME}')`;
+ })()`;
return `module.exports=${code}`;
}
diff --git a/driver/js/packages/hippy-vue-next-style-parser/src/style-match/css-map.ts b/driver/js/packages/hippy-vue-next-style-parser/src/style-match/css-map.ts
index 2eb77cef3ac..29e021fa60a 100644
--- a/driver/js/packages/hippy-vue-next-style-parser/src/style-match/css-map.ts
+++ b/driver/js/packages/hippy-vue-next-style-parser/src/style-match/css-map.ts
@@ -34,9 +34,6 @@ import { SelectorsMap } from './css-selectors-match';
import { parseSelector } from './parser';
import { HIPPY_GLOBAL_STYLE_NAME, HIPPY_GLOBAL_DISPOSE_STYLE_NAME } from './';
-type Declaration = [property: string, value: string | number];
-export type ASTRule = [hash: string, selectors: string[], declarations: Declaration[]];
-
// style load hook
const beforeLoadStyleHook: Function = (declaration: Function): Function => declaration;
@@ -73,7 +70,7 @@ function createSimpleSelectorFromAst(ast) {
? new AttributeSelector(ast.property, ast.test, ast.value)
: new AttributeSelector(ast.property);
default:
- return new InvalidSelector(new Error('Unknown selector.'));;
+ return null;
}
}
@@ -128,23 +125,10 @@ function createSelector(sel) {
* @param beforeLoadStyle
*/
export function fromAstNodes(
- astRules: Array = [],
+ astRules: CssAttribute[] = [],
beforeLoadStyle?: Function,
): RuleSet[] {
- const rules = astRules.map(rule => {
- if (!Array.isArray(rule)) return rule;
- const [hash, selectors, declarations] = rule as ASTRule;
- return {
- hash,
- selectors,
- declarations: declarations.map(([property, value]) => ({
- type: 'declaration',
- property,
- value,
- })),
- };
- });
- return rules.map((rule) => {
+ return astRules.map((rule) => {
const declarations = rule.declarations
.filter(isDeclaration)
// use default hook when there is no hook passed in
diff --git a/framework/ios/base/bridge/HippyBridge.mm b/framework/ios/base/bridge/HippyBridge.mm
index 1de3a8eecb1..4f644c7c684 100644
--- a/framework/ios/base/bridge/HippyBridge.mm
+++ b/framework/ios/base/bridge/HippyBridge.mm
@@ -183,7 +183,7 @@ @interface HippyBridge() {
/// Bundle fetch operation queue (concurrent)
@property (nonatomic, strong) NSOperationQueue *bundleQueue;
/// Record the last execute operation for adding execution dependency.
-@property (atomic, strong, nullable) NSOperation *lastExecuteOperation;
+@property (nonatomic, strong, nullable) NSOperation *lastExecuteOperation;
/// Cached Dimensions info,will be passed to JS Side.
@property (atomic, strong) NSDictionary *cachedDimensionsInfo;
@@ -591,13 +591,17 @@ - (void)beginLoadingBundle:(NSURL *)bundleURL
strongSelf.valid, script];
HippyLogError(@"%@", errMsg);
completion(bundleURL, HippyErrorWithMessage(errMsg));
- strongSelf.lastExecuteOperation = nil;
+ @synchronized (self) {
+ strongSelf.lastExecuteOperation = nil;
+ }
return;
}
[strongSelf executeJSCode:script sourceURL:bundleURL onCompletion:^(id result, NSError *error) {
HippyLogInfo(@"End executing bundle(%s)",
HP_CSTR_NOT_NULL(bundleURL.absoluteString.lastPathComponent.UTF8String));
- strongSelf.lastExecuteOperation = nil;
+ @synchronized (self) {
+ strongSelf.lastExecuteOperation = nil;
+ }
if (completion) {
completion(bundleURL, error);
}
@@ -624,13 +628,18 @@ - (void)beginLoadingBundle:(NSURL *)bundleURL
// Add dependency, make sure that doing fetch before execute,
// and all execution operations must be queued.
[executeOperation addDependency:fetchOperation];
- if (self.lastExecuteOperation) {
- [executeOperation addDependency:self.lastExecuteOperation];
+ @synchronized (self) {
+ NSOperation *lastOp = self.lastExecuteOperation;
+ if (lastOp) {
+ [executeOperation addDependency:lastOp];
+ }
}
// Enqueue operation
[_bundleQueue addOperations:@[fetchOperation, executeOperation] waitUntilFinished:NO];
- self.lastExecuteOperation = executeOperation;
+ @synchronized (self) {
+ self.lastExecuteOperation = executeOperation;
+ }
}
- (void)unloadInstanceForRootView:(NSNumber *)rootTag {
diff --git a/modules/footstone/include/footstone/logging.h b/modules/footstone/include/footstone/logging.h
index 71f5dbd2ee9..3cfa7329c76 100644
--- a/modules/footstone/include/footstone/logging.h
+++ b/modules/footstone/include/footstone/logging.h
@@ -225,9 +225,9 @@ bool ShouldCreateLogMessage(LogSeverity severity);
#define HP_CSTR_NOT_NULL( p ) (p ? p : "")
-#ifdef DEBUG
+#ifdef ENABLE_HIPPY_PERFLOG
+// enable perf log output when `ENABLE_HIPPY_PERFLOG` is set
-// enable perf log output in debug mode only
#define TDF_PERF_LOG(format, ...) \
footstone::LogMessage::LogWithFormat(__FILE_NAME__, __LINE__, "[HP PERF] " format, \
##__VA_ARGS__)
@@ -241,4 +241,4 @@ footstone::LogMessage::LogWithFormat(__FILE_NAME__, __LINE__, "[HP PERF] " forma
#define TDF_PERF_LOG(format, ...)
#define TDF_PERF_DO_STMT_AND_LOG(STMT , format, ...)
-#endif
+#endif /* ENABLE_HIPPY_PERFLOG */
diff --git a/renderer/native/ios/renderer/HippyUIManager.mm b/renderer/native/ios/renderer/HippyUIManager.mm
index c24a2d3df9d..140acda23c9 100644
--- a/renderer/native/ios/renderer/HippyUIManager.mm
+++ b/renderer/native/ios/renderer/HippyUIManager.mm
@@ -201,16 +201,16 @@ @interface HippyUIManager() {
NSHashTable> *_componentTransactionListeners;
std::mutex _renderQueueLock;
- NSMutableDictionary *_viewManagers;
- NSArray *_extraComponents;
-
- NSMutableArray> *_imageProviders;
}
-
+/// All managed ViewManagers
+@property (atomic, strong) NSMutableDictionary *viewManagers;
+/// All extra components
+@property (atomic, strong) NSArray *extraComponents;
@end
+
@implementation HippyUIManager
@synthesize domManager = _domManager;
@@ -675,36 +675,37 @@ - (void)updateView:(nonnull NSNumber *)componentTag
- (__kindof HippyViewManager *)viewManagerForViewName:(NSString *)viewName {
HippyBridge *strongBridge = self.bridge;
- if (!_viewManagers) {
- _viewManagers = [NSMutableDictionary dictionary];
- if (_extraComponents) {
- for (Class cls in _extraComponents) {
+ if (!self.viewManagers) {
+ NSMutableDictionary *viewManagers = [NSMutableDictionary dictionary];
+ if (self.extraComponents) {
+ for (Class cls in self.extraComponents) {
NSString *viewName = viewNameFromViewManagerClass(cls);
- HippyAssert(![_viewManagers objectForKey:viewName],
+ HippyAssert(![viewManagers objectForKey:viewName],
@"duplicated component %@ for class %@ and %@", viewName,
NSStringFromClass(cls),
- NSStringFromClass([_viewManagers objectForKey:viewName]));
- [_viewManagers setObject:cls forKey:viewName];
+ NSStringFromClass([viewManagers objectForKey:viewName]));
+ [viewManagers setObject:cls forKey:viewName];
}
}
NSArray *classes = HippyGetViewManagerClasses(strongBridge);
NSMutableDictionary *defaultViewManagerClasses = [NSMutableDictionary dictionaryWithCapacity:[classes count]];
for (Class cls in classes) {
NSString *viewName = viewNameFromViewManagerClass(cls);
- if ([_viewManagers objectForKey:viewName]) {
+ if ([viewManagers objectForKey:viewName]) {
continue;
}
[defaultViewManagerClasses setObject:cls forKey:viewName];
}
- [_viewManagers addEntriesFromDictionary:defaultViewManagerClasses];
+ [viewManagers addEntriesFromDictionary:defaultViewManagerClasses];
+ self.viewManagers = viewManagers;
}
// Get and instantiate the class
- id object = [_viewManagers objectForKey:viewName];
+ id object = [self.viewManagers objectForKey:viewName];
if (object_isClass(object)) {
HippyViewManager *viewManager = [object new];
viewManager.bridge = strongBridge;
NSAssert([viewManager isKindOfClass:[HippyViewManager class]], @"Must be a HippyViewManager instance");
- [_viewManagers setObject:viewManager forKey:viewName];
+ [self.viewManagers setObject:viewManager forKey:viewName];
object = viewManager;
}
return object;
@@ -1125,7 +1126,7 @@ - (void)dispatchFunction:(const std::string &)functionName
}
- (void)registerExtraComponent:(NSArray *)extraComponents {
- _extraComponents = extraComponents;
+ self.extraComponents = extraComponents;
}
diff --git a/renderer/native/ios/renderer/component/textinput/HippyShadowTextView.mm b/renderer/native/ios/renderer/component/textinput/HippyShadowTextView.mm
index 83b518f50e1..0d38fba2fc0 100644
--- a/renderer/native/ios/renderer/component/textinput/HippyShadowTextView.mm
+++ b/renderer/native/ios/renderer/component/textinput/HippyShadowTextView.mm
@@ -192,17 +192,15 @@ - (void)dirtyText:(BOOL)needToDoLayout {
}
- (void)amendLayoutBeforeMount:(NSMutableSet *)blocks {
- [super amendLayoutBeforeMount:blocks];
-
- if (NativeRenderUpdateLifecycleComputed == _propagationLifecycle) {
- return;
+ if (NativeRenderUpdateLifecycleComputed != _propagationLifecycle) {
+ //Set needs layout for font change event, etc.
+ NSNumber *currentTag = self.hippyTag;
+ [blocks addObject:^(NSDictionary *viewRegistry, UIView * _Nullable lazyCreatedView) {
+ UIView *view = lazyCreatedView ?: viewRegistry[currentTag];
+ [view setNeedsLayout];
+ }];
}
- //Set needs layout for font change event, etc.
- NSNumber *currentTag = self.hippyTag;
- [blocks addObject:^(NSDictionary *viewRegistry, UIView * _Nullable lazyCreatedView) {
- UIView *view = lazyCreatedView ?: viewRegistry[currentTag];
- [view setNeedsLayout];
- }];
+ [super amendLayoutBeforeMount:blocks];
}
diff --git a/renderer/native/ios/renderer/component/view/HippyShadowView.mm b/renderer/native/ios/renderer/component/view/HippyShadowView.mm
index 17875abdf35..8f59aacd67b 100644
--- a/renderer/native/ios/renderer/component/view/HippyShadowView.mm
+++ b/renderer/native/ios/renderer/component/view/HippyShadowView.mm
@@ -97,7 +97,7 @@ - (instancetype)init {
if ((self = [super init])) {
_propagationLifecycle = NativeRenderUpdateLifecycleUninitialized;
_frame = CGRectMake(0, 0, NAN, NAN);
- _objectSubviews = [NSMutableArray arrayWithCapacity:8];
+ _objectSubviews = [NSMutableArray array];
_confirmedLayoutDirection = hippy::Direction::Inherit;
_layoutDirection = hippy::Direction::Inherit;
}