Best JavaScript code snippet using playwright-internal
patch.js
Source:patch.js
...32 a.key === b.key && (33 (34 a.tag === b.tag &&35 a.isComment === b.isComment &&36 isDef(a.data) === isDef(b.data) &&37 sameInputType(a, b)38 ) || (39 isTrue(a.isAsyncPlaceholder) &&40 a.asyncFactory === b.asyncFactory &&41 isUndef(b.asyncFactory.error)42 )43 )44 )45}46function sameInputType (a, b) {47 if (a.tag !== 'input') return true48 let i49 const typeA = isDef(i = a.data) && isDef(i = i.attrs) && i.type50 const typeB = isDef(i = b.data) && isDef(i = i.attrs) && i.type51 return typeA === typeB || isTextInputType(typeA) && isTextInputType(typeB)52}53function createKeyToOldIdx (children, beginIdx, endIdx) {54 let i, key55 const map = {}56 for (i = beginIdx; i <= endIdx; ++i) {57 key = children[i].key58 if (isDef(key)) map[key] = i59 }60 return map61}62export function createPatchFunction (backend) {63 let i, j64 const cbs = {} // å个 hooks çåè°éå65 const { modules, nodeOps } = backend66 for (i = 0; i < hooks.length; ++i) {67 cbs[hooks[i]] = []68 for (j = 0; j < modules.length; ++j) {69 if (isDef(modules[j][hooks[i]])) {70 cbs[hooks[i]].push(modules[j][hooks[i]])71 }72 }73 }74 function emptyNodeAt (elm) {75 return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)76 }77 function createRmCb (childElm, listeners) {78 function remove () {79 if (--remove.listeners === 0) {80 removeNode(childElm)81 }82 }83 remove.listeners = listeners84 return remove85 }86 function removeNode (el) {87 const parent = nodeOps.parentNode(el)88 // element may have already been removed due to v-html / v-text89 if (isDef(parent)) {90 nodeOps.removeChild(parent, el)91 }92 }93 function isUnknownElement (vnode, inVPre) {94 return (95 !inVPre &&96 !vnode.ns &&97 !(98 config.ignoredElements.length &&99 config.ignoredElements.some(ignore => {100 return isRegExp(ignore)101 ? ignore.test(vnode.tag)102 : ignore === vnode.tag103 })104 ) &&105 config.isUnknownElement(vnode.tag)106 )107 }108 let creatingElmInVPre = 0109 // createElm å°±æ¯éè¿èæèç¹å建çå® DOM 并æå
¥å°å
¶ç¶èç¹ã110 function createElm (111 vnode,112 insertedVnodeQueue,113 parentElm,114 refElm,115 nested,116 ownerArray,117 index118 ) {119 if (isDef(vnode.elm) && isDef(ownerArray)) {120 // This vnode was used in a previous render!121 // now it's used as a new node, overwriting its elm would cause122 // potential patch errors down the road when it's used as an insertion123 // reference node. Instead, we clone the node on-demand before creating124 // associated DOM element for it.125 vnode = ownerArray[index] = cloneVNode(vnode)126 }127 vnode.isRootInsert = !nested // for transition enter check128 // createComponent æ¯ç»ä»¶ vnode èµ°çé»è¾129 // è¥æ¯ç»ä»¶ vnode ï¼é£ç´æ¥æ§è¡å® createComponent åå°±ç»æ createElm() å½æ°130 if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {131 return132 }133 const data = vnode.data134 const children = vnode.children135 const tag = vnode.tag136 if (isDef(tag)) {137 if (process.env.NODE_ENV !== 'production') {138 if (data && data.pre) {139 creatingElmInVPre++140 }141 // å¤æ tag æ¯å¦åæ³142 if (isUnknownElement(vnode, creatingElmInVPre)) {143 warn(144 'Unknown custom element: <' + tag + '> - did you ' +145 'register the component correctly? For recursive components, ' +146 'make sure to provide the "name" option.',147 vnode.context148 )149 }150 }151 vnode.elm = vnode.ns // é¦æ¬¡æ¸²æ vnode.ns 为 undefined152 ? nodeOps.createElementNS(vnode.ns, tag)153 : nodeOps.createElement(tag, vnode) // å建ä¸ä¸ªæ ç¾ä¸º tag ç空å
ç´ 154 setScope(vnode)155 /* istanbul ignore if */156 if (__WEEX__) {157 // in Weex, the default insertion order is parent-first.158 // List items can be optimized to use children-first insertion159 // with append="tree".160 const appendAsTree = isDef(data) && isTrue(data.appendAsTree)161 if (!appendAsTree) {162 if (isDef(data)) {163 invokeCreateHooks(vnode, insertedVnodeQueue)164 }165 insert(parentElm, vnode.elm, refElm)166 }167 createChildren(vnode, children, insertedVnodeQueue)168 if (appendAsTree) {169 if (isDef(data)) {170 invokeCreateHooks(vnode, insertedVnodeQueue)171 }172 insert(parentElm, vnode.elm, refElm)173 }174 } else {175 createChildren(vnode, children, insertedVnodeQueue) // éå½æ该 vnode çä½ä¸ºæ ¹èç¹æ·»å 好å®çåèç¹å½¢æ vnode tree å176 if (isDef(data)) {177 invokeCreateHooks(vnode, insertedVnodeQueue) // æ§è¡ææ create é©å并æ vnode push å° insertedVnodeQueue ä¸178 }179 insert(parentElm, vnode.elm, refElm) // æ DOM èç¹æå
¥å°ç¶èç¹ã180 }181 if (process.env.NODE_ENV !== 'production' && data && data.pre) {182 creatingElmInVPre--183 }184 } else if (isTrue(vnode.isComment)) {185 vnode.elm = nodeOps.createComment(vnode.text)186 insert(parentElm, vnode.elm, refElm)187 } else {188 vnode.elm = nodeOps.createTextNode(vnode.text)189 insert(parentElm, vnode.elm, refElm)190 }191 }192 function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {193 let i = vnode.data194 if (isDef(i)) {195 const isReactivated = isDef(vnode.componentInstance) && i.keepAlive196 if (isDef(i = i.hook) && isDef(i = i.init)) {197 // data.hook.init() // è¿æ¹æ³æ¯å建ç»ä»¶ vnode æ¶æå
¥çç»ä»¶é©åå½æ° init()198 // è¿ä¸ªæ¹æ³çä½ç¨å°±æ¯åå§ååç»ä»¶ãå建åç»ä»¶ç vnode 并æåç»ä»¶æè½½å°é¡µé¢ä¸199 i(vnode, false /* hydrating */) 200 }201 // after calling the init hook, if the vnode is a child component202 // it should've created a child instance and mounted it. the child203 // component also has set the placeholder vnode's elm.204 // in that case we can just return the element and be done.205 if (isDef(vnode.componentInstance)) {206 initComponent(vnode, insertedVnodeQueue)207 insert(parentElm, vnode.elm, refElm)208 if (isTrue(isReactivated)) {209 reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm)210 }211 return true212 }213 }214 }215 function initComponent (vnode, insertedVnodeQueue) {216 if (isDef(vnode.data.pendingInsert)) {217 insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert)218 vnode.data.pendingInsert = null219 }220 vnode.elm = vnode.componentInstance.$el221 if (isPatchable(vnode)) {222 invokeCreateHooks(vnode, insertedVnodeQueue)223 setScope(vnode)224 } else {225 // empty component root.226 // skip all element-related modules except for ref (#3455)227 registerRef(vnode)228 // make sure to invoke the insert hook229 insertedVnodeQueue.push(vnode)230 }231 }232 function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {233 let i234 // hack for #4339: a reactivated component with inner transition235 // does not trigger because the inner node's created hooks are not called236 // again. It's not ideal to involve module-specific logic in here but237 // there doesn't seem to be a better way to do it.238 let innerNode = vnode239 while (innerNode.componentInstance) {240 innerNode = innerNode.componentInstance._vnode241 if (isDef(i = innerNode.data) && isDef(i = i.transition)) {242 for (i = 0; i < cbs.activate.length; ++i) {243 cbs.activate[i](emptyNode, innerNode)244 }245 insertedVnodeQueue.push(innerNode)246 break247 }248 }249 // unlike a newly created component,250 // a reactivated keep-alive component doesn't insert itself251 insert(parentElm, vnode.elm, refElm)252 }253 function insert (parent, elm, ref) {254 if (isDef(parent)) {255 if (isDef(ref)) {256 if (nodeOps.parentNode(ref) === parent) {257 nodeOps.insertBefore(parent, elm, ref)258 }259 } else {260 nodeOps.appendChild(parent, elm)261 }262 }263 }264 function createChildren (vnode, children, insertedVnodeQueue) {265 if (Array.isArray(children)) {266 if (process.env.NODE_ENV !== 'production') {267 checkDuplicateKeys(children)268 }269 for (let i = 0; i < children.length; ++i) { // éååèæèç¹270 // æ ¹æ®èæèç¹å建çå®èç¹æå
¥ç¶èç¹ä¸ã271 createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i)272 }273 } else if (isPrimitive(vnode.text)) {274 // å¦ææ¯ææ¬èæèç¹ç´æ¥å建ææ¬èç¹æå
¥ç¶èç¹ä¸ã275 nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)))276 }277 }278 function isPatchable (vnode) {279 while (vnode.componentInstance) {280 vnode = vnode.componentInstance._vnode281 }282 return isDef(vnode.tag)283 }284 function invokeCreateHooks (vnode, insertedVnodeQueue) {285 for (let i = 0; i < cbs.create.length; ++i) {286 cbs.create[i](emptyNode, vnode)287 }288 i = vnode.data.hook // Reuse variable289 if (isDef(i)) {290 if (isDef(i.create)) i.create(emptyNode, vnode)291 if (isDef(i.insert)) insertedVnodeQueue.push(vnode)292 }293 }294 // set scope id attribute for scoped CSS.295 // this is implemented as a special case to avoid the overhead296 // of going through the normal attribute patching process.297 function setScope (vnode) {298 let i299 if (isDef(i = vnode.fnScopeId)) {300 nodeOps.setStyleScope(vnode.elm, i)301 } else {302 let ancestor = vnode303 while (ancestor) {304 if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) {305 nodeOps.setStyleScope(vnode.elm, i)306 }307 ancestor = ancestor.parent308 }309 }310 // for slot content they should also get the scopeId from the host instance.311 if (isDef(i = activeInstance) &&312 i !== vnode.context &&313 i !== vnode.fnContext &&314 isDef(i = i.$options._scopeId)315 ) {316 nodeOps.setStyleScope(vnode.elm, i)317 }318 }319 function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) {320 for (; startIdx <= endIdx; ++startIdx) {321 createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm, false, vnodes, startIdx)322 }323 }324 function invokeDestroyHook (vnode) {325 let i, j326 const data = vnode.data327 if (isDef(data)) {328 if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode)329 for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode)330 }331 if (isDef(i = vnode.children)) {332 for (j = 0; j < vnode.children.length; ++j) {333 invokeDestroyHook(vnode.children[j])334 }335 }336 }337 function removeVnodes (vnodes, startIdx, endIdx) {338 for (; startIdx <= endIdx; ++startIdx) {339 const ch = vnodes[startIdx]340 if (isDef(ch)) {341 if (isDef(ch.tag)) {342 removeAndInvokeRemoveHook(ch)343 invokeDestroyHook(ch)344 } else { // Text node345 removeNode(ch.elm)346 }347 }348 }349 }350 function removeAndInvokeRemoveHook (vnode, rm) {351 if (isDef(rm) || isDef(vnode.data)) {352 let i353 const listeners = cbs.remove.length + 1354 if (isDef(rm)) {355 // we have a recursively passed down rm callback356 // increase the listeners count357 rm.listeners += listeners358 } else {359 // directly removing360 rm = createRmCb(vnode.elm, listeners)361 }362 // recursively invoke hooks on child component root node363 if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) {364 removeAndInvokeRemoveHook(i, rm)365 }366 for (i = 0; i < cbs.remove.length; ++i) {367 cbs.remove[i](vnode, rm)368 }369 if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {370 i(vnode, rm)371 } else {372 rm()373 }374 } else {375 removeNode(vnode.elm)376 }377 }378 function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {379 let oldStartIdx = 0380 let newStartIdx = 0381 let oldEndIdx = oldCh.length - 1382 let oldStartVnode = oldCh[0]383 let oldEndVnode = oldCh[oldEndIdx]384 let newEndIdx = newCh.length - 1385 let newStartVnode = newCh[0]386 let newEndVnode = newCh[newEndIdx]387 let oldKeyToIdx, idxInOld, vnodeToMove, refElm388 // removeOnly is a special flag used only by <transition-group>389 // to ensure removed elements stay in correct relative positions390 // during leaving transitions391 const canMove = !removeOnly392 if (process.env.NODE_ENV !== 'production') {393 checkDuplicateKeys(newCh)394 }395 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {396 if (isUndef(oldStartVnode)) {397 oldStartVnode = oldCh[++oldStartIdx] // Vnode has been moved left398 } else if (isUndef(oldEndVnode)) {399 oldEndVnode = oldCh[--oldEndIdx]400 } else if (sameVnode(oldStartVnode, newStartVnode)) {401 patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)402 oldStartVnode = oldCh[++oldStartIdx]403 newStartVnode = newCh[++newStartIdx]404 } else if (sameVnode(oldEndVnode, newEndVnode)) {405 patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx)406 oldEndVnode = oldCh[--oldEndIdx]407 newEndVnode = newCh[--newEndIdx]408 } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right409 patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx)410 canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm))411 oldStartVnode = oldCh[++oldStartIdx]412 newEndVnode = newCh[--newEndIdx]413 } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left414 patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)415 canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)416 oldEndVnode = oldCh[--oldEndIdx]417 newStartVnode = newCh[++newStartIdx]418 } else {419 if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)420 idxInOld = isDef(newStartVnode.key)421 ? oldKeyToIdx[newStartVnode.key]422 : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)423 if (isUndef(idxInOld)) { // New element424 createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)425 } else {426 vnodeToMove = oldCh[idxInOld]427 if (sameVnode(vnodeToMove, newStartVnode)) {428 patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)429 oldCh[idxInOld] = undefined430 canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)431 } else {432 // same key but different element. treat as new element433 createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)434 }435 }436 newStartVnode = newCh[++newStartIdx]437 }438 }439 if (oldStartIdx > oldEndIdx) {440 refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm441 addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)442 } else if (newStartIdx > newEndIdx) {443 removeVnodes(oldCh, oldStartIdx, oldEndIdx)444 }445 }446 function checkDuplicateKeys (children) {447 const seenKeys = {}448 for (let i = 0; i < children.length; i++) {449 const vnode = children[i]450 const key = vnode.key451 if (isDef(key)) {452 if (seenKeys[key]) {453 warn(454 `Duplicate keys detected: '${key}'. This may cause an update error.`,455 vnode.context456 )457 } else {458 seenKeys[key] = true459 }460 }461 }462 }463 function findIdxInOld (node, oldCh, start, end) {464 for (let i = start; i < end; i++) {465 const c = oldCh[i]466 if (isDef(c) && sameVnode(node, c)) return i467 }468 }469 function patchVnode (470 oldVnode,471 vnode,472 insertedVnodeQueue,473 ownerArray,474 index,475 removeOnly476 ) {477 if (oldVnode === vnode) {478 return479 }480 if (isDef(vnode.elm) && isDef(ownerArray)) {481 // clone reused vnode482 vnode = ownerArray[index] = cloneVNode(vnode)483 }484 const elm = vnode.elm = oldVnode.elm485 if (isTrue(oldVnode.isAsyncPlaceholder)) {486 if (isDef(vnode.asyncFactory.resolved)) {487 hydrate(oldVnode.elm, vnode, insertedVnodeQueue)488 } else {489 vnode.isAsyncPlaceholder = true490 }491 return492 }493 // reuse element for static trees.494 // note we only do this if the vnode is cloned -495 // if the new node is not cloned it means the render functions have been496 // reset by the hot-reload-api and we need to do a proper re-render.497 if (isTrue(vnode.isStatic) &&498 isTrue(oldVnode.isStatic) &&499 vnode.key === oldVnode.key &&500 (isTrue(vnode.isCloned) || isTrue(vnode.isOnce))501 ) {502 vnode.componentInstance = oldVnode.componentInstance503 return504 }505 let i506 const data = vnode.data507 if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {508 i(oldVnode, vnode)509 }510 const oldCh = oldVnode.children511 const ch = vnode.children512 if (isDef(data) && isPatchable(vnode)) {513 for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode)514 if (isDef(i = data.hook) && isDef(i = i.update)) i(oldVnode, vnode)515 }516 if (isUndef(vnode.text)) {517 if (isDef(oldCh) && isDef(ch)) {518 if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly)519 } else if (isDef(ch)) {520 if (process.env.NODE_ENV !== 'production') {521 checkDuplicateKeys(ch)522 }523 if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, '')524 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue)525 } else if (isDef(oldCh)) {526 removeVnodes(oldCh, 0, oldCh.length - 1)527 } else if (isDef(oldVnode.text)) {528 nodeOps.setTextContent(elm, '')529 }530 } else if (oldVnode.text !== vnode.text) {531 nodeOps.setTextContent(elm, vnode.text)532 }533 if (isDef(data)) {534 if (isDef(i = data.hook) && isDef(i = i.postpatch)) i(oldVnode, vnode)535 }536 }537 function invokeInsertHook (vnode, queue, initial) {538 // delay insert hooks for component root nodes, invoke them after the539 // element is really inserted540 if (isTrue(initial) && isDef(vnode.parent)) {541 vnode.parent.data.pendingInsert = queue542 } else {543 for (let i = 0; i < queue.length; ++i) {544 queue[i].data.hook.insert(queue[i])545 }546 }547 }548 let hydrationBailed = false549 // list of modules that can skip create hook during hydration because they550 // are already rendered on the client or has no need for initialization551 // Note: style is excluded because it relies on initial clone for future552 // deep updates (#7063).553 const isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key')554 // Note: this is a browser-only function so we can assume elms are DOM nodes.555 function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {556 let i557 const { tag, data, children } = vnode558 inVPre = inVPre || (data && data.pre)559 vnode.elm = elm560 if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {561 vnode.isAsyncPlaceholder = true562 return true563 }564 // assert node match565 if (process.env.NODE_ENV !== 'production') {566 if (!assertNodeMatch(elm, vnode, inVPre)) {567 return false568 }569 }570 if (isDef(data)) {571 if (isDef(i = data.hook) && isDef(i = i.init)) i(vnode, true /* hydrating */)572 if (isDef(i = vnode.componentInstance)) {573 // child component. it should have hydrated its own tree.574 initComponent(vnode, insertedVnodeQueue)575 return true576 }577 }578 if (isDef(tag)) {579 if (isDef(children)) {580 // empty element, allow client to pick up and populate children581 if (!elm.hasChildNodes()) {582 createChildren(vnode, children, insertedVnodeQueue)583 } else {584 // v-html and domProps: innerHTML585 if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {586 if (i !== elm.innerHTML) {587 /* istanbul ignore if */588 if (process.env.NODE_ENV !== 'production' &&589 typeof console !== 'undefined' &&590 !hydrationBailed591 ) {592 hydrationBailed = true593 console.warn('Parent: ', elm)594 console.warn('server innerHTML: ', i)595 console.warn('client innerHTML: ', elm.innerHTML)596 }597 return false598 }599 } else {600 // iterate and compare children lists601 let childrenMatch = true602 let childNode = elm.firstChild603 for (let i = 0; i < children.length; i++) {604 if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue, inVPre)) {605 childrenMatch = false606 break607 }608 childNode = childNode.nextSibling609 }610 // if childNode is not null, it means the actual childNodes list is611 // longer than the virtual children list.612 if (!childrenMatch || childNode) {613 /* istanbul ignore if */614 if (process.env.NODE_ENV !== 'production' &&615 typeof console !== 'undefined' &&616 !hydrationBailed617 ) {618 hydrationBailed = true619 console.warn('Parent: ', elm)620 console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children)621 }622 return false623 }624 }625 }626 }627 if (isDef(data)) {628 let fullInvoke = false629 for (const key in data) {630 if (!isRenderedModule(key)) {631 fullInvoke = true632 invokeCreateHooks(vnode, insertedVnodeQueue)633 break634 }635 }636 if (!fullInvoke && data['class']) {637 // ensure collecting deps for deep class bindings for future updates638 traverse(data['class'])639 }640 }641 } else if (elm.data !== vnode.text) {642 elm.data = vnode.text643 }644 return true645 }646 function assertNodeMatch (node, vnode, inVPre) {647 if (isDef(vnode.tag)) {648 return vnode.tag.indexOf('vue-component') === 0 || (649 !isUnknownElement(vnode, inVPre) &&650 vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase())651 )652 } else {653 return node.nodeType === (vnode.isComment ? 8 : 3)654 }655 }656 return function patch (oldVnode, vnode, hydrating, removeOnly) {657 // é¦æ¬¡æ¸²æçæ¶åï¼ oldVnode æ¯ vm.$elï¼vnode å°±æ¯ _render() çæç vnode658 if (isUndef(vnode)) {659 if (isDef(oldVnode)) invokeDestroyHook(oldVnode)660 return661 }662 let isInitialPatch = false663 const insertedVnodeQueue = [] // æå
¥ç vnode éå664 if (isUndef(oldVnode)) { // ç»ä»¶ä¸ä¼æ el å±æ§ï¼æ以è¿é为空665 // empty mount (likely as component), create new root element666 isInitialPatch = true667 createElm(vnode, insertedVnodeQueue)668 } else {669 const isRealElement = isDef(oldVnode.nodeType) // é¦æ¬¡æ¸²æçæ¶åæ¯çå®èç¹670 if (!isRealElement && sameVnode(oldVnode, vnode)) {671 // patch existing root node672 patchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly)673 } else {674 if (isRealElement) {675 // mounting to a real element676 // check if this is server-rendered content and if we can perform677 // a successful hydration.678 if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {679 oldVnode.removeAttribute(SSR_ATTR)680 hydrating = true681 }682 if (isTrue(hydrating)) {683 if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {684 invokeInsertHook(vnode, insertedVnodeQueue, true)685 return oldVnode686 } else if (process.env.NODE_ENV !== 'production') {687 warn(688 'The client-side rendered virtual DOM tree is not matching ' +689 'server-rendered content. This is likely caused by incorrect ' +690 'HTML markup, for example nesting block-level elements inside ' +691 '<p>, or missing <tbody>. Bailing hydration and performing ' +692 'full client-side render.'693 )694 }695 }696 // either not server-rendered, or hydration failed.697 // create an empty node and replace it698 oldVnode = emptyNodeAt(oldVnode) // æ ¹æ®æè½½ç¹å建ä¸ä¸ªç©ºèæèç¹699 }700 // replacing existing element701 const oldElm = oldVnode.elm // ä¸é¢ç©ºèæèç¹ç elm å±æ§å¯¹åºå
¶åæ¬ççå® DOM èç¹702 const parentElm = nodeOps.parentNode(oldElm) // é¦æ¬¡æ¸²ææ¶ï¼å¯¹äºæ们ä¾åæ¥è¯´ï¼æè½½ç¹çç¶èç¹å°±æ¯ body æ ç¾ç DOM èç¹703 // create new node704 // createElm çä½ç¨æ¯éè¿èæèç¹å建çå®ç DOM 并æå
¥å°å®çç¶èç¹ä¸705 createElm(706 vnode,707 insertedVnodeQueue,708 // extremely rare edge case: do not insert if old element is in a709 // leaving transition. Only happens when combining transition +710 // keep-alive + HOCs. (#4590)711 oldElm._leaveCb ? null : parentElm,712 nodeOps.nextSibling(oldElm)713 )714 // update parent placeholder node element, recursively715 // è¿æ¯ç»ä»¶æ¶åï¼æä¸èè716 if (isDef(vnode.parent)) {717 let ancestor = vnode.parent718 const patchable = isPatchable(vnode)719 while (ancestor) {720 for (let i = 0; i < cbs.destroy.length; ++i) {721 cbs.destroy[i](ancestor)722 }723 ancestor.elm = vnode.elm724 if (patchable) {725 for (let i = 0; i < cbs.create.length; ++i) {726 cbs.create[i](emptyNode, ancestor)727 }728 // #6513729 // invoke insert hooks that may have been merged by create hooks.730 // e.g. for directives that uses the "inserted" hook.731 const insert = ancestor.data.hook.insert732 if (insert.merged) {733 // start at index 1 to avoid re-invoking component mounted hook734 for (let i = 1; i < insert.fns.length; i++) {735 insert.fns[i]()736 }737 }738 } else {739 registerRef(ancestor)740 }741 ancestor = ancestor.parent742 }743 }744 // destroy old node745 if (isDef(parentElm)) {746 removeVnodes([oldVnode], 0, 0) // å¨éå½å建å®çå® DOM æ 并æå
¥å°æè½½ç¹çç¶èç¹åï¼å°±å é¤ææè½½ç¹ DOM ã747 } else if (isDef(oldVnode.tag)) {748 invokeDestroyHook(oldVnode)749 }750 }751 }752 invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch)753 return vnode.elm754 }...
snabbdom.js
Source:snabbdom.js
...3import htmlDomApi from './htmldomapi';4function isUndef(s) {5 return s === undefined;6}7function isDef(s) {8 return s !== undefined;9}10var emptyNode = vnode('', {}, [], undefined, undefined);11function sameVnode(vnode1, vnode2) {12 return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel;13}14function isVnode(vnode) {15 return vnode.sel !== undefined;16}17function createKeyToOldIdx(children, beginIdx, endIdx) {18 var i,19 map = {},20 key,21 ch;22 for (i = beginIdx; i <= endIdx; ++i) {23 ch = children[i];24 if (ch != null) {25 key = ch.key;26 if (key !== undefined) map[key] = i;27 }28 }29 return map;30}31var hooks = ['create', 'update', 'remove', 'destroy', 'pre', 'post'];32export { h } from './h';33export { thunk } from './thunk';34export function init(modules, domApi) {35 var i,36 j,37 cbs = {};38 var api = domApi !== undefined ? domApi : htmlDomApi;39 for (i = 0; i < hooks.length; ++i) {40 cbs[hooks[i]] = [];41 for (j = 0; j < modules.length; ++j) {42 var hook = modules[j][hooks[i]];43 if (hook !== undefined) {44 cbs[hooks[i]].push(hook);45 }46 }47 }48 function emptyNodeAt(elm) {49 var id = elm.id ? '#' + elm.id : '';50 var c = elm.className ? '.' + elm.className.split(' ').join('.') : '';51 return vnode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm);52 }53 function createRmCb(childElm, listeners) {54 return function rmCb() {55 if (--listeners === 0) {56 var parent_1 = api.parentNode(childElm);57 api.removeChild(parent_1, childElm);58 }59 };60 }61 function createElm(vnode, insertedVnodeQueue) {62 var i,63 data = vnode.data;64 if (data !== undefined) {65 if (isDef(i = data.hook) && isDef(i = i.init)) {66 i(vnode);67 data = vnode.data;68 }69 }70 var children = vnode.children,71 sel = vnode.sel;72 if (sel === '!') {73 if (isUndef(vnode.text)) {74 vnode.text = '';75 }76 vnode.elm = api.createComment(vnode.text);77 } else if (sel !== undefined) {78 // Parse selector79 var hashIdx = sel.indexOf('#');80 var dotIdx = sel.indexOf('.', hashIdx);81 var hash = hashIdx > 0 ? hashIdx : sel.length;82 var dot = dotIdx > 0 ? dotIdx : sel.length;83 var tag = hashIdx !== -1 || dotIdx !== -1 ? sel.slice(0, Math.min(hash, dot)) : sel;84 var elm = vnode.elm = isDef(data) && isDef(i = data.ns) ? api.createElementNS(i, tag) : api.createElement(tag);85 if (hash < dot) elm.setAttribute('id', sel.slice(hash + 1, dot));86 if (dotIdx > 0) elm.setAttribute('class', sel.slice(dot + 1).replace(/\./g, ' '));87 for (i = 0; i < cbs.create.length; ++i) {88 cbs.create[i](emptyNode, vnode);89 }90 if (is.array(children)) {91 for (i = 0; i < children.length; ++i) {92 var ch = children[i];93 if (ch != null) {94 api.appendChild(elm, createElm(ch, insertedVnodeQueue));95 }96 }97 } else if (is.primitive(vnode.text)) {98 api.appendChild(elm, api.createTextNode(vnode.text));99 }100 i = vnode.data.hook; // Reuse variable101 if (isDef(i)) {102 if (i.create) i.create(emptyNode, vnode);103 if (i.insert) insertedVnodeQueue.push(vnode);104 }105 } else {106 vnode.elm = api.createTextNode(vnode.text);107 }108 return vnode.elm;109 }110 function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {111 for (; startIdx <= endIdx; ++startIdx) {112 var ch = vnodes[startIdx];113 if (ch != null) {114 api.insertBefore(parentElm, createElm(ch, insertedVnodeQueue), before);115 }116 }117 }118 function invokeDestroyHook(vnode) {119 var i,120 j,121 data = vnode.data;122 if (data !== undefined) {123 if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode);124 for (i = 0; i < cbs.destroy.length; ++i) {125 cbs.destroy[i](vnode);126 }127 if (vnode.children !== undefined) {128 for (j = 0; j < vnode.children.length; ++j) {129 i = vnode.children[j];130 if (i != null && typeof i !== "string") {131 invokeDestroyHook(i);132 }133 }134 }135 }136 }137 function removeVnodes(parentElm, vnodes, startIdx, endIdx) {138 for (; startIdx <= endIdx; ++startIdx) {139 var i_1 = void 0,140 listeners = void 0,141 rm = void 0,142 ch = vnodes[startIdx];143 if (ch != null) {144 if (isDef(ch.sel)) {145 invokeDestroyHook(ch);146 listeners = cbs.remove.length + 1;147 rm = createRmCb(ch.elm, listeners);148 for (i_1 = 0; i_1 < cbs.remove.length; ++i_1) {149 cbs.remove[i_1](ch, rm);150 }151 if (isDef(i_1 = ch.data) && isDef(i_1 = i_1.hook) && isDef(i_1 = i_1.remove)) {152 i_1(ch, rm);153 } else {154 rm();155 }156 } else {157 api.removeChild(parentElm, ch.elm);158 }159 }160 }161 }162 function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) {163 var oldStartIdx = 0,164 newStartIdx = 0;165 var oldEndIdx = oldCh.length - 1;166 var oldStartVnode = oldCh[0];167 var oldEndVnode = oldCh[oldEndIdx];168 var newEndIdx = newCh.length - 1;169 var newStartVnode = newCh[0];170 var newEndVnode = newCh[newEndIdx];171 var oldKeyToIdx;172 var idxInOld;173 var elmToMove;174 var before;175 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {176 if (oldStartVnode == null) {177 oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left178 } else if (oldEndVnode == null) {179 oldEndVnode = oldCh[--oldEndIdx];180 } else if (newStartVnode == null) {181 newStartVnode = newCh[++newStartIdx];182 } else if (newEndVnode == null) {183 newEndVnode = newCh[--newEndIdx];184 } else if (sameVnode(oldStartVnode, newStartVnode)) {185 patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);186 oldStartVnode = oldCh[++oldStartIdx];187 newStartVnode = newCh[++newStartIdx];188 } else if (sameVnode(oldEndVnode, newEndVnode)) {189 patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);190 oldEndVnode = oldCh[--oldEndIdx];191 newEndVnode = newCh[--newEndIdx];192 } else if (sameVnode(oldStartVnode, newEndVnode)) {193 patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);194 api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm));195 oldStartVnode = oldCh[++oldStartIdx];196 newEndVnode = newCh[--newEndIdx];197 } else if (sameVnode(oldEndVnode, newStartVnode)) {198 patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);199 api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);200 oldEndVnode = oldCh[--oldEndIdx];201 newStartVnode = newCh[++newStartIdx];202 } else {203 if (oldKeyToIdx === undefined) {204 oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);205 }206 idxInOld = oldKeyToIdx[newStartVnode.key];207 if (isUndef(idxInOld)) {208 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);209 newStartVnode = newCh[++newStartIdx];210 } else {211 elmToMove = oldCh[idxInOld];212 if (elmToMove.sel !== newStartVnode.sel) {213 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);214 } else {215 patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);216 oldCh[idxInOld] = undefined;217 api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);218 }219 newStartVnode = newCh[++newStartIdx];220 }221 }222 }223 if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {224 if (oldStartIdx > oldEndIdx) {225 before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;226 addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);227 } else {228 removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);229 }230 }231 }232 function patchVnode(oldVnode, vnode, insertedVnodeQueue) {233 var i, hook;234 if (isDef(i = vnode.data) && isDef(hook = i.hook) && isDef(i = hook.prepatch)) {235 i(oldVnode, vnode);236 }237 var elm = vnode.elm = oldVnode.elm;238 var oldCh = oldVnode.children;239 var ch = vnode.children;240 if (oldVnode === vnode) return;241 if (vnode.data !== undefined) {242 for (i = 0; i < cbs.update.length; ++i) {243 cbs.update[i](oldVnode, vnode);244 }245 i = vnode.data.hook;246 if (isDef(i) && isDef(i = i.update)) i(oldVnode, vnode);247 }248 if (isUndef(vnode.text)) {249 if (isDef(oldCh) && isDef(ch)) {250 if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue);251 } else if (isDef(ch)) {252 if (isDef(oldVnode.text)) api.setTextContent(elm, '');253 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);254 } else if (isDef(oldCh)) {255 removeVnodes(elm, oldCh, 0, oldCh.length - 1);256 } else if (isDef(oldVnode.text)) {257 api.setTextContent(elm, '');258 }259 } else if (oldVnode.text !== vnode.text) {260 api.setTextContent(elm, vnode.text);261 }262 if (isDef(hook) && isDef(i = hook.postpatch)) {263 i(oldVnode, vnode);264 }265 }266 return function patch(oldVnode, vnode) {267 var i, elm, parent;268 var insertedVnodeQueue = [];269 for (i = 0; i < cbs.pre.length; ++i) {270 cbs.pre[i]();271 }272 if (!isVnode(oldVnode)) {273 oldVnode = emptyNodeAt(oldVnode);274 }275 if (sameVnode(oldVnode, vnode)) {276 patchVnode(oldVnode, vnode, insertedVnodeQueue);...
render.js
Source:render.js
...33 }34 }35}36function renderNode (node, isRoot, context) {37 if (isDef(node.componentOptions)) {38 renderComponent(node, isRoot, context)39 } else {40 if (isDef(node.tag)) {41 renderElement(node, isRoot, context)42 } else if (isTrue(node.isComment)) {43 context.write(44 `<!--${node.text}-->`,45 context.next46 )47 } else {48 context.write(49 node.raw ? node.text : escape(String(node.text)),50 context.next51 )52 }53 }54}55function renderComponent (node, isRoot, context) {56 const { write, next, userContext } = context57 // check cache hit58 const Ctor = node.componentOptions.Ctor59 const getKey = Ctor.options.serverCacheKey60 const name = Ctor.options.name61 // exposed by vue-loader, need to call this if cache hit because62 // component lifecycle hooks will not be called.63 const registerComponent = Ctor.options._ssrRegister64 if (write.caching && isDef(registerComponent)) {65 write.componentBuffer[write.componentBuffer.length - 1].add(registerComponent)66 }67 const cache = context.cache68 if (isDef(getKey) && isDef(cache) && isDef(name)) {69 const key = name + '::' + getKey(node.componentOptions.propsData)70 const { has, get } = context71 if (isDef(has)) {72 has(key, hit => {73 if (hit === true && isDef(get)) {74 get(key, res => {75 if (isDef(registerComponent)) {76 registerComponent(userContext)77 }78 res.components.forEach(register => register(userContext))79 write(res.html, next)80 })81 } else {82 renderComponentWithCache(node, isRoot, key, context)83 }84 })85 } else if (isDef(get)) {86 get(key, res => {87 if (isDef(res)) {88 if (isDef(registerComponent)) {89 registerComponent(userContext)90 }91 res.components.forEach(register => register(userContext))92 write(res.html, next)93 } else {94 renderComponentWithCache(node, isRoot, key, context)95 }96 })97 }98 } else {99 if (isDef(getKey) && isUndef(cache)) {100 warnOnce(101 `[vue-server-renderer] Component ${102 Ctor.options.name || '(anonymous)'103 } implemented serverCacheKey, ` +104 'but no cache was provided to the renderer.'105 )106 }107 if (isDef(getKey) && isUndef(name)) {108 warnOnce(109 `[vue-server-renderer] Components that implement "serverCacheKey" ` +110 `must also define a unique "name" option.`111 )112 }113 renderComponentInner(node, isRoot, context)114 }115}116function renderComponentWithCache (node, isRoot, key, context) {117 const write = context.write118 write.caching = true119 const buffer = write.cacheBuffer120 const bufferIndex = buffer.push('') - 1121 const componentBuffer = write.componentBuffer122 componentBuffer.push(new Set())123 context.renderStates.push({124 type: 'ComponentWithCache',125 key,126 buffer,127 bufferIndex,128 componentBuffer129 })130 renderComponentInner(node, isRoot, context)131}132function renderComponentInner (node, isRoot, context) {133 const prevActive = context.activeInstance134 // expose userContext on vnode135 node.ssrContext = context.userContext136 const child = context.activeInstance = createComponentInstanceForVnode(137 node,138 context.activeInstance139 )140 node.ssrContext = null141 normalizeRender(child)142 const childNode = child._render()143 childNode.parent = node144 context.renderStates.push({145 type: 'Component',146 prevActive147 })148 renderNode(childNode, isRoot, context)149}150function renderElement (el, isRoot, context) {151 if (isTrue(isRoot)) {152 if (!el.data) el.data = {}153 if (!el.data.attrs) el.data.attrs = {}154 el.data.attrs[SSR_ATTR] = 'true'155 }156 const startTag = renderStartingTag(el, context)157 const endTag = `</${el.tag}>`158 const { write, next } = context159 if (context.isUnaryTag(el.tag)) {160 write(startTag, next)161 } else if (isUndef(el.children) || el.children.length === 0) {162 write(startTag + endTag, next)163 } else {164 const children: Array<VNode> = el.children165 context.renderStates.push({166 type: 'Element',167 rendered: 0,168 total: children.length,169 endTag, children170 })171 write(startTag, next)172 }173}174function hasAncestorData (node: VNode) {175 const parentNode = node.parent176 return isDef(parentNode) && (isDef(parentNode.data) || hasAncestorData(parentNode))177}178function getVShowDirectiveInfo (node: VNode): ?VNodeDirective {179 let dir: VNodeDirective180 let tmp181 while (isDef(node)) {182 if (node.data && node.data.directives) {183 tmp = node.data.directives.find(dir => dir.name === 'show')184 if (tmp) {185 dir = tmp186 }187 }188 node = node.parent189 }190 return dir191}192function renderStartingTag (node: VNode, context) {193 let markup = `<${node.tag}`194 const { directives, modules } = context195 // construct synthetic data for module processing196 // because modules like style also produce code by parent VNode data197 if (isUndef(node.data) && hasAncestorData(node)) {198 node.data = {}199 }200 if (isDef(node.data)) {201 // check directives202 const dirs = node.data.directives203 if (dirs) {204 for (let i = 0; i < dirs.length; i++) {205 const name = dirs[i].name206 const dirRenderer = directives[name]207 if (dirRenderer && name !== 'show') {208 // directives mutate the node's data209 // which then gets rendered by modules210 dirRenderer(node, dirs[i])211 }212 }213 }214 // v-show directive needs to be merged from parent to child215 const vshowDirectiveInfo = getVShowDirectiveInfo(node)216 if (vshowDirectiveInfo) {217 directives.show(node, vshowDirectiveInfo)218 }219 // apply other modules220 for (let i = 0; i < modules.length; i++) {221 const res = modules[i](node)222 if (res) {223 markup += res224 }225 }226 }227 // attach scoped CSS ID228 let scopeId229 const activeInstance = context.activeInstance230 if (isDef(activeInstance) &&231 activeInstance !== node.context &&232 isDef(scopeId = activeInstance.$options._scopeId)) {233 markup += ` ${(scopeId: any)}`234 }235 while (isDef(node)) {236 if (isDef(scopeId = node.context.$options._scopeId)) {237 markup += ` ${scopeId}`238 }239 node = node.parent240 }241 return markup + '>'242}243/*å建renderå½æ°*/244export function createRenderFunction (245 modules: Array<Function>,246 directives: Object,247 isUnaryTag: Function,248 cache: any249) {250 return function render (...
create-element.js
Source:create-element.js
...49 children?: any,50 normalizationType?: number51): VNode | Array<VNode> {52 // data çå个å±æ§ä¸å
许æ¯ååºå¼çï¼æ¯ä¸ª render å½æ°ä¸ä¼ è¿ createElement ç data å¿
é¡»æ¯ä¸ä¸ª fresh object.53 if (isDef(data) && isDef((data: any).__ob__)) { // æ .__ob__ è¿ä¸ªå±æ§è¡¨ç¤ºå·²ååºå¼54 process.env.NODE_ENV !== 'production' && warn(55 `Avoid using observed data object as vnode data: ${JSON.stringify(data)}\n` +56 'Always create fresh vnode data objects in each render!',57 context58 )59 return createEmptyVNode() // 该æ¹æ³å¾ç®åï¼å¯ä»¥ç解为就æ¯å建ä¸ä¸ªæ³¨é vnodeã60 }61 // object syntax in v-bind62 if (isDef(data) && isDef(data.is)) {63 tag = data.is64 }65 if (!tag) {66 // in case of component :is set to falsy value67 return createEmptyVNode()68 }69 // warn against non-primitive key70 if (process.env.NODE_ENV !== 'production' &&71 isDef(data) && isDef(data.key) && !isPrimitive(data.key) // data ç key åªè½æ¯åºç¡ç±»åçå¼ã72 ) {73 if (!__WEEX__ || !('@binding' in data.key)) {74 warn(75 'Avoid using non-primitive value as key, ' +76 'use string/number value instead.',77 context78 )79 }80 }81 // support single function children as default scoped slot // slot ç¸å
³æä¸è®¨è®º82 if (Array.isArray(children) &&83 typeof children[0] === 'function'84 ) {85 data = data || {}86 data.scopedSlots = { default: children[0] }87 children.length = 088 }89 // 90 if (normalizationType === ALWAYS_NORMALIZE) { // é对æåç render ä¸æåç data åæ°ä¼ ç» createElement(tag, data, children, normalizationType, true)91 // ææåµå¥ç children æ°ç»(vnode[])æå¹³ï¼åæä¸ç»´æ°ç»ã92 children = normalizeChildren(children) // å¯¹ä¼ ç children åèç¹è¿è¡åºåå(æ£å¸¸å) =ã æåçå¯è½ä¼ è¿æ¥ç children å¯è½æ¯åµå¥äºå¾å¤å±åèç¹ï¼è¿éå°±æåµå¥çåèç¹é½ååºæ¥æ平为ä¸ä½æ°ç»ã93 } else if (normalizationType === SIMPLE_NORMALIZE) { // é对ç¼è¯èæ¥ç render å½æ°è°ç¨ç createElement(tag, data, children, normalizationType, false);94 // æåµå¥ç children æ°ç»æå¹³ï¼åæä¸ç»´æ°ç»ã95 children = simpleNormalizeChildren(children) // 对 children ç®åæ£å¸¸å => ç¼è¯èæ¥çè§å®ä¼ å
¥ç children æå¤åºç°ä¸å±åµå¥ï¼ä¹å°±æ¯äºç»´æ°ç»ï¼è¿éæ平为ä¸ç»´æ°ç»ã96 }97 let vnode, ns98 if (typeof tag === 'string') {99 let Ctor100 ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)101 if (config.isReservedTag(tag)) { // html native æ ç¾102 // platform built-in elements103 if (process.env.NODE_ENV !== 'production' && isDef(data) && isDef(data.nativeOn)) {104 warn(105 `The .native modifier for v-on is only valid on components but it was used on <${tag}>.`,106 context107 )108 }109 // æ ¹æ® tag, data, children, context å建ä¸ä¸ª vnodeã110 vnode = new VNode(111 config.parsePlatformTagName(tag), data, children,112 undefined, undefined, context113 )114 } else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {115 // component116 vnode = createComponent(Ctor, data, context, children, tag)117 } else {118 // unknown or unlisted namespaced elements119 // check at runtime because it may get assigned a namespace when its120 // parent normalizes children121 vnode = new VNode(122 tag, data, children,123 undefined, undefined, context124 )125 }126 } else { // tag è¿å¯è½ä¼ ç»ä»¶ï¼æä¸çã127 // direct component options / constructor128 vnode = createComponent(tag, data, context, children)129 }130 if (Array.isArray(vnode)) {131 return vnode132 } else if (isDef(vnode)) {133 if (isDef(ns)) applyNS(vnode, ns)134 if (isDef(data)) registerDeepBindings(data)135 return vnode // è¿å vnode136 } else {137 return createEmptyVNode()138 }139}140function applyNS (vnode, ns, force) {141 vnode.ns = ns142 if (vnode.tag === 'foreignObject') {143 // use default namespace inside foreignObject144 ns = undefined145 force = true146 }147 if (isDef(vnode.children)) {148 for (let i = 0, l = vnode.children.length; i < l; i++) {149 const child = vnode.children[i]150 if (isDef(child.tag) && (151 isUndef(child.ns) || (isTrue(force) && child.tag !== 'svg'))) {152 applyNS(child, ns, force)153 }154 }155 }156}157// ref #5318158// necessary to ensure parent re-render when deep bindings like :style and159// :class are used on slot nodes160function registerDeepBindings (data) {161 if (isObject(data.style)) {162 traverse(data.style)163 }164 if (isObject(data.class)) {...
resolve-async-component.js
Source:resolve-async-component.js
...17 baseCtor: Class<Component>,18 context: Component19): Class<Component> | void {20 /*åºéç»ä»¶å·¥åè¿ååºéç»ä»¶*/21 if (isTrue(factory.error) && isDef(factory.errorComp)) {22 return factory.errorComp23 }24 /*resovedæ¶åè¿åresolvedç»ä»¶*/25 if (isDef(factory.resolved)) {26 return factory.resolved27 }28 /*å è½½ç»ä»¶*/29 if (isTrue(factory.loading) && isDef(factory.loadingComp)) {30 return factory.loadingComp31 }32 if (isDef(factory.contexts)) {33 // already pending34 factory.contexts.push(context)35 } else {36 const contexts = factory.contexts = [context]37 let sync = true38 const forceRender = () => {39 for (let i = 0, l = contexts.length; i < l; i++) {40 contexts[i].$forceUpdate()41 }42 }43 const resolve = once((res: Object | Class<Component>) => {44 // cache resolved45 factory.resolved = ensureCtor(res, baseCtor)46 // invoke callbacks only if this is not a synchronous resolve47 // (async resolves are shimmed as synchronous during SSR)48 if (!sync) {49 forceRender()50 }51 })52 const reject = once(reason => {53 process.env.NODE_ENV !== 'production' && warn(54 `Failed to resolve async component: ${String(factory)}` +55 (reason ? `\nReason: ${reason}` : '')56 )57 if (isDef(factory.errorComp)) {58 factory.error = true59 forceRender()60 }61 })62 const res = factory(resolve, reject)63 if (isObject(res)) {64 if (typeof res.then === 'function') {65 // () => Promise66 if (isUndef(factory.resolved)) {67 res.then(resolve, reject)68 }69 } else if (isDef(res.component) && typeof res.component.then === 'function') {70 res.component.then(resolve, reject)71 if (isDef(res.error)) {72 factory.errorComp = ensureCtor(res.error, baseCtor)73 }74 if (isDef(res.loading)) {75 factory.loadingComp = ensureCtor(res.loading, baseCtor)76 if (res.delay === 0) {77 factory.loading = true78 } else {79 setTimeout(() => {80 if (isUndef(factory.resolved) && isUndef(factory.error)) {81 factory.loading = true82 forceRender()83 }84 }, res.delay || 200)85 }86 }87 if (isDef(res.timeout)) {88 setTimeout(() => {89 reject(90 process.env.NODE_ENV !== 'production'91 ? `timeout (${res.timeout}ms)`92 : null93 )94 }, res.timeout)95 }96 }97 }98 sync = false99 // return in case resolved synchronously100 return factory.loading101 ? factory.loadingComp...
Using AI Code Generation
1const { isDef } = require('playwright/lib/utils/utils');2console.log(isDef(null));3console.log(isDef(undefined));4console.log(isDef(0));5console.log(isDef(''));6console.log(isDef(false));7console.log(isDef({}));8console.log(isDef([]));9const { isDef } = require('playwright/lib/utils/utils');10console.log(isDef(null));11console.log(isDef(undefined));12console.log(isDef(0));13console.log(isDef(''));14console.log(isDef(false));15console.log(isDef({}));16console.log(isDef([]));17const { isString } = require('playwright/lib/utils/utils');18console.log(isString(null));19console.log(isString(undefined));20console.log(isString(0));21console.log(isString(''));22console.log(isString(false));23console.log(isString({}));24console.log(isString([]));25const { isNumber } = require('playwright/lib/utils/utils');26console.log(isNumber(null));27console.log(isNumber(undefined));28console.log(isNumber(0));29console.log(isNumber(''));30console.log(isNumber(false));31console.log(isNumber({}));32console.log(isNumber([]));
Using AI Code Generation
1const { isDef } = require('playwright/lib/utils/utils');2console.log(isDef({}));3console.log(isDef(null));4console.log(isDef(undefined));5console.log(isDef(0));6console.log(isDef(1));7console.log(isDef(''));8console.log(isDef('hello'));9console.log(isDef([]));10console.log(isDef([1]));11console.log(isDef({}));12var request = require('request');13request({14 form: {15 }16}, function(err, response, body) {17 if (err) {18 console.error(err);19 return;20 }21 console.log(response.statusCode, body);22});23var request = require('request');24request({25 form: {26 }27}, function(err, response, body) {28 if (err) {29 console.error(err);30 return;31 }32 console.log(response.statusCode, body);33});34var request = require('request');35request({
Using AI Code Generation
1const {isDef} = require('playwright/lib/internal/utils/utils');2const {isDef} = require('playwright/lib/internal/utils/utils');3test('test', async ({page}) => {4});5Your name to display (optional):6Your name to display (optional):
Using AI Code Generation
1const { isDef } = require('playwright/lib/utils/utils')2const { isDef } = require('playwright')3const { isDef } = require('playwright/lib/utils/utils')4const { isDef } = require('playwright')5const { isDef } = require('playwright/lib/utils/utils')6const { isDef } = require('playwright')7const { isDef } = require('playwright/lib/utils/utils')8const { isDef } = require('playwright')9const { isDef } = require('playwright/lib/utils/utils')10const { isDef } = require('playwright')11const { isDef } = require('playwright/lib/utils/utils')12const { isDef } = require('playwright')13const { isDef } = require('playwright/lib/utils/utils')14const { isDef } = require('playwright')15const { isDef } = require('playwright/lib/utils/utils')16const { isDef } = require('playwright')17const { isDef } = require('playwright/lib/utils/utils')18const { isDef } = require('playwright')19const { isDef } = require('playwright/lib/utils/utils')20const { isDef } = require('playwright')21const { isDef } = require('playwright/lib/utils/utils')
Using AI Code Generation
1const { isDef } = require('@playwright/test/lib/server/dom');2const { test, expect } = require('@playwright/test');3test('Check if element is defined', async ({ page }) => {4 const element = await page.$('h1');5 expect(isDef(element)).toBe(true);6});
Using AI Code Generation
1const { isDef } = require('playwright/lib/utils/utils');2const { test } = require('@playwright/test');3test('example test', async ({ page }) => {4 const element = await page.$('#myElement');5 if (isDef(element)) {6 await element.click();7 }8});9const { isNotDef } = require('playwright/lib/utils/utils');10const { test } = require('@playwright/test');11test('example test', async ({ page }) => {12 const element = await page.$('#myElement');13 if (isNotDef(element)) {14 await page.click('#myElement');15 }16});17const { isString } = require('playwright/lib/utils/utils');18const { test } = require('@playwright/test');19test('example test', async ({ page }) => {20 const element = await page.$('#myElement');21 if (isString(element)) {22 await page.click('#myElement');23 }24});
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!