<commit_before>//
//  VZMistItem.m
//  MIST
//
//  Created by moxin on 2016/12/6.
//  Copyright © 2016年 Vizlab. All rights reserved.
//

#import "VZMistListItem.h"
#import "VZMistTemplate.h"
#import "VZFNode+Template.h"
#import "VZTExpressionContext.h"
#import "VZMistTemplateHelper.h"
#import "VZMistTemplateController.h"
#import <VZFlexLayout/VZFValue.h>
#import "VZMistItem.h"
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#import "VZMist.h"
#import "VZMistInternal.h"
#import "VZMistJSContextBuilder.h"
#import "VZMistTemplateAction.h"

#ifdef DEBUG
#import "VZScriptErrorMsgViewController.h"
#endif

@interface VZMistWeakObject : NSObject

@property (nonatomic, weak) id object;

@end


@implementation VZMistWeakObject

- (instancetype)initWithObject:(id)object
{
    if (self = [super init]) {
        _object = object;
    }
    return self;
}
@end


static const void *kMistItemInCell = &kMistItemInCell;

@interface VZMistListItem ()
@property (nonatomic, copy) void (^updateStateCompletion)();
@property (strong, readwrite) NSDictionary *state;

#ifdef DEBUG
@property (nonatomic, strong) UIWindow *errorWindow;
@property (nonatomic, strong) NSString *errMsg;
#endif

@end

@implementation VZMistListItem
{
    NSMutableArray *_stateUpdatesQueue;
    __weak UITableView *_tableView;
    __weak UIViewController *_viewController;
    NSDictionary *_rawData;
    NSDictionary *_processedData;
    BOOL _didLoad;
}

@synthesize jsContext = _jsContext;

- (instancetype)init
{
    NSAssert(NO, @"%@: init: should not be called.", self.class);
    return [self initWithData:nil customData:nil template:nil];
}

- (instancetype)initWithData:(NSDictionary *)data customData:(NSDictionary *)customData template:(VZMistTemplate *)tpl
{
    self = [super init];
    if (self) {
        //初始化数据和模板
        _rawData = data;
        _customData = customData ? [customData mutableCopy] : [NSMutableDictionary dictionary];
        _stateUpdatesQueue = [NSMutableArray new];
        _constrainedSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, VZ::FlexValue::Auto());

        _tpl = tpl;
        [self render];
    }
    return self;
}

+ (NSDictionary *)builtinVars {
    static NSDictionary *vars;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        __block UIEdgeInsets safeArea;
        if (@available(iOS 11.0, *)) {
            if (![NSThread isMainThread]) {
                dispatch_sync(dispatch_get_main_queue(), ^{
                    safeArea = [UIApplication sharedApplication].keyWindow.safeAreaInsets;
                });
            }
            else {
                safeArea = [UIApplication sharedApplication].keyWindow.safeAreaInsets;
            }
        }
        else {
            safeArea = UIEdgeInsetsZero;
        }

        vars = @{
                 @"system": @{
                         @"name": [UIDevice currentDevice].systemName ?: @"",
                         @"version": [UIDevice currentDevice].systemVersion ?: @"",
                         @"deviceName": [UIDevice currentDevice].name,
                         },
                 @"screen": @{
                         @"width": @([UIScreen mainScreen].bounds.size.width),
                         @"height": @([UIScreen mainScreen].bounds.size.height),
                         @"scale": @([UIScreen mainScreen].scale),
                         @"statusBarHeight": @([UIApplication sharedApplication].statusBarFrame.size.height),
                         @"isPlus": @([UIScreen mainScreen].bounds.size.width > 375),
                         @"isSmall": @([UIScreen mainScreen].bounds.size.width < 375),
                         @"isX": @([UIScreen mainScreen].bounds.size.height == 812),
                         @"safeArea": @{
                                 @"top": @(safeArea.top),<commit_msg>写死 statusBarHeight 和 safeAera 的值<commit_after>//
//  VZMistItem.m
//  MIST
//
//  Created by moxin on 2016/12/6.
//  Copyright © 2016年 Vizlab. All rights reserved.
//

#import "VZMistListItem.h"
#import "VZMistTemplate.h"
#import "VZFNode+Template.h"
#import "VZTExpressionContext.h"
#import "VZMistTemplateHelper.h"
#import "VZMistTemplateController.h"
#import <VZFlexLayout/VZFValue.h>
#import "VZMistItem.h"
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#import "VZMist.h"
#import "VZMistInternal.h"
#import "VZMistJSContextBuilder.h"
#import "VZMistTemplateAction.h"

#ifdef DEBUG
#import "VZScriptErrorMsgViewController.h"
#endif

@interface VZMistWeakObject : NSObject

@property (nonatomic, weak) id object;

@end


@implementation VZMistWeakObject

- (instancetype)initWithObject:(id)object
{
    if (self = [super init]) {
        _object = object;
    }
    return self;
}
@end


static const void *kMistItemInCell = &kMistItemInCell;

@interface VZMistListItem ()
@property (nonatomic, copy) void (^updateStateCompletion)();
@property (strong, readwrite) NSDictionary *state;

#ifdef DEBUG
@property (nonatomic, strong) UIWindow *errorWindow;
@property (nonatomic, strong) NSString *errMsg;
#endif

@end

@implementation VZMistListItem
{
    NSMutableArray *_stateUpdatesQueue;
    __weak UITableView *_tableView;
    __weak UIViewController *_viewController;
    NSDictionary *_rawData;
    NSDictionary *_processedData;
    BOOL _didLoad;
}

@synthesize jsContext = _jsContext;

- (instancetype)init
{
    NSAssert(NO, @"%@: init: should not be called.", self.class);
    return [self initWithData:nil customData:nil template:nil];
}

- (instancetype)initWithData:(NSDictionary *)data customData:(NSDictionary *)customData template:(VZMistTemplate *)tpl
{
    self = [super init];
    if (self) {
        //初始化数据和模板
        _rawData = data;
        _customData = customData ? [customData mutableCopy] : [NSMutableDictionary dictionary];
        _stateUpdatesQueue = [NSMutableArray new];
        _constrainedSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, VZ::FlexValue::Auto());

        _tpl = tpl;
        [self render];
    }
    return self;
}

+ (NSDictionary *)builtinVars {
    static NSDictionary *vars;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        BOOL isX = [UIScreen mainScreen].bounds.size.height == 812;
        UIEdgeInsets safeArea = isX ? UIEdgeInsetsMake(44, 0, 34, 0) : UIEdgeInsetsZero;

        vars = @{
                 @"system": @{
                         @"name": [UIDevice currentDevice].systemName ?: @"",
                         @"version": [UIDevice currentDevice].systemVersion ?: @"",
                         @"deviceName": [UIDevice currentDevice].name ?: @"",
                         },
                 @"screen": @{
                         @"width": @([UIScreen mainScreen].bounds.size.width),
                         @"height": @([UIScreen mainScreen].bounds.size.height),
                         @"scale": @([UIScreen mainScreen].scale),
                         @"statusBarHeight": isX ? @44 : @20,
                         @"isPlus": @([UIScreen mainScreen].bounds.size.width > 375),
                         @"isSmall": @([UIScreen mainScreen].bounds.size.width < 375),
                         @"isX": @(isX),
                         @"safeArea": @{
                                 @"top": @(safeArea.top),
{'fraction_non_alphanumeric': 0.12734547461368653, 'fraction_numerical': 0.007312362030905077, 'mean_word_length': 2.651889168765743, 'pattern_counts': {'":': 28, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5972400', 'n_tokens_mistral': 2409, 'n_tokens_neox': 2228, 'n_words': 461}