第一
This commit is contained in:
parent
fa6556a0d5
commit
05b8cc7469
@ -65,6 +65,7 @@ export function baseCompile(
|
|||||||
const onError = options.onError || defaultOnError
|
const onError = options.onError || defaultOnError
|
||||||
const isModuleMode = options.mode === 'module'
|
const isModuleMode = options.mode === 'module'
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
|
// 只要不是 dev onError 就是空函数
|
||||||
if (__BROWSER__) {
|
if (__BROWSER__) {
|
||||||
if (options.prefixIdentifiers === true) {
|
if (options.prefixIdentifiers === true) {
|
||||||
onError(createCompilerError(ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED))
|
onError(createCompilerError(ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED))
|
||||||
@ -81,7 +82,7 @@ export function baseCompile(
|
|||||||
if (options.scopeId && !isModuleMode) {
|
if (options.scopeId && !isModuleMode) {
|
||||||
onError(createCompilerError(ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED))
|
onError(createCompilerError(ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED))
|
||||||
}
|
}
|
||||||
|
// 给options 赋初始值 如果不是字符串 直接返回 template
|
||||||
const ast = isString(template) ? baseParse(template, options) : template
|
const ast = isString(template) ? baseParse(template, options) : template
|
||||||
const [nodeTransforms, directiveTransforms] =
|
const [nodeTransforms, directiveTransforms] =
|
||||||
getBaseTransformPreset(prefixIdentifiers)
|
getBaseTransformPreset(prefixIdentifiers)
|
||||||
|
@ -67,17 +67,17 @@ const decodeMap: Record<string, string> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const defaultParserOptions: MergedParserOptions = {
|
export const defaultParserOptions: MergedParserOptions = {
|
||||||
delimiters: [`{{`, `}}`],
|
delimiters: [`{{`, `}}`], // 模板分割付
|
||||||
getNamespace: () => Namespaces.HTML,
|
getNamespace: () => Namespaces.HTML, // HTML
|
||||||
getTextMode: () => TextModes.DATA,
|
getTextMode: () => TextModes.DATA, //DATA
|
||||||
isVoidTag: NO,
|
isVoidTag: NO, // 无效标签
|
||||||
isPreTag: NO,
|
isPreTag: NO, // 是不是pre标签
|
||||||
isCustomElement: NO,
|
isCustomElement: NO, // 是不是自定义标签
|
||||||
decodeEntities: (rawText: string): string =>
|
decodeEntities: (rawText: string): string =>
|
||||||
rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
|
rawText.replace(decodeRE, (_, p1) => decodeMap[p1]), // 讲实体字符转换成字符串
|
||||||
onError: defaultOnError,
|
onError: defaultOnError,
|
||||||
onWarn: defaultOnWarn,
|
onWarn: defaultOnWarn,
|
||||||
comments: __DEV__
|
comments: __DEV__ // ???
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum TextModes {
|
export const enum TextModes {
|
||||||
@ -105,8 +105,11 @@ export function baseParse(
|
|||||||
content: string,
|
content: string,
|
||||||
options: ParserOptions = {}
|
options: ParserOptions = {}
|
||||||
): RootNode {
|
): RootNode {
|
||||||
|
// 给options 覆初始值 没有的属性都赋值进去
|
||||||
const context = createParserContext(content, options)
|
const context = createParserContext(content, options)
|
||||||
|
// 貌似获取的是固定的
|
||||||
const start = getCursor(context)
|
const start = getCursor(context)
|
||||||
|
// create root
|
||||||
return createRoot(
|
return createRoot(
|
||||||
parseChildren(context, TextModes.DATA, []),
|
parseChildren(context, TextModes.DATA, []),
|
||||||
getSelection(context, start)
|
getSelection(context, start)
|
||||||
@ -117,15 +120,12 @@ function createParserContext(
|
|||||||
content: string,
|
content: string,
|
||||||
rawOptions: ParserOptions
|
rawOptions: ParserOptions
|
||||||
): ParserContext {
|
): ParserContext {
|
||||||
const options = extend({}, defaultParserOptions)
|
const options = extend({}, defaultParserOptions) // 这一行将所有defaultParserOptions属性复制给options
|
||||||
|
// 如果对象属性没有 讲使用默认的 defaultParserOptions
|
||||||
let key: keyof ParserOptions
|
let key: keyof ParserOptions
|
||||||
for (key in rawOptions) {
|
for (key in rawOptions) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
options[key] =
|
options[key] = rawOptions[key] === undefined ? defaultParserOptions[key] : rawOptions[key] // 当rawOptions key值是undefined的时候 给defaultParserOptionsde的值 不是unidentified 给 rawOptions的值
|
||||||
rawOptions[key] === undefined
|
|
||||||
? defaultParserOptions[key]
|
|
||||||
: rawOptions[key]
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
options,
|
options,
|
||||||
@ -139,24 +139,27 @@ function createParserContext(
|
|||||||
onWarn: options.onWarn
|
onWarn: options.onWarn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 解析标签
|
||||||
|
// ancestors 默认是空数组
|
||||||
function parseChildren(
|
function parseChildren(
|
||||||
context: ParserContext,
|
context: ParserContext,
|
||||||
mode: TextModes,
|
mode: TextModes,
|
||||||
ancestors: ElementNode[]
|
ancestors: ElementNode[]
|
||||||
): TemplateChildNode[] {
|
): TemplateChildNode[] {
|
||||||
|
// ancestors 获取最后一个元素 默认undefined
|
||||||
|
// mode DATA
|
||||||
const parent = last(ancestors)
|
const parent = last(ancestors)
|
||||||
const ns = parent ? parent.ns : Namespaces.HTML
|
const ns = parent ? parent.ns : Namespaces.HTML // 如果有 就取ns 没有 HTML ?
|
||||||
const nodes: TemplateChildNode[] = []
|
const nodes: TemplateChildNode[] = [] // ??创建列表
|
||||||
|
// 判断是不是结束标签
|
||||||
while (!isEnd(context, mode, ancestors)) {
|
while (!isEnd(context, mode, ancestors)) {
|
||||||
__TEST__ && assert(context.source.length > 0)
|
__TEST__ && assert(context.source.length > 0)
|
||||||
const s = context.source
|
const s = context.source // html 代码
|
||||||
let node: TemplateChildNode | TemplateChildNode[] | undefined = undefined
|
let node: TemplateChildNode | TemplateChildNode[] | undefined = undefined
|
||||||
|
|
||||||
if (mode === TextModes.DATA || mode === TextModes.RCDATA) {
|
if (mode === TextModes.DATA || mode === TextModes.RCDATA) {
|
||||||
if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
|
if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
|
||||||
// '{{'
|
// 判断是不是'{{' 开头
|
||||||
node = parseInterpolation(context, mode)
|
node = parseInterpolation(context, mode)
|
||||||
} else if (mode === TextModes.DATA && s[0] === '<') {
|
} else if (mode === TextModes.DATA && s[0] === '<') {
|
||||||
// https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
|
// https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
|
||||||
@ -964,11 +967,12 @@ function parseInterpolation(
|
|||||||
context: ParserContext,
|
context: ParserContext,
|
||||||
mode: TextModes
|
mode: TextModes
|
||||||
): InterpolationNode | undefined {
|
): InterpolationNode | undefined {
|
||||||
const [open, close] = context.options.delimiters
|
const [open, close] = context.options.delimiters // open {{ close }}
|
||||||
__TEST__ && assert(startsWith(context.source, open))
|
__TEST__ && assert(startsWith(context.source, open)) // 是否为test
|
||||||
|
|
||||||
const closeIndex = context.source.indexOf(close, open.length)
|
const closeIndex = context.source.indexOf(close, open.length)// 获取结束位置
|
||||||
if (closeIndex === -1) {
|
if (closeIndex === -1) {
|
||||||
|
// 找不到结束
|
||||||
emitError(context, ErrorCodes.X_MISSING_INTERPOLATION_END)
|
emitError(context, ErrorCodes.X_MISSING_INTERPOLATION_END)
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
@ -1057,6 +1061,7 @@ function parseTextData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getCursor(context: ParserContext): Position {
|
function getCursor(context: ParserContext): Position {
|
||||||
|
console.log(context)
|
||||||
const { column, line, offset } = context
|
const { column, line, offset } = context
|
||||||
return { column, line, offset }
|
return { column, line, offset }
|
||||||
}
|
}
|
||||||
@ -1067,6 +1072,7 @@ function getSelection(
|
|||||||
end?: Position
|
end?: Position
|
||||||
): SourceLocation {
|
): SourceLocation {
|
||||||
end = end || getCursor(context)
|
end = end || getCursor(context)
|
||||||
|
console.log(start,end)
|
||||||
return {
|
return {
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
@ -1132,7 +1138,7 @@ function isEnd(
|
|||||||
mode: TextModes,
|
mode: TextModes,
|
||||||
ancestors: ElementNode[]
|
ancestors: ElementNode[]
|
||||||
): boolean {
|
): boolean {
|
||||||
const s = context.source
|
const s = context.source // 原始html
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case TextModes.DATA:
|
case TextModes.DATA:
|
||||||
|
@ -37,10 +37,14 @@ export const DOMDirectiveTransforms: Record<string, DirectiveTransform> = {
|
|||||||
show: transformShow
|
show: transformShow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成语法树
|
||||||
export function compile(
|
export function compile(
|
||||||
template: string,
|
template: string,
|
||||||
options: CompilerOptions = {}
|
options: CompilerOptions = {}
|
||||||
): CodegenResult {
|
): CodegenResult {
|
||||||
|
// template 模板
|
||||||
|
// options 不知道干啥的参数
|
||||||
|
// console.log(options)
|
||||||
return baseCompile(
|
return baseCompile(
|
||||||
template,
|
template,
|
||||||
extend({}, parserOptions, options, {
|
extend({}, parserOptions, options, {
|
||||||
|
@ -756,6 +756,7 @@ let installWithProxy: (i: ComponentInternalInstance) => void
|
|||||||
* For runtime-dom to register the compiler.
|
* For runtime-dom to register the compiler.
|
||||||
* Note the exported method uses any to avoid d.ts relying on the compiler types.
|
* Note the exported method uses any to avoid d.ts relying on the compiler types.
|
||||||
*/
|
*/
|
||||||
|
// ???
|
||||||
export function registerRuntimeCompiler(_compile: any) {
|
export function registerRuntimeCompiler(_compile: any) {
|
||||||
compile = _compile
|
compile = _compile
|
||||||
installWithProxy = i => {
|
installWithProxy = i => {
|
||||||
|
@ -14,6 +14,7 @@ export const vShow: ObjectDirective<VShowElement> = {
|
|||||||
setDisplay(el, value)
|
setDisplay(el, value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 监听器 属性复制
|
||||||
mounted(el, { value }, { transition }) {
|
mounted(el, { value }, { transition }) {
|
||||||
if (transition && value) {
|
if (transition && value) {
|
||||||
transition.enter(el)
|
transition.enter(el)
|
||||||
|
@ -21,24 +21,31 @@ import * as runtimeDom from '@vue/runtime-dom'
|
|||||||
|
|
||||||
function wrappedCreateApp(...args: any[]) {
|
function wrappedCreateApp(...args: any[]) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
// 兼容new Vue
|
||||||
const app = createApp(...args)
|
const app = createApp(...args)
|
||||||
|
// todo: 是不是看内部组件是否兼容??
|
||||||
if (compatUtils.isCompatEnabled(DeprecationTypes.RENDER_FUNCTION, null)) {
|
if (compatUtils.isCompatEnabled(DeprecationTypes.RENDER_FUNCTION, null)) {
|
||||||
// register built-in components so that they can be resolved via strings
|
// register built-in components so that they can be resolved via strings
|
||||||
// in the legacy h() call. The __compat__ prefix is to ensure that v3 h()
|
// in the legacy h() call. The __compat__ prefix is to ensure that v3 h()
|
||||||
// doesn't get affected.
|
// doesn't get affected.
|
||||||
|
// 。注册内部组件
|
||||||
app.component('__compat__transition', Transition)
|
app.component('__compat__transition', Transition)
|
||||||
app.component('__compat__transition-group', TransitionGroup)
|
app.component('__compat__transition-group', TransitionGroup)
|
||||||
app.component('__compat__keep-alive', KeepAlive)
|
app.component('__compat__keep-alive', KeepAlive)
|
||||||
// built-in directives. No need for prefix since there's no render fn API
|
// built-in directives. No need for prefix since there's no render fn API
|
||||||
// for resolving directives via string in v3.
|
// for resolving directives via string in v3.
|
||||||
|
// v-show 实现
|
||||||
app._context.directives.show = vShow
|
app._context.directives.show = vShow
|
||||||
|
// v-model 实现
|
||||||
app._context.directives.model = vModelDynamic
|
app._context.directives.model = vModelDynamic
|
||||||
}
|
}
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createCompatVue() {
|
export function createCompatVue() {
|
||||||
|
// 旧得全局构造函数????
|
||||||
const Vue = compatUtils.createCompatVue(createApp, wrappedCreateApp)
|
const Vue = compatUtils.createCompatVue(createApp, wrappedCreateApp)
|
||||||
|
// 把所有runtimeDom里面的属性方法放到Vue里面
|
||||||
extend(Vue, runtimeDom)
|
extend(Vue, runtimeDom)
|
||||||
return Vue
|
return Vue
|
||||||
}
|
}
|
||||||
|
@ -17,23 +17,31 @@ function compileToFunction(
|
|||||||
template: string | HTMLElement,
|
template: string | HTMLElement,
|
||||||
options?: CompilerOptions
|
options?: CompilerOptions
|
||||||
): RenderFunction {
|
): RenderFunction {
|
||||||
|
// 不是string
|
||||||
if (!isString(template)) {
|
if (!isString(template)) {
|
||||||
|
// 判断节点类型 没有就不是节点
|
||||||
if (template.nodeType) {
|
if (template.nodeType) {
|
||||||
|
// 取内部的html代码
|
||||||
template = template.innerHTML
|
template = template.innerHTML
|
||||||
} else {
|
} else {
|
||||||
|
// 报错 返回一个空函数
|
||||||
__DEV__ && warn(`invalid template option: `, template)
|
__DEV__ && warn(`invalid template option: `, template)
|
||||||
return NOOP
|
return NOOP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = template
|
const key = template
|
||||||
|
// 获取值
|
||||||
const cached = compileCache[key]
|
const cached = compileCache[key]
|
||||||
|
// 如果有值 直接返回缓存之前的
|
||||||
if (cached) {
|
if (cached) {
|
||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
|
// 判断第一个字符串是不是#
|
||||||
if (template[0] === '#') {
|
if (template[0] === '#') {
|
||||||
|
// 那么通过id 去选择元素
|
||||||
const el = document.querySelector(template)
|
const el = document.querySelector(template)
|
||||||
|
// 如果获取不到
|
||||||
if (__DEV__ && !el) {
|
if (__DEV__ && !el) {
|
||||||
warn(`Template element not found or is empty: ${template}`)
|
warn(`Template element not found or is empty: ${template}`)
|
||||||
}
|
}
|
||||||
@ -41,13 +49,14 @@ function compileToFunction(
|
|||||||
// Reason: potential execution of JS expressions in in-DOM template.
|
// Reason: potential execution of JS expressions in in-DOM template.
|
||||||
// The user must make sure the in-DOM template is trusted. If it's rendered
|
// The user must make sure the in-DOM template is trusted. If it's rendered
|
||||||
// by the server, the template should not contain any user data.
|
// by the server, the template should not contain any user data.
|
||||||
|
// 获取的到 取内部的html
|
||||||
template = el ? el.innerHTML : ``
|
template = el ? el.innerHTML : ``
|
||||||
}
|
}
|
||||||
|
// 如果是 dev 不是test 不包含 options.whitespace 发出警告 压缩空白
|
||||||
if (__DEV__ && !__TEST__ && (!options || !options.whitespace)) {
|
if (__DEV__ && !__TEST__ && (!options || !options.whitespace)) {
|
||||||
warnDeprecation(DeprecationTypes.CONFIG_WHITESPACE, null)
|
warnDeprecation(DeprecationTypes.CONFIG_WHITESPACE, null)
|
||||||
}
|
}
|
||||||
|
// template html 模板
|
||||||
const { code } = compile(
|
const { code } = compile(
|
||||||
template,
|
template,
|
||||||
extend(
|
extend(
|
||||||
@ -89,9 +98,11 @@ function compileToFunction(
|
|||||||
return (compileCache[key] = render)
|
return (compileCache[key] = render)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 为runtime-dom 注册编译器
|
||||||
registerRuntimeCompiler(compileToFunction)
|
registerRuntimeCompiler(compileToFunction)
|
||||||
|
// 创建vue 初始化属性 自带组件
|
||||||
const Vue = createCompatVue()
|
const Vue = createCompatVue()
|
||||||
|
// 编译?函数
|
||||||
Vue.compile = compileToFunction
|
Vue.compile = compileToFunction
|
||||||
|
|
||||||
export default Vue
|
export default Vue
|
||||||
|
@ -6,7 +6,7 @@ import { registerRuntimeCompiler, RenderFunction, warn } from '@vue/runtime-dom'
|
|||||||
import * as runtimeDom from '@vue/runtime-dom'
|
import * as runtimeDom from '@vue/runtime-dom'
|
||||||
import { isString, NOOP, generateCodeFrame, extend } from '@vue/shared'
|
import { isString, NOOP, generateCodeFrame, extend } from '@vue/shared'
|
||||||
import { InternalRenderFunction } from 'packages/runtime-core/src/component'
|
import { InternalRenderFunction } from 'packages/runtime-core/src/component'
|
||||||
|
// 判断是不是调试模式
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
initDev()
|
initDev()
|
||||||
}
|
}
|
||||||
@ -17,21 +17,27 @@ function compileToFunction(
|
|||||||
template: string | HTMLElement,
|
template: string | HTMLElement,
|
||||||
options?: CompilerOptions
|
options?: CompilerOptions
|
||||||
): RenderFunction {
|
): RenderFunction {
|
||||||
|
// 判断是不是字符串
|
||||||
if (!isString(template)) {
|
if (!isString(template)) {
|
||||||
|
// 不是字符串判断下有没有nodeType属性
|
||||||
if (template.nodeType) {
|
if (template.nodeType) {
|
||||||
|
// 获取内部的html代码
|
||||||
template = template.innerHTML
|
template = template.innerHTML
|
||||||
} else {
|
} else {
|
||||||
|
// 报错 返回空函数
|
||||||
__DEV__ && warn(`invalid template option: `, template)
|
__DEV__ && warn(`invalid template option: `, template)
|
||||||
return NOOP
|
return NOOP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// key 等于传入末班
|
||||||
const key = template
|
const key = template
|
||||||
|
// 获取缓存 ??
|
||||||
const cached = compileCache[key]
|
const cached = compileCache[key]
|
||||||
|
// 有直接返回缓存
|
||||||
if (cached) {
|
if (cached) {
|
||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
|
// 判断是不是id
|
||||||
if (template[0] === '#') {
|
if (template[0] === '#') {
|
||||||
const el = document.querySelector(template)
|
const el = document.querySelector(template)
|
||||||
if (__DEV__ && !el) {
|
if (__DEV__ && !el) {
|
||||||
@ -43,7 +49,10 @@ function compileToFunction(
|
|||||||
// by the server, the template should not contain any user data.
|
// by the server, the template should not contain any user data.
|
||||||
template = el ? el.innerHTML : ``
|
template = el ? el.innerHTML : ``
|
||||||
}
|
}
|
||||||
|
// 合并传入的选项
|
||||||
|
// 添加 hoistStatic
|
||||||
|
// onError
|
||||||
|
// onWarn
|
||||||
const opts = extend(
|
const opts = extend(
|
||||||
{
|
{
|
||||||
hoistStatic: true,
|
hoistStatic: true,
|
||||||
@ -52,7 +61,9 @@ function compileToFunction(
|
|||||||
} as CompilerOptions,
|
} as CompilerOptions,
|
||||||
options
|
options
|
||||||
)
|
)
|
||||||
|
// ?? 不知道这个是干啥的
|
||||||
|
// 根不执行
|
||||||
|
console.log(opts.isCustomElement,customElements)
|
||||||
if (!opts.isCustomElement && typeof customElements !== 'undefined') {
|
if (!opts.isCustomElement && typeof customElements !== 'undefined') {
|
||||||
opts.isCustomElement = tag => !!customElements.get(tag)
|
opts.isCustomElement = tag => !!customElements.get(tag)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user