Skip to content

Latest commit

 

History

History
521 lines (393 loc) · 13.6 KB

File metadata and controls

521 lines (393 loc) · 13.6 KB

JSON Schema 解析库 - 代码执行流程和组件功能分析

一、整体架构

这是一个用于解析 JSON Schema 并动态生成表单编辑器的 JavaScript 库。主要组件包括:

  • 核心控制器 (core.js)
  • Schema 加载器 (schemaloader.js)
  • 编辑器解析器 (resolvers.js)
  • 编辑器基类 (editor.js)
  • 验证器 (validator.js)
  • 主题系统 (theme.js)
  • 工具函数 (utilities.js)

二、执行流程

阶段 1: 初始化 (core.js - JSONEditor 构造函数)

执行顺序:

  1. 构造函数调用 (new JSONEditor(element, options))

    • 验证 element 是否为 DOM 元素
    • 合并默认配置和用户配置
    • 初始化内部状态变量
  2. 主题初始化 (第 28-61 行)

    • 获取主题名称(默认 'html')
    • 实例化主题类 (new themeClass(this))
    • 加载样式规则(支持 Shadow DOM)
    • 添加主题相关的 CSS 类到容器
  3. 图标库初始化 (第 64-66 行)

    • 根据配置加载图标库
    • 实例化图标库类
  4. 容器创建 (第 68-69 行)

    • 通过主题获取根容器
    • 将容器添加到 DOM 元素
  5. Schema 加载 (第 72-122 行)

    • 创建 SchemaLoader 实例
    • 调用 loader.load() 异步加载 Schema
    • 加载完成后执行回调

关键函数:

  • JSONEditor.constructor() - 主构造函数
  • getEditorsRules() - 获取所有编辑器的样式规则
  • addNewStyleRules() / addNewStyleRulesToShadowRoot() - 添加样式规则

阶段 2: Schema 加载和展开 (schemaloader.js)

执行顺序:

  1. 外部引用加载 (_loadExternalRefs())

    • 扫描 Schema 中的所有 $ref 引用
    • 通过 AJAX 或 URN 解析器加载外部 Schema
    • 递归加载嵌套引用
    • 等待所有引用加载完成
  2. 定义提取 (_getDefinitions())

    • 提取 Schema 中的 definitions 部分
    • 将定义注册到 refs 对象中
    • 支持嵌套定义
  3. 引用展开 (expandRefs())

    • $ref 引用替换为实际的 Schema 对象
    • 合并引用 Schema 和当前 Schema
  4. Schema 展开 (expandSchema())

    • 处理子 Schema 结构:
      • type (数组或对象类型)
      • disallow (禁止类型)
      • anyOf (任一匹配)
      • dependencies (依赖关系)
      • not (否定)
    • 处理合并 Schema:
      • allOf (全部匹配,合并到父 Schema)
      • extends (继承,合并到父 Schema)
      • oneOf (唯一匹配,父 Schema 合并到子 Schema)

关键函数:

  • load() - 主加载入口
  • _loadExternalRefs() - 加载外部引用
  • expandRefs() - 展开引用
  • expandSchema() - 展开 Schema
  • extendSchemas() - 合并 Schema

阶段 3: 编辑器选择 (resolvers.js)

执行顺序:

  1. 解析器链执行 (getEditorClass() in core.js)

    • 按顺序遍历所有解析器函数
    • 每个解析器检查 Schema 是否匹配
    • 返回第一个匹配的编辑器类名
  2. 解析器优先级 (从高到低):

    • multiLine - 多行文本编辑器
    • colorPicker - 颜色选择器
    • ip - IP 地址输入
    • ace - 代码编辑器(支持多种语言)
    • xhtml - HTML/BBcode 编辑器
    • markdown - Markdown 编辑器
    • jodit - 富文本编辑器
    • autoComplete - 自动完成
    • uuid - UUID 输入
    • info - 信息显示
    • button - 按钮
    • stepper - 步进器
    • describeBy - 动态描述
    • starratings - 星级评分
    • date - 日期时间
    • oneOf / anyOf - 多选编辑器
    • arraysOfStrings - 字符串数组编辑器
    • enumeratedProperties - 枚举编辑器
    • enumSource - 动态枚举
    • table - 表格编辑器
    • upload - 文件上传
    • base64 - Base64 编码
    • any - 任意类型
    • boolean - 布尔值
    • signature - 签名
    • primitive - 基础类型(string, number, integer)
    • object - 对象类型(推断)
    • defaultResolver - 默认多选编辑器

关键函数:

  • getEditorClass() - 获取编辑器类
  • 各个解析器函数 - 检查 Schema 特征并返回编辑器名称

阶段 4: 编辑器创建和构建 (editor.js - AbstractEditor)

