Best JavaScript code snippet using storybook-root
patch.js
Source:patch.js
1/**2 * Virtual DOM patching algorithm based on Snabbdom by3 * Simon Friis Vindum (@paldepind)4 * Licensed under the MIT License5 * https://github.com/paldepind/snabbdom/blob/master/LICENSE6 *7 * modified by Evan You (@yyx990803)8 *9 * Not type-checking this because this file is perf-critical and the cost10 * of making flow understand it is not worth it.11 */12import VNode, { cloneVNode } from './vnode'13import config from '../config'14import { SSR_ATTR } from 'shared/constants'15import { registerRef } from './modules/ref'16import { traverse } from '../observer/traverse'17import { activeInstance } from '../instance/lifecycle'18import { isTextInputType } from 'web/util/element'19import {20 warn,21 isDef,22 isUndef,23 isTrue,24 makeMap,25 isRegExp,26 isPrimitive27} from '../util/index'28export const emptyNode = new VNode('', {}, [])29const hooks = ['create', 'activate', 'update', 'remove', 'destroy']30function sameVnode (a, b) {31 return (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 = {}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 function createElm (110 vnode,111 insertedVnodeQueue,112 parentElm,113 refElm,114 nested,115 ownerArray,116 index117 ) {118 if (isDef(vnode.elm) && isDef(ownerArray)) {119 // This vnode was used in a previous render!120 // now it's used as a new node, overwriting its elm would cause121 // potential patch errors down the road when it's used as an insertion122 // reference node. Instead, we clone the node on-demand before creating123 // associated DOM element for it.124 vnode = ownerArray[index] = cloneVNode(vnode)125 }126 vnode.isRootInsert = !nested // for transition enter check127 if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {128 return129 }130 const data = vnode.data131 const children = vnode.children132 const tag = vnode.tag133 if (isDef(tag)) {134 if (process.env.NODE_ENV !== 'production') {135 if (data && data.pre) {136 creatingElmInVPre++137 }138 if (isUnknownElement(vnode, creatingElmInVPre)) {139 warn(140 'Unknown custom element: <' + tag + '> - did you ' +141 'register the component correctly? For recursive components, ' +142 'make sure to provide the "name" option.',143 vnode.context144 )145 }146 }147 vnode.elm = vnode.ns148 ? nodeOps.createElementNS(vnode.ns, tag)149 : nodeOps.createElement(tag, vnode)150 setScope(vnode)151 /* istanbul ignore if */152 if (__WEEX__) {153 // in Weex, the default insertion order is parent-first.154 // List items can be optimized to use children-first insertion155 // with append="tree".156 const appendAsTree = isDef(data) && isTrue(data.appendAsTree)157 if (!appendAsTree) {158 if (isDef(data)) {159 invokeCreateHooks(vnode, insertedVnodeQueue)160 }161 insert(parentElm, vnode.elm, refElm)162 }163 createChildren(vnode, children, insertedVnodeQueue)164 if (appendAsTree) {165 if (isDef(data)) {166 invokeCreateHooks(vnode, insertedVnodeQueue)167 }168 insert(parentElm, vnode.elm, refElm)169 }170 } else {171 createChildren(vnode, children, insertedVnodeQueue)172 if (isDef(data)) {173 invokeCreateHooks(vnode, insertedVnodeQueue)174 }175 insert(parentElm, vnode.elm, refElm)176 }177 if (process.env.NODE_ENV !== 'production' && data && data.pre) {178 creatingElmInVPre--179 }180 } else if (isTrue(vnode.isComment)) {181 vnode.elm = nodeOps.createComment(vnode.text)182 insert(parentElm, vnode.elm, refElm)183 } else {184 vnode.elm = nodeOps.createTextNode(vnode.text)185 insert(parentElm, vnode.elm, refElm)186 }187 }188 function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {189 let i = vnode.data190 if (isDef(i)) {191 const isReactivated = isDef(vnode.componentInstance) && i.keepAlive192 if (isDef(i = i.hook) && isDef(i = i.init)) {193 i(vnode, false /* hydrating */)194 }195 // after calling the init hook, if the vnode is a child component196 // it should've created a child instance and mounted it. the child197 // component also has set the placeholder vnode's elm.198 // in that case we can just return the element and be done.199 if (isDef(vnode.componentInstance)) {200 initComponent(vnode, insertedVnodeQueue)201 insert(parentElm, vnode.elm, refElm)202 if (isTrue(isReactivated)) {203 reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm)204 }205 return true206 }207 }208 }209 function initComponent (vnode, insertedVnodeQueue) {210 if (isDef(vnode.data.pendingInsert)) {211 insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert)212 vnode.data.pendingInsert = null213 }214 vnode.elm = vnode.componentInstance.$el215 if (isPatchable(vnode)) {216 invokeCreateHooks(vnode, insertedVnodeQueue)217 setScope(vnode)218 } else {219 // empty component root.220 // skip all element-related modules except for ref (#3455)221 registerRef(vnode)222 // make sure to invoke the insert hook223 insertedVnodeQueue.push(vnode)224 }225 }226 function reactivateComponent (vnode, insertedVnodeQueue, parentElm, refElm) {227 let i228 // hack for #4339: a reactivated component with inner transition229 // does not trigger because the inner node's created hooks are not called230 // again. It's not ideal to involve module-specific logic in here but231 // there doesn't seem to be a better way to do it.232 let innerNode = vnode233 while (innerNode.componentInstance) {234 innerNode = innerNode.componentInstance._vnode235 if (isDef(i = innerNode.data) && isDef(i = i.transition)) {236 for (i = 0; i < cbs.activate.length; ++i) {237 cbs.activate[i](emptyNode, innerNode)238 }239 insertedVnodeQueue.push(innerNode)240 break241 }242 }243 // unlike a newly created component,244 // a reactivated keep-alive component doesn't insert itself245 insert(parentElm, vnode.elm, refElm)246 }247 function insert (parent, elm, ref) {248 if (isDef(parent)) {249 if (isDef(ref)) {250 if (nodeOps.parentNode(ref) === parent) {251 nodeOps.insertBefore(parent, elm, ref)252 }253 } else {254 nodeOps.appendChild(parent, elm)255 }256 }257 }258 function createChildren (vnode, children, insertedVnodeQueue) {259 if (Array.isArray(children)) {260 if (process.env.NODE_ENV !== 'production') {261 checkDuplicateKeys(children)262 }263 for (let i = 0; i < children.length; ++i) {264 createElm(children[i], insertedVnodeQueue, vnode.elm, null, true, children, i)265 }266 } else if (isPrimitive(vnode.text)) {267 nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)))268 }269 }270 function isPatchable (vnode) {271 while (vnode.componentInstance) {272 vnode = vnode.componentInstance._vnode273 }274 return isDef(vnode.tag)275 }276 function invokeCreateHooks (vnode, insertedVnodeQueue) {277 for (let i = 0; i < cbs.create.length; ++i) {278 cbs.create[i](emptyNode, vnode)279 }280 i = vnode.data.hook // Reuse variable281 if (isDef(i)) {282 if (isDef(i.create)) i.create(emptyNode, vnode)283 if (isDef(i.insert)) insertedVnodeQueue.push(vnode)284 }285 }286 // set scope id attribute for scoped CSS.287 // this is implemented as a special case to avoid the overhead288 // of going through the normal attribute patching process.289 function setScope (vnode) {290 let i291 if (isDef(i = vnode.fnScopeId)) {292 nodeOps.setStyleScope(vnode.elm, i)293 } else {294 let ancestor = vnode295 while (ancestor) {296 if (isDef(i = ancestor.context) && isDef(i = i.$options._scopeId)) {297 nodeOps.setStyleScope(vnode.elm, i)298 }299 ancestor = ancestor.parent300 }301 }302 // for slot content they should also get the scopeId from the host instance.303 if (isDef(i = activeInstance) &&304 i !== vnode.context &&305 i !== vnode.fnContext &&306 isDef(i = i.$options._scopeId)307 ) {308 nodeOps.setStyleScope(vnode.elm, i)309 }310 }311 function addVnodes (parentElm, refElm, vnodes, startIdx, endIdx, insertedVnodeQueue) {312 for (; startIdx <= endIdx; ++startIdx) {313 createElm(vnodes[startIdx], insertedVnodeQueue, parentElm, refElm, false, vnodes, startIdx)314 }315 }316 function invokeDestroyHook (vnode) {317 let i, j318 const data = vnode.data319 if (isDef(data)) {320 if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode)321 for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode)322 }323 if (isDef(i = vnode.children)) {324 for (j = 0; j < vnode.children.length; ++j) {325 invokeDestroyHook(vnode.children[j])326 }327 }328 }329 function removeVnodes (vnodes, startIdx, endIdx) {330 for (; startIdx <= endIdx; ++startIdx) {331 const ch = vnodes[startIdx]332 if (isDef(ch)) {333 if (isDef(ch.tag)) {334 removeAndInvokeRemoveHook(ch)335 invokeDestroyHook(ch)336 } else { // Text node337 removeNode(ch.elm)338 }339 }340 }341 }342 function removeAndInvokeRemoveHook (vnode, rm) {343 if (isDef(rm) || isDef(vnode.data)) {344 let i345 const listeners = cbs.remove.length + 1346 if (isDef(rm)) {347 // we have a recursively passed down rm callback348 // increase the listeners count349 rm.listeners += listeners350 } else {351 // directly removing352 rm = createRmCb(vnode.elm, listeners)353 }354 // recursively invoke hooks on child component root node355 if (isDef(i = vnode.componentInstance) && isDef(i = i._vnode) && isDef(i.data)) {356 removeAndInvokeRemoveHook(i, rm)357 }358 for (i = 0; i < cbs.remove.length; ++i) {359 cbs.remove[i](vnode, rm)360 }361 if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {362 i(vnode, rm)363 } else {364 rm()365 }366 } else {367 removeNode(vnode.elm)368 }369 }370 function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {371 let oldStartIdx = 0372 let newStartIdx = 0373 let oldEndIdx = oldCh.length - 1374 let oldStartVnode = oldCh[0]375 let oldEndVnode = oldCh[oldEndIdx]376 let newEndIdx = newCh.length - 1377 let newStartVnode = newCh[0]378 let newEndVnode = newCh[newEndIdx]379 let oldKeyToIdx, idxInOld, vnodeToMove, refElm380 // removeOnly is a special flag used only by <transition-group>381 // to ensure removed elements stay in correct relative positions382 // during leaving transitions383 const canMove = !removeOnly384 if (process.env.NODE_ENV !== 'production') {385 checkDuplicateKeys(newCh)386 }387 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {388 if (isUndef(oldStartVnode)) {389 oldStartVnode = oldCh[++oldStartIdx] // Vnode has been moved left390 } else if (isUndef(oldEndVnode)) {391 oldEndVnode = oldCh[--oldEndIdx]392 } else if (sameVnode(oldStartVnode, newStartVnode)) {393 patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)394 oldStartVnode = oldCh[++oldStartIdx]395 newStartVnode = newCh[++newStartIdx]396 } else if (sameVnode(oldEndVnode, newEndVnode)) {397 patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx)398 oldEndVnode = oldCh[--oldEndIdx]399 newEndVnode = newCh[--newEndIdx]400 } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right401 patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue, newCh, newEndIdx)402 canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm))403 oldStartVnode = oldCh[++oldStartIdx]404 newEndVnode = newCh[--newEndIdx]405 } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left406 patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)407 canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)408 oldEndVnode = oldCh[--oldEndIdx]409 newStartVnode = newCh[++newStartIdx]410 } else {411 if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)412 idxInOld = isDef(newStartVnode.key)413 ? oldKeyToIdx[newStartVnode.key]414 : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)415 if (isUndef(idxInOld)) { // New element416 createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)417 } else {418 vnodeToMove = oldCh[idxInOld]419 if (sameVnode(vnodeToMove, newStartVnode)) {420 patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)421 oldCh[idxInOld] = undefined422 canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)423 } else {424 // same key but different element. treat as new element425 createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)426 }427 }428 newStartVnode = newCh[++newStartIdx]429 }430 }431 if (oldStartIdx > oldEndIdx) {432 refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm433 addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue)434 } else if (newStartIdx > newEndIdx) {435 removeVnodes(oldCh, oldStartIdx, oldEndIdx)436 }437 }438 function checkDuplicateKeys (children) {439 const seenKeys = {}440 for (let i = 0; i < children.length; i++) {441 const vnode = children[i]442 const key = vnode.key443 if (isDef(key)) {444 if (seenKeys[key]) {445 warn(446 `Duplicate keys detected: '${key}'. This may cause an update error.`,447 vnode.context448 )449 } else {450 seenKeys[key] = true451 }452 }453 }454 }455 function findIdxInOld (node, oldCh, start, end) {456 for (let i = start; i < end; i++) {457 const c = oldCh[i]458 if (isDef(c) && sameVnode(node, c)) return i459 }460 }461 function patchVnode (462 oldVnode,463 vnode,464 insertedVnodeQueue,465 ownerArray,466 index,467 removeOnly468 ) {469 if (oldVnode === vnode) {470 return471 }472 if (isDef(vnode.elm) && isDef(ownerArray)) {473 // clone reused vnode474 vnode = ownerArray[index] = cloneVNode(vnode)475 }476 const elm = vnode.elm = oldVnode.elm477 if (isTrue(oldVnode.isAsyncPlaceholder)) {478 if (isDef(vnode.asyncFactory.resolved)) {479 hydrate(oldVnode.elm, vnode, insertedVnodeQueue)480 } else {481 vnode.isAsyncPlaceholder = true482 }483 return484 }485 // reuse element for static trees.486 // note we only do this if the vnode is cloned -487 // if the new node is not cloned it means the render functions have been488 // reset by the hot-reload-api and we need to do a proper re-render.489 if (isTrue(vnode.isStatic) &&490 isTrue(oldVnode.isStatic) &&491 vnode.key === oldVnode.key &&492 (isTrue(vnode.isCloned) || isTrue(vnode.isOnce))493 ) {494 vnode.componentInstance = oldVnode.componentInstance495 return496 }497 let i498 const data = vnode.data499 if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {500 i(oldVnode, vnode)501 }502 const oldCh = oldVnode.children503 const ch = vnode.children504 if (isDef(data) && isPatchable(vnode)) {505 for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode)506 if (isDef(i = data.hook) && isDef(i = i.update)) i(oldVnode, vnode)507 }508 if (isUndef(vnode.text)) {509 if (isDef(oldCh) && isDef(ch)) {510 if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly)511 } else if (isDef(ch)) {512 if (process.env.NODE_ENV !== 'production') {513 checkDuplicateKeys(ch)514 }515 if (isDef(oldVnode.text)) nodeOps.setTextContent(elm, '')516 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue)517 } else if (isDef(oldCh)) {518 removeVnodes(oldCh, 0, oldCh.length - 1)519 } else if (isDef(oldVnode.text)) {520 nodeOps.setTextContent(elm, '')521 }522 } else if (oldVnode.text !== vnode.text) {523 nodeOps.setTextContent(elm, vnode.text)524 }525 if (isDef(data)) {526 if (isDef(i = data.hook) && isDef(i = i.postpatch)) i(oldVnode, vnode)527 }528 }529 function invokeInsertHook (vnode, queue, initial) {530 // delay insert hooks for component root nodes, invoke them after the531 // element is really inserted532 if (isTrue(initial) && isDef(vnode.parent)) {533 vnode.parent.data.pendingInsert = queue534 } else {535 for (let i = 0; i < queue.length; ++i) {536 queue[i].data.hook.insert(queue[i])537 }538 }539 }540 let hydrationBailed = false541 // list of modules that can skip create hook during hydration because they542 // are already rendered on the client or has no need for initialization543 // Note: style is excluded because it relies on initial clone for future544 // deep updates (#7063).545 const isRenderedModule = makeMap('attrs,class,staticClass,staticStyle,key')546 // Note: this is a browser-only function so we can assume elms are DOM nodes.547 function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {548 let i549 const { tag, data, children } = vnode550 inVPre = inVPre || (data && data.pre)551 vnode.elm = elm552 if (isTrue(vnode.isComment) && isDef(vnode.asyncFactory)) {553 vnode.isAsyncPlaceholder = true554 return true555 }556 // assert node match557 if (process.env.NODE_ENV !== 'production') {558 if (!assertNodeMatch(elm, vnode, inVPre)) {559 return false560 }561 }562 if (isDef(data)) {563 if (isDef(i = data.hook) && isDef(i = i.init)) i(vnode, true /* hydrating */)564 if (isDef(i = vnode.componentInstance)) {565 // child component. it should have hydrated its own tree.566 initComponent(vnode, insertedVnodeQueue)567 return true568 }569 }570 if (isDef(tag)) {571 if (isDef(children)) {572 // empty element, allow client to pick up and populate children573 if (!elm.hasChildNodes()) {574 createChildren(vnode, children, insertedVnodeQueue)575 } else {576 // v-html and domProps: innerHTML577 if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {578 if (i !== elm.innerHTML) {579 /* istanbul ignore if */580 if (process.env.NODE_ENV !== 'production' &&581 typeof console !== 'undefined' &&582 !hydrationBailed583 ) {584 hydrationBailed = true585 console.warn('Parent: ', elm)586 console.warn('server innerHTML: ', i)587 console.warn('client innerHTML: ', elm.innerHTML)588 }589 return false590 }591 } else {592 // iterate and compare children lists593 let childrenMatch = true594 let childNode = elm.firstChild595 for (let i = 0; i < children.length; i++) {596 if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue, inVPre)) {597 childrenMatch = false598 break599 }600 childNode = childNode.nextSibling601 }602 // if childNode is not null, it means the actual childNodes list is603 // longer than the virtual children list.604 if (!childrenMatch || childNode) {605 /* istanbul ignore if */606 if (process.env.NODE_ENV !== 'production' &&607 typeof console !== 'undefined' &&608 !hydrationBailed609 ) {610 hydrationBailed = true611 console.warn('Parent: ', elm)612 console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children)613 }614 return false615 }616 }617 }618 }619 if (isDef(data)) {620 let fullInvoke = false621 for (const key in data) {622 if (!isRenderedModule(key)) {623 fullInvoke = true624 invokeCreateHooks(vnode, insertedVnodeQueue)625 break626 }627 }628 if (!fullInvoke && data['class']) {629 // ensure collecting deps for deep class bindings for future updates630 traverse(data['class'])631 }632 }633 } else if (elm.data !== vnode.text) {634 elm.data = vnode.text635 }636 return true637 }638 function assertNodeMatch (node, vnode, inVPre) {639 if (isDef(vnode.tag)) {640 return vnode.tag.indexOf('vue-component') === 0 || (641 !isUnknownElement(vnode, inVPre) &&642 vnode.tag.toLowerCase() === (node.tagName && node.tagName.toLowerCase())643 )644 } else {645 return node.nodeType === (vnode.isComment ? 8 : 3)646 }647 }648 return function patch (oldVnode, vnode, hydrating, removeOnly) {649 if (isUndef(vnode)) {650 if (isDef(oldVnode)) invokeDestroyHook(oldVnode)651 return652 }653 let isInitialPatch = false654 const insertedVnodeQueue = []655 if (isUndef(oldVnode)) {656 // empty mount (likely as component), create new root element657 isInitialPatch = true658 createElm(vnode, insertedVnodeQueue)659 } else {660 const isRealElement = isDef(oldVnode.nodeType)661 if (!isRealElement && sameVnode(oldVnode, vnode)) {662 // patch existing root node663 patchVnode(oldVnode, vnode, insertedVnodeQueue, null, null, removeOnly)664 } else {665 if (isRealElement) {666 // mounting to a real element667 // check if this is server-rendered content and if we can perform668 // a successful hydration.669 if (oldVnode.nodeType === 1 && oldVnode.hasAttribute(SSR_ATTR)) {670 oldVnode.removeAttribute(SSR_ATTR)671 hydrating = true672 }673 if (isTrue(hydrating)) {674 if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {675 invokeInsertHook(vnode, insertedVnodeQueue, true)676 return oldVnode677 } else if (process.env.NODE_ENV !== 'production') {678 warn(679 'The client-side rendered virtual DOM tree is not matching ' +680 'server-rendered content. This is likely caused by incorrect ' +681 'HTML markup, for example nesting block-level elements inside ' +682 '<p>, or missing <tbody>. Bailing hydration and performing ' +683 'full client-side render.'684 )685 }686 }687 // either not server-rendered, or hydration failed.688 // create an empty node and replace it689 oldVnode = emptyNodeAt(oldVnode)690 }691 // replacing existing element692 const oldElm = oldVnode.elm693 const parentElm = nodeOps.parentNode(oldElm)694 // create new node695 createElm(696 vnode,697 insertedVnodeQueue,698 // extremely rare edge case: do not insert if old element is in a699 // leaving transition. Only happens when combining transition +700 // keep-alive + HOCs. (#4590)701 oldElm._leaveCb ? null : parentElm,702 nodeOps.nextSibling(oldElm)703 )704 // update parent placeholder node element, recursively705 if (isDef(vnode.parent)) {706 let ancestor = vnode.parent707 const patchable = isPatchable(vnode)708 while (ancestor) {709 for (let i = 0; i < cbs.destroy.length; ++i) {710 cbs.destroy[i](ancestor)711 }712 ancestor.elm = vnode.elm713 if (patchable) {714 for (let i = 0; i < cbs.create.length; ++i) {715 cbs.create[i](emptyNode, ancestor)716 }717 // #6513718 // invoke insert hooks that may have been merged by create hooks.719 // e.g. for directives that uses the "inserted" hook.720 const insert = ancestor.data.hook.insert721 if (insert.merged) {722 // start at index 1 to avoid re-invoking component mounted hook723 for (let i = 1; i < insert.fns.length; i++) {724 insert.fns[i]()725 }726 }727 } else {728 registerRef(ancestor)729 }730 ancestor = ancestor.parent731 }732 }733 // destroy old node734 if (isDef(parentElm)) {735 removeVnodes([oldVnode], 0, 0)736 } else if (isDef(oldVnode.tag)) {737 invokeDestroyHook(oldVnode)738 }739 }740 }741 invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch)742 return vnode.elm743 }...
snabbdom.js
Source:snabbdom.js
...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)) {...
Using AI Code Generation
1import { withKnobs } from '@storybook/addon-knobs';2import { withA11y } from '@storybook/addon-a11y';3import { withTests } from '@storybook/addon-jest';4import results from '../.jest-test-results.json';5 withTests({6 }),7];8import { addDecorator } from '@storybook/html';9import { withKnobs } from '@storybook/addon-knobs';10import { withA11y } from '@storybook/addon-a11y';11import { withTests } from '@storybook/addon-jest';12import results from '../.jest-test-results.json';13addDecorator(withKnobs);14addDecorator(withA11y);15addDecorator(16 withTests({17 })18);19import { addDecorator } from '@storybook/html';20import { withTests } from '@storybook/addon-jest';21import results from '../.jest-test-results.json';22addDecorator(23 withTests({24 })25);26import { addDecorator } from '@storybook/html';27import { withTests } from '@storybook/addon-jest';28import results from '../.jest-test-results.json';29addDecorator(30 withTests({31 })32);33import { addDecorator } from '@storybook/html';34import { withTests } from '@storybook/addon-jest';35import { createResults } from '@storybook/addon-jest';36const jestResults = createResults(results);37addDecorator(38 withTests({39 })40);
Using AI Code Generation
1import { withKnobs } from "@storybook/addon-knobs";2import { withVNode } from "storybook-addon-vue-info";3import { addDecorator, addParameters } from "@storybook/vue";4addDecorator(withKnobs);5addDecorator(withVNode);6addParameters({ options: { showRoots: true } });7import { storiesOf } from "@storybook/vue";8import MyComponent from "./MyComponent.vue";9storiesOf("MyComponent", module).add(10 () => ({11 components: { MyComponent },12 }),13 {14 info: {15 components: { MyComponent }16 }17 }18);19import { withKnobs } from "@storybook/addon-knobs";20import { withInfo } from "@storybook/addon-info";21import { withVNode } from "storybook-addon-vue-info";22import { addDecorator, addParameters } from "@storybook/vue";23addDecorator(withKnobs);24addDecorator(withVNode);25addDecorator(withInfo);26addParameters({ options: { showRoots: true } });27import { storiesOf } from "@storybook/vue";28import MyComponent from "./MyComponent.vue";29storiesOf("MyComponent", module).add(30 () => ({31 components: { MyComponent },32 }),33 {34 info: {35 components: { MyComponent }36 }37 }38);
Using AI Code Generation
1import { storiesOf } from '@storybook/vue'2import { withInfo } from 'storybook-addon-vue-info'3import { withKnobs, text, boolean, number } from '@storybook/addon-knobs'4import { action } from '@storybook/addon-actions'5import MyComponent from '../components/MyComponent.vue'6storiesOf('MyComponent', module)7 .addDecorator(withInfo)8 .addDecorator(withKnobs)9 .add('with text', () => ({10 components: { MyComponent },11 props: {12 msg: {13 default: text('Message', 'Hello Storybook')14 }15 }16 }))17 .add('with some emoji', () => ({18 components: { MyComponent },19 props: {20 msg: {21 default: text('Message', '๐ ๐ ๐ ๐ฏ')22 }23 }24 }))25 .add('with some button action', () => ({26 components: { MyComponent },27 methods: { action: action('clicked') },28 props: {29 msg: {30 default: text('Message', 'Hello Storybook')31 }32 }33 }))34 .add('with some button action', () => ({35 components: { MyComponent },36 methods: { action: action('clicked') },37 props: {38 msg: {39 default: text('Message', 'Hello Storybook')40 }41 }42 }))43 .add('with some button action', () => ({44 components: { MyComponent },45 methods: { action: action('clicked') },46 props: {47 msg: {48 default: text('Message', 'Hello Storybook')49 }50 }51 }))52 .add('with some button action', () => ({53 components: { MyComponent },54 methods: { action: action('clicked') },55 props: {56 msg: {57 default: text('Message', 'Hello Storybook')58 }
Using AI Code Generation
1import { storiesOf } from '@storybook/vue';2import { action } from '@storybook/addon-actions';3import { withKnobs, text, number, select, boolean } from '@storybook/addon-knobs';4import { withInfo } from 'storybook-addon-vue-info';5import { withNotes } from '@storybook/addon-notes';6import MyComponent from './MyComponent.vue';7storiesOf('MyComponent', module)8 .addDecorator(withKnobs)9 .addDecorator(withInfo)10 .addDecorator(withNotes)11 .add('with text', () => ({12 components: { MyComponent },13 props: {14 msg: {15 default: text('Message', 'Hello Storybook')16 }17 }18 }))19 .add('with some emoji', () => ({20 components: { MyComponent },21 props: {22 msg: {23 default: text('Message', '๐ ๐ ๐ ๐ฏ')24 }25 }26 }))27 .add('with some number', () => ({28 components: { MyComponent },29 props: {30 msg: {31 default: text('Message', 123)32 }33 }34 }))35 .add('with some number', () => ({36 components: { MyComponent },37 props: {38 msg: {39 default: number('Message', 123)40 }41 }42 }))43 .add('with some boolean', () => ({44 components: { MyComponent },45 props: {46 msg: {47 default: boolean('Message', true)48 }49 }50 }))51 .add('with some options', () => ({52 components: { MyComponent },53 props: {54 msg: {55 default: select('Message', { 'Hello': 'Hello Storybook', 'Bye': 'Bye Storybook' }, 'Hello Storybook')56 }57 }58 }))59 .add('with some actions', () => ({60 components: { MyComponent },
Using AI Code Generation
1import { render } from 'react-dom';2import { storiesOf } from '@storybook/react';3import { action } from '@storybook/addon-actions';4import { withKnobs, text, boolean, number, array } from '@storybook/addon-knobs';5import { withInfo } from '@storybook/addon-info';6import { withNotes } from '@storybook/addon-notes';7import { withViewport } from '@storybook/addon-viewport';8import { linkTo } from '@storybook/addon-links';9import { withBackgrounds } from '@storybook/addon-backgrounds';10import { withOptions } from '@storybook/addon-options';11import { withA11y } from '@storybook/addon-a11y';12import { withConsole } from '@storybook/addon-console';13import { withTests } from '@storybook/addon-jest';14import { withState } from '@dump247/storybook-state';15import { setOptions } from '@storybook/addon-options';16import { checkA11y } from '@storybook/addon-a11y';17import { jsxDecorator } from 'storybook-addon-jsx';18import { withDocs } from 'storybook-readme';19import { withReadme } from 'storybook-readme/with-readme';20import { withPropsTable } from 'storybook-addon-react-docgen';21import { withInfoAddon } from '@storybook/addon-info';22import { withStorySource } from '@storybook/addon-storysource';23import { withPropsCombinations } from 'react-storybook-addon-props-combinations';24import { withCode } from 'storybook-addon-code';25import { withLinks } from '@storybook/addon-links';26import { withStoryshots } from '@storybook/addon-storyshots';27import { withRedux } from 'addon-redux';28import { withStorybookInfo } from '@storybook/addon-storybook-info';29import { withStorybookInfoAddon } from '@storybook/addon-storybook-info-addon';30import { withReactLiveEdit } from 'storybook-addon-react-live-edit';31import { withI18n } from 'storybook-addon-i18n';32import { withCsf } from '@storybook/csf';33import { withCsfV2 } from '@storybook/csf-v2';34import { withCssResources } from '@storybook/addon-cssresources';35import { withHtml } from '@whitespace/storybook-addon-html/react';36import { withContexts } from '@storybook/addon-contexts/react';37import { withContextsV2 }
Using AI Code Generation
1import { vnode } from 'storybook-root';2import storybookRoot from 'storybook-root';3import storybookRoot from 'storybook-root';4import storybookRoot from 'storybook-root';5import storybookRoot from 'storybook-root';6import storybookRoot from 'storybook-root';7import storybookRoot from 'storybook-root';8import storybookRoot from 'storybook-root';9import storybookRoot from 'storybook-root';10import storybookRoot from 'storybook-root';11import { vnode } from 'storybook-root';12import storybookRoot from 'storybook-root';13import storybookRoot from 'storybook-root';14import storybookRoot from 'storybook-root';15import storybookRoot from 'storybook-root';16import storybookRoot from 'storybook-root';17import storybookRoot from 'storybook-root';18 {{ item.children[0] }}19 {{ item.children[0] }}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!