执行顺序:

  1. 编辑器实例化 (createEditor() in core.js)

    • 合并编辑器选项
    • 创建编辑器实例 (new editorClass(options))
    • 传递深度计数器(防止无限递归)
  2. 编辑器初始化 (AbstractEditor.constructor())

    • 设置基本属性(jsoneditor, theme, schema 等)
    • 展开 Schema (expandSchema())
    • 设置路径和表单名称
    • 注册依赖关系
  3. 构建阶段 (三阶段构建模式)

    a) preBuild() (第 98 行)

    • 子类可重写
    • 构建前的准备工作

    b) build() (第 99 行)

    • 子类必须实现
    • 创建 DOM 结构
    • 设置事件监听器
    • 初始化控件

    c) postBuild() (第 100 行)

    • 设置监听器 (setupWatchListeners())
    • 添加链接 (addLinks())
    • 设置默认值 (setValue(getDefault()))
    • 更新标题 (updateHeaderText())
    • 注册编辑器 (register())
    • 触发监听字段变化 (onWatchedFieldChange())
  4. 值设置 (第 103 行)

    • 如果提供了 startval,设置初始值
    • 调用 root.setValue()

关键函数:

  • createEditor() - 创建编辑器实例
  • preBuild() - 构建前处理
  • build() - 构建 DOM
  • postBuild() - 构建后处理
  • setupWatchListeners() - 设置字段监听
  • register() - 注册编辑器到全局注册表

阶段 5: 验证 (validator.js)

执行顺序:

  1. 验证器初始化 (new Validator())

    • 保存 JSONEditor 引用
    • 设置 Schema 和选项
    • 初始化翻译函数
  2. 初始验证 (core.js 第 105 行)

    • 调用 validator.validate(root.getValue())
    • 缓存验证结果
  3. 验证流程 (_validateSchema())

    a) 类型无关验证 (第 792-801 行)

    • const - 常量值
    • enum - 枚举值
    • extends - 继承验证
    • allOf - 全部匹配
    • anyOf - 任一匹配(支持依赖项优化)
    • oneOf - 唯一匹配
    • not - 否定验证
    • type - 类型检查
    • disallow - 禁止类型

    b) 类型相关验证 (第 803-943 行)

    数字类型:

    • multipleOf / divisibleBy - 倍数验证
    • maximum / exclusiveMaximum - 最大值
    • minimum / exclusiveMinimum - 最小值
    • relativeTo - 相对值验证

    字符串类型:

    • maxLength - 最大长度
    • minLength - 最小长度
    • pattern - 正则匹配

    数组类型:

    • items - 项验证
    • additionalItems - 额外项验证
    • maxItems - 最大项数
    • minItems - 最小项数
    • uniqueItems - 唯一项验证
    • compareThanPrev - 与前一项比较
    • exclusive - 互斥项

    对象类型:

    • maxProperties - 最大属性数
    • minProperties - 最小属性数
    • required - 必需属性
    • properties - 属性验证
    • patternProperties - 模式属性验证
    • propertyNames - 属性名验证
    • additionalProperties - 额外属性验证
    • dependencies - 依赖验证

    c) 特殊格式验证 (第 817-828 行)

    • 日期时间验证 (_validateDateTimeSubSchema())
    • UUID 验证 (_validateUUIDSchema())
    • 自定义验证器 (_validateCustomValidator())
    • IP 地址验证 (ipValidator)
    • 日期验证 (dateValidator)
  4. 错误处理 (第 830-831 行)

    • 移除重复错误
    • 添加错误计数
  5. 验证结果显示 (core.js 第 117 行)

    • 调用 root.showValidationErrors()
    • 在 UI 上显示错误信息

关键函数:

  • validate() - 主验证入口
  • _validateSchema() - Schema 验证核心
  • _validateByValueType() - 按类型验证
  • _checkType() - 类型检查

阶段 6: 事件和交互

执行顺序:

  1. 值变化处理 (onChange() in core.js)

    • 防抖处理(使用 requestAnimationFrame
    • 重新验证值
    • 显示验证错误(可选)
    • 触发 change 事件
  2. 依赖关系处理 (evaluateDependencies() in editor.js)

    • 监听依赖字段变化
    • 评估依赖条件
    • 显示/隐藏相关字段
  3. 字段监听 (setupWatchListeners() in editor.js)

    • 设置字段变化监听
    • 更新动态标题
    • 更新链接 URL
  4. 编辑器注册 (register() / unregister())

    • 将编辑器注册到全局注册表
    • 支持通过路径查找编辑器

关键函数:

  • onChange() - 值变化处理
  • evaluateDependencies() - 依赖评估
  • setupWatchListeners() - 设置监听
  • register() / unregister() - 编辑器注册

三、核心组件功能

1. JSONEditor (core.js)

主要功能:

  • 管理整个编辑器实例的生命周期
  • 协调各个子系统(Schema 加载、编辑器创建、验证)
  • 提供公共 API(getValue, setValue, validate, destroy)
  • 事件系统(on, off, trigger)
  • 编辑器注册表管理
  • 字段监听系统

关键方法:

  • getValue() - 获取当前值
  • setValue() - 设置值
  • validate() - 验证值
  • onChange() - 值变化处理
  • getEditorClass() - 获取编辑器类
  • createEditor() - 创建编辑器

2. SchemaLoader (schemaloader.js)

主要功能:

  • 加载外部 Schema 引用(AJAX 或 URN)
  • 展开 $ref 引用
  • 处理 Schema 继承和合并(allOf, extends, oneOf)
  • 提取和注册 definitions
  • 处理嵌套引用

关键方法:

  • load() - 加载 Schema
  • expandRefs() - 展开引用
  • expandSchema() - 展开 Schema
  • extendSchemas() - 合并 Schema
  • _loadExternalRefs() - 加载外部引用

3. Resolvers (resolvers.js)

主要功能:

  • 根据 Schema 特征选择合适的编辑器
  • 提供解析器链机制
  • 支持自定义编辑器类型

解析器类型:

  • 格式特定解析器(date, color, ip 等)
  • 类型特定解析器(boolean, array, object 等)
  • 特殊功能解析器(upload, enum, oneOf 等)

4. AbstractEditor (editor.js)

主要功能:

  • 所有编辑器的基类
  • 提供通用的编辑器功能
  • 管理编辑器的生命周期
  • 处理依赖关系
  • 字段监听和动态更新
  • 链接和模板支持

关键方法:

  • preBuild() - 构建前处理
  • build() - 构建 DOM(子类实现)
  • postBuild() - 构建后处理
  • setValue() - 设置值
  • getValue() - 获取值
  • showValidationErrors() - 显示验证错误
  • evaluateDependencies() - 评估依赖

5. Validator (validator.js)

主要功能:

  • 根据 JSON Schema 规范验证值
  • 支持多种验证规则
  • 提供详细的错误信息
  • 支持自定义验证器
  • 优化 anyOf 验证(支持依赖项)

验证类型:

  • 类型验证
  • 数值范围验证
  • 字符串长度和模式验证
  • 数组项验证
  • 对象属性验证
  • 依赖关系验证
  • 特殊格式验证

6. AbstractTheme (theme.js)

主要功能:

  • 提供 UI 元素的创建方法
  • 支持多种主题(HTML, Bootstrap3, Tailwind)
  • 创建表单控件、按钮、容器等
  • 处理标签页、表格等复杂 UI

关键方法:

  • getContainer() - 获取容器
  • getFormInputField() - 获取输入框
  • getButton() - 获取按钮
  • getFormControl() - 获取表单控件
  • getTable() - 获取表格
  • getTabHolder() - 获取标签页容器

7. Utilities (utilities.js)

主要功能:

  • 对象扩展和深拷贝
  • 类型检查(数字、整数)
  • 日期转换
  • 属性路径访问
  • 数组扁平化
  • 事件触发

关键函数:

  • extend() - 对象扩展
  • deepCopy() - 深拷贝
  • isNumber() - 数字检查
  • isInteger() - 整数检查
  • getProp() - 安全属性访问
  • flatArrByPath() - 数组扁平化

四、数据流

用户输入 Schema
    ↓
JSONEditor 初始化
    ↓
SchemaLoader 加载和展开 Schema
    ↓
Resolvers 选择编辑器类型
    ↓
创建编辑器实例 (AbstractEditor)
    ↓
构建 DOM (preBuild → build → postBuild)
    ↓
设置初始值
    ↓
Validator 验证
    ↓
显示验证结果
    ↓
用户交互 → 值变化 → 重新验证 → 更新 UI

五、关键设计模式

  1. 策略模式 - 编辑器选择(Resolvers)
  2. 模板方法模式 - 编辑器构建流程(preBuild → build → postBuild)
  3. 观察者模式 - 事件系统和字段监听
  4. 注册表模式 - 编辑器注册表
  5. 工厂模式 - 编辑器创建(createEditor)
  6. 责任链模式 - 解析器链

六、扩展点

  1. 自定义编辑器 - 继承 AbstractEditor 并注册
  2. 自定义解析器 - 添加到 resolvers 数组
  3. 自定义验证器 - 添加到 custom_validators
  4. 自定义主题 - 继承 AbstractTheme 并注册
  5. 自定义模板引擎 - 实现模板接口并注册

七、性能优化

  1. 防抖处理 - onChange 使用 requestAnimationFrame
  2. 延迟验证 - 使用 setTimeout 避免渲染错位
  3. 依赖优化 - anyOf 验证时仅验证当前激活项
  4. 缓存验证结果 - 避免重复验证
  5. 按需加载 - 外部 Schema 异步加载

八、总结

这个库的核心思想是:

  1. 声明式 - 通过 JSON Schema 声明表单结构
  2. 自动化 - 自动选择合适的编辑器
  3. 可扩展 - 支持自定义编辑器、验证器、主题
  4. 类型安全 - 完整的 Schema 验证
  5. 用户友好 - 实时验证和错误提示

整个系统通过清晰的职责分离和标准化的接口,实现了高度可扩展和可维护的架构。