Best JavaScript code snippet using playwright-internal
snabbdom.js
Source: snabbdom.js
...10 return s !== undefined;11 }12 var emptyNode = VNode('', {}, [], undefined, undefined);13 //è¿ä¸ªå½æ°ä¸»è¦ç¨äºæ¯è¾oldvnodeä¸vnodeåå±æ¬¡èç¹çæ¯è¾ï¼å¦æåå±æ¬¡èç¹çkeyåselé½ç¸åï¼æ们就å¯ä»¥ä¿çè¿ä¸ªèç¹ï¼ å¦åç´æ¥æ¿æ¢èç¹14 function sameVnode(vnode1, vnode2) {15 return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel;16 }17 //å°oldvnodeæ°ç»ä¸ä½ç½®å¯¹oldvnode.keyçæ å°è½¬æ¢ä¸ºoldvnode.key对ä½ç½®çæ å°18 //ä¾å¦:19 /*20 [{key:'a'},{key:'b'},{key:'c'}] ==> {'a':0, 'b':1, 'c':2}21 */22 function createKeyToOldIdx(children, beginIdx, endIdx) {23 var i, map = {},24 key;25 for (i = beginIdx; i <= endIdx; ++i) {26 key = children[i].key;27 if (isDef(key)) map[key] = i;28 }29 return map;30 }31 var hooks = ['create', 'update', 'remove', 'destroy', 'pre', 'post']; //å
¨å±é©åï¼modulesèªå¸¦çé©åå½æ°32 function init(modules, api) {33 var i, j, cbs = {};34 //è·å对äºçå®domæä½çapi35 if (isUndef(api)) api = domApi;36 //注åé©åçåè°ï¼å¨åçç¶æåæ´æ¶ï¼è§¦å对åºå±æ§åæ´37 /*38 ä¾å¦:cbs={39 create:[ClassModule.create,EventlistenerModule.create...],40 update:[ClassModule.update,EventlistenerModule.update...]41 ...42 }43 */44 for (i = 0; i < hooks.length; ++i) {45 cbs[hooks[i]] = [];46 for (j = 0; j < modules.length; ++j) {47 if (modules[j][hooks[i]] !== undefined) cbs[hooks[i]].push(modules[j][hooks[i]]);48 }49 }50 /*51 è¿ä¸ªå½æ°ä¸»è¦çåè½æ¯å°ä¸ä¸ªçå®çæ åèç¹çDOMèç¹è½¬åævnodeå½¢å¼ï¼52 å¦<div id='a' class='b c'></div>å°è½¬æ¢ä¸º{sel:'div#a.b.c',data:{},children:[],text:undefined,elm:<div id='a' class='b c'>}53 */54 function emptyNodeAt(elm) {55 var id = elm.id ? '#' + elm.id : '';56 var c = elm.className ? '.' + elm.className.split(' ').join('.') : '';57 return VNode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm);58 }59 /*60 removeä¸ä¸ªvnodeæ¶ï¼ä¼è§¦åremoveé©åä½æ¦æªå¨ï¼åªæå¨ææremoveé©å61 åè°å½æ°é½è§¦åå®æä¼å°èç¹ä»ç¶èç¹å é¤ï¼èè¿ä¸ªå½æ°æä¾çå°±æ¯å¯¹removeé©ååè°æä½ç计æ°åè½62 */63 function createRmCb(childElm, listeners) {64 return function() {65 if (--listeners === 0) {66 var parent = api.parentNode(childElm);67 api.removeChild(parent, childElm);68 }69 };70 }71 //å°vnodeå建为çå®dom72 function createElm(vnode, insertedVnodeQueue) {73 var i, data = vnode.data;74 if (data !== undefined) {75 if (isDef(i = data.hook) && isDef(i = i.init)) {76 i(vnode);77 data = vnode.data;78 }79 }80 var elm, children = vnode.children,81 sel = vnode.sel;82 if (isDef(sel)) {83 //解æselåæ°ï¼ä¾å¦div#divId.divClass ==>id="divId" class="divClass"84 var hashIdx = sel.indexOf('#');85 //å
idåclass86 var dotIdx = sel.indexOf('.', hashIdx);87 var hash = hashIdx > 0 ? hashIdx : sel.length;88 var dot = dotIdx > 0 ? dotIdx : sel.length;89 var tag = hashIdx !== -1 || dotIdx !== -1 ? sel.slice(0, Math.min(hash, dot)) : sel;90 //å建ä¸ä¸ªDOMèç¹å¼ç¨ï¼å¹¶å¯¹å
¶å±æ§å®ä¾å91 elm = vnode.elm = isDef(data) && isDef(i = data.ns) ? api.createElementNS(i, tag) : api.createElement(tag);92 //è·åidå #a --> a93 if (hash < dot) elm.id = sel.slice(hash + 1, dot);94 //è·åç±»åï¼å¹¶æ ¼å¼å .a.b --> a b95 if (dotIdx > 0) elm.className = sel.slice(dot + 1).replace(/\./g, ' ');96 //å¦æåå¨åå
ç´ Vnodeèç¹ï¼åéå½å°åå
ç´ èç¹æå
¥å°å½åVnodeèç¹ä¸ï¼å¹¶å°å·²æå
¥çåå
ç´ èç¹å¨insertedVnodeQueueä¸ä½è®°å½97 if (is.array(children)) {98 for (i = 0; i < children.length; ++i) {99 api.appendChild(elm, createElm(children[i], insertedVnodeQueue));100 }101 } else if (is.primitive(vnode.text)) { //å¦æåå¨åææ¬èç¹ï¼åç´æ¥å°å
¶æå
¥å°å½åVnodeèç¹102 api.appendChild(elm, api.createTextNode(vnode.text));103 }104 //å½å建å®æ¯åï¼è§¦åå
¨å±createé©ååè°105 for (i = 0; i < cbs.create.length; ++i) {106 cbs.create[i](emptyNode, vnode);107 }108 i = vnode.data.hook; // Reuse variable109 if (isDef(i)) { //触åèªèº«çcreateé©ååè°110 if (i.create) i.create(emptyNode, vnode);111 //å¦ææinserté©åï¼åæ¨è¿insertedVnodeQueueä¸ä½è®°å½ï¼ä»èå®ç°æ¹éæå
¥è§¦åinsertåè°112 if (i.insert) insertedVnodeQueue.push(vnode);113 }114 }115 //å¦æ没声æéæ©å¨ï¼å说æè¿ä¸ªæ¯ä¸ä¸ªtextèç¹116 else {117 elm = vnode.elm = api.createTextNode(vnode.text);118 }119 return vnode.elm;120 }121 //å°vnode转æ¢åçdomèç¹æå
¥å°domæ çæå®ä½ç½®ä¸å»122 function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {123 for (; startIdx <= endIdx; ++startIdx) {124 api.insertBefore(parentElm, createElm(vnodes[startIdx], insertedVnodeQueue), before);125 }126 }127 /*128 è¿ä¸ªå½æ°ç¨äºæå¨è§¦ådestoryé©ååè°ï¼ä¸»è¦æ¥éª¤å¦ä¸ï¼129 å
è°ç¨vnodeä¸çdestory130 åè°ç¨å
¨å±ä¸çdestory131 éå½è°ç¨åvnodeçdestory132 */133 function invokeDestroyHook(vnode) {134 var i, j, data = vnode.data;135 if (isDef(data)) {136 if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode); //è°ç¨èªèº«çdestroyé©å137 for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode); //è°ç¨å
¨å±destroyé©å138 if (isDef(i = vnode.children)) {139 for (j = 0; j < vnode.children.length; ++j) {140 invokeDestroyHook(vnode.children[j]);141 }142 }143 }144 }145 /*146 è¿ä¸ªå½æ°ä¸»è¦åè½æ¯æ¹éå é¤DOMèç¹ï¼éè¦é
åinvokeDestoryHookåcreateRmCb147 主è¦æ¥éª¤å¦ä¸ï¼148 è°ç¨invokeDestoryHook以触ådestoryåè°149 è°ç¨createRmCbæ¥å¼å§å¯¹removeåè°è¿è¡è®¡æ°150 å é¤DOMèç¹151 *152 *153 * @param parentElm ç¶èç¹154 * @param vnodes å é¤èç¹æ°ç»155 * @param startIdx å é¤èµ·å§åæ 156 * @param endIdx å é¤ç»æåæ 157 */158 function removeVnodes(parentElm, vnodes, startIdx, endIdx) {159 for (; startIdx <= endIdx; ++startIdx) {160 var i, listeners, rm, ch = vnodes[startIdx]; //ch代表åèç¹161 if (isDef(ch)) {162 if (isDef(ch.sel)) {163 //è°ç¨destroyé©å164 invokeDestroyHook(ch);165 //对å
¨å±removeé©åè¿è¡è®¡æ°166 listeners = cbs.remove.length + 1;167 rm = createRmCb(ch.elm, listeners);168 //è°ç¨å
¨å±removeåè°å½æ°ï¼å¹¶æ¯æ¬¡åå°ä¸ä¸ªremoveé©å计æ°169 for (i = 0; i < cbs.remove.length; ++i) {170 cbs.remove[i](ch, rm);171 }172 //è°ç¨å
é¨vnode.data.hookä¸çremoveé©åï¼åªæä¸ä¸ªï¼173 if (isDef(i = ch.data) && isDef(i = i.hook) && isDef(i = i.remove)) {174 i(ch, rm);175 } else {176 //å¦æ没æå
é¨removeé©åï¼éè¦è°ç¨rmï¼ç¡®ä¿è½å¤removeèç¹177 rm();178 }179 } else { // Text node180 api.removeChild(parentElm, ch.elm);181 }182 }183 }184 }185 //http://qiutianaimeili.com/html/page/2018/05/4si69yn4stl.html186 //æ¯è¾new vnodeåold vnodeçåèç¹187 function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) {188 /*189 (oldStartVnode) (oldEndVnode)190 oStartIdx-> <-oEndIdx191 old [x x x x x] 192 193 (newStartVnode) (newEndVnode)194 nStartIdx-> <-nEndIdx195 new [x x x x x] 196 ç¹æ®æ¯è¾è§åï¼197 1.sameVnode(oldStartVnode, newStartVnode) 198 sameVnodeæ¯æ¯è¾vnodeçselåkeyå¼ï¼å¦æä¸è®¾ç½®keyå¼ï¼åkeyå¼é½ä¸ºundefinedï¼ä¸ºç¸çï¼å¿
é¡»è¦ä¸¤è
é½ç¸åæè¿åtrue199 ****************************************200 (oldStartVnode) 201 oStartIdx-> 202 old [x x x x x] 203 204 (newStartVnode) 205 nStartIdx-> 206 new [x x x x x] 207 è¥ç¸ä¼¼åä¸ç¨å°æ´ä¸ªold vnodeå é¤ï¼æ¯è¾new vnodeåold vnodeå·®å¼ï¼è¿è¡patchï¼oStartIdx++ nStartIdx++208 ****************************************209 2.sameVnode(oldEndVnode, newEndVnode)210 (oldEndVnode)211 <-oEndIdx212 old [x x x x x] 213 214 (newEndVnode)215 <-nEndIdx216 new [x x x x x] 217 è¥ç¸ä¼¼åä¸ç¨å°æ´ä¸ªold vnodeå é¤ï¼æ¯è¾new vnodeåold vnodeå·®å¼ï¼è¿è¡patchï¼oEndIdx++ nEndIdx++218 ****************************************219 3.sameVnode(oldStartVnode, newEndVnode)220 (oldStartVnode) 221 oStartIdx-> 222 old [x x x x x] 223 224 (newEndVnode)225 <-nEndIdx226 new [x x x x x] 227 228 è¥ç¸ä¼¼åä¸ç¨å°æ´ä¸ªold vnodeå é¤ï¼æ¯è¾new vnodeåold vnodeå·®å¼ï¼è¿è¡patchï¼oStartIdx++ nEndIdx++229 ****************************************230 4.sameVnode(oldEndVnode, newStartVnode)231 (oldEndVnode)232 <-oEndIdx233 old [x x x x x] 234 235 (newStartVnode) 236 nStartIdx-> 237 new [x x x x x] 238 è¥ç¸ä¼¼åä¸ç¨å°æ´ä¸ªold vnodeå é¤ï¼æ¯è¾new vnodeåold vnodeå·®å¼ï¼è¿è¡patchï¼oEndIdx++ nStartIdx++239 */240 var oldStartIdx = 0,241 newStartIdx = 0;242 var oldEndIdx = oldCh.length - 1;243 var oldStartVnode = oldCh[0];244 var oldEndVnode = oldCh[oldEndIdx];245 var newEndIdx = newCh.length - 1;246 var newStartVnode = newCh[0];247 var newEndVnode = newCh[newEndIdx];248 var oldKeyToIdx, idxInOld, elmToMove, before;249 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {250 if (isUndef(oldStartVnode)) {251 oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left252 } else if (isUndef(oldEndVnode)) {253 oldEndVnode = oldCh[--oldEndIdx];254 } else if (sameVnode(oldStartVnode, newStartVnode)) {255 patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);256 oldStartVnode = oldCh[++oldStartIdx];257 newStartVnode = newCh[++newStartIdx];258 } else if (sameVnode(oldEndVnode, newEndVnode)) {259 patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);260 oldEndVnode = oldCh[--oldEndIdx];261 newEndVnode = newCh[--newEndIdx];262 } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right263 patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);264 api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm));265 oldStartVnode = oldCh[++oldStartIdx];266 newEndVnode = newCh[--newEndIdx];267 } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left268 patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);269 api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);270 oldEndVnode = oldCh[--oldEndIdx];271 newStartVnode = newCh[++newStartIdx];272 } else {273 if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);274 idxInOld = oldKeyToIdx[newStartVnode.key]; //éåoldVnode,æ¥çnewVnodeæ¯å¦åå¨äºoldVnode275 if (isUndef(idxInOld)) { // å¦æä¸åå¨ï¼å为æ°èç¹ï¼è¿è¡æ·»å 276 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);277 newStartVnode = newCh[++newStartIdx];278 } else {279 //è¥åå¨ï¼éè¦æ¥çselå±æ§æ¯å¦ä¸è´ï¼å¦æä¸ä¸è´åæ°å¢ï¼è¥åå¨ï¼åå¨æ§Vnodeä¸è¿è¡patch280 elmToMove = oldCh[idxInOld];281 if (elmToMove.sel !== newStartVnode.sel) {282 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);283 } else {284 patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);285 oldCh[idxInOld] = undefined;286 api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);287 }288 newStartVnode = newCh[++newStartIdx];289 }290 }291 }292 //éåç»æåï¼æ¥çæ°æ§Vnodeæ°ç»çéåæ
åµï¼æ¯å¦éåå®293 if (oldStartIdx > oldEndIdx) { //è¥æ§Vnodeæ°ç»éåå®,åå°å©ä½çæ°Vnodeæ°ç»ä¸çVnodeè¿è¡æ·»å 294 before = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm;295 addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);296 } else if (newStartIdx > newEndIdx) { //è¥æ°Vnodeæ°ç»éåå®ï¼åå é¤å©ä½çæ§Vnodeæ°ç»ä¸çVnode297 removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);298 }299 }300 function patchVnode(oldVnode, vnode, insertedVnodeQueue) {301 var i, hook;302 //å¨patchä¹åï¼å
è°ç¨vnode.dataçprePatché©å303 if (isDef(i = vnode.data) && isDef(hook = i.hook) && isDef(i = hook.prepatch)) {304 i(oldVnode, vnode);305 }306 var elm = vnode.elm = oldVnode.elm,307 oldCh = oldVnode.children,308 ch = vnode.children;309 //å¦væoldnodeåvnodeçå¼ç¨ç¸åï¼è¯´æ没åçä»»ä½ååç´æ¥è¿åï¼é¿å
æ§è½æµªè´¹310 if (oldVnode === vnode) return;311 //å¦æoldvnodeåvnodeä¸åï¼è¯´ævnodeææ´æ°312 //å¦ævnodeåoldvnodeä¸ç¸ä¼¼åç´æ¥ç¨vnodeå¼ç¨çDOMèç¹å»æ¿ä»£oldvnodeå¼ç¨çæ§èç¹313 if (!sameVnode(oldVnode, vnode)) {314 var parentElm = api.parentNode(oldVnode.elm);315 elm = createElm(vnode, insertedVnodeQueue);316 api.insertBefore(parentElm, elm, oldVnode.elm);317 removeVnodes(parentElm, [oldVnode], 0, 0);318 return;319 }320 //å¦ævnodeåoldvnodeç¸ä¼¼ï¼é£ä¹æ们è¦å¯¹oldvnodeæ¬èº«è¿è¡æ´æ°321 if (isDef(vnode.data)) {322 //é¦å
è°ç¨å
¨å±çupdateé©åï¼å¯¹vnode.elmæ¬èº«å±æ§è¿è¡æ´æ°323 for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode);324 //ç¶åè°ç¨vnode.dataéé¢çupdateé©å,å次对vnode.elmæ´æ°325 i = vnode.data.hook;326 if (isDef(i) && isDef(i = i.update)) i(oldVnode, vnode);327 }328 /*329 åæ
åµè®¨è®ºèç¹çæ´æ°ï¼ new代表æ°Vnode old代表æ§Vnode330 ps:å¦æèªèº«åå¨ææ¬èç¹ï¼åä¸åå¨åèç¹ å³:ætextåä¸ä¼åå¨ch331 1 newä¸ä¸ºææ¬èç¹332 1.1 newä¸ä¸ºææ¬èç¹,newè¿åå¨åèç¹ 333 1.1.1 newä¸ä¸ºææ¬èç¹,newè¿åå¨åèç¹,oldæåèç¹334 1.1.2 newä¸ä¸ºææ¬èç¹,newè¿åå¨åèç¹,old没æåèç¹335 1.1.2.1 newä¸ä¸ºææ¬èç¹,newè¿åå¨åèç¹,old没æåèç¹,old为ææ¬èç¹336 1.2 newä¸ä¸ºææ¬èç¹,newä¸åå¨åèç¹337 1.2.1 newä¸ä¸ºææ¬èç¹,newä¸åå¨åèç¹,oldåå¨åèç¹338 1.2.2 newä¸ä¸ºææ¬èç¹,newä¸åå¨åèç¹,old为ææ¬èç¹339 2.new为ææ¬èç¹340 2.1 new为ææ¬èç¹,并ä¸oldä¸newçææ¬èç¹ä¸ç¸ç341 psï¼è¿éåªéè¦è®¨è®ºè¿ä¸ç§æ
åµï¼å 为å¦æoldåå¨åèç¹ï¼é£ä¹ææ¬èç¹text为undefinedï¼åä¸newçtextä¸ç¸ç342 ç´æ¥node.textContentå³å¯æ¸
æ¥oldåå¨çåèç¹ãè¥oldåå¨åèç¹ï¼ä¸ç¸çåæ éä¿®æ¹343 */344 //1345 if (isUndef(vnode.text)) {346 //1.1.1347 if (isDef(oldCh) && isDef(ch)) {348 //å½Vnodeåoldvnodeçåèç¹ä¸åæ¶ï¼è°ç¨updatechilrenå½æ°ï¼diffåèç¹349 if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue);350 }351 //1.1.2352 else if (isDef(ch)) {353 //oldvnodeæ¯textèç¹ï¼åå°elmçtextæ¸
é¤354 //1.1.2.1355 if (isDef(oldVnode.text)) api.setTextContent(elm, '');356 //并添å vnodeçchildren357 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);358 }359 //å¦æoldvnodeæchildrenï¼èvnode没childrenï¼å移é¤elmçchildren360 //1.2.1361 else if (isDef(oldCh)) {362 removeVnodes(elm, oldCh, 0, oldCh.length - 1);363 }364 //1.2.2365 //å¦ævnodeåoldvnodeé½æ²¡chidlrenï¼ä¸vnode没textï¼åå é¤oldvnodeçtext366 else if (isDef(oldVnode.text)) {367 api.setTextContent(elm, '');368 }369 }370 //å¦æoldvnodeçtextåvnodeçtextä¸åï¼åæ´æ°ä¸ºvnodeçtextï¼371 //2.1372 else if (oldVnode.text !== vnode.text) {373 api.setTextContent(elm, vnode.text);374 }375 //patchå®ï¼è§¦åpostpatché©å376 if (isDef(hook) && isDef(i = hook.postpatch)) {377 i(oldVnode, vnode);378 }379 }380 return function(oldVnode, vnode) {381 var i, elm, parent;382 //è®°å½è¢«æå
¥çvnodeéåï¼ç¨äºæ¹é触åinsert383 var insertedVnodeQueue = [];384 //è°ç¨å
¨å±preé©å385 for (i = 0; i < cbs.pre.length; ++i) cbs.pre[i]();386 //å¦æoldvnodeæ¯domèç¹ï¼è½¬å为oldvnodeï¼å¨åå§å渲æçæ¶åçå¤ç387 if (isUndef(oldVnode.sel)) {388 oldVnode = emptyNodeAt(oldVnode);389 }390 //å¦æoldvnodeä¸vnodeç¸ä¼¼ï¼è¿è¡æ´æ°ï¼æ¯è¾å
¶keyå¼ä¸selå¼391 if (sameVnode(oldVnode, vnode)) {392 patchVnode(oldVnode, vnode, insertedVnodeQueue);393 } else {394 //å¦åï¼å°vnodeæå
¥ï¼å¹¶å°oldvnodeä»å
¶ç¶èç¹ä¸ç´æ¥å é¤395 elm = oldVnode.elm;396 parent = api.parentNode(elm);397 createElm(vnode, insertedVnodeQueue);398 if (parent !== null) {399 api.insertBefore(parent, vnode.elm, api.nextSibling(elm));400 removeVnodes(parent, [oldVnode], 0, 0);401 }402 }403 //æå
¥å®åï¼è°ç¨è¢«æå
¥çvnodeçinserté©å404 for (i = 0; i < insertedVnodeQueue.length; ++i) {405 insertedVnodeQueue[i].data.hook.insert(insertedVnodeQueue[i]);...
index.js
Source: index.js
1// æ¯è¾å±æ§æ´æ°ãææ¬æ´æ°ã触ååèç¹æ´æ°2function patchVnode() {}3// æ¯è¾èç¹æ¯å¦æ¯åä¸ä¸ª4function sameVnode() {}5// æ¯å¦æ¯undefined or null6function isUndef() {}7// æ¯å¦æ¯éundefined or null8function isDef() {}9// å¨endåstartä¹é´æ¹éæå
¥æ°èç¹10function addVNodes() {}11// æ¹éå é¤èç¹12function removeVnodes() {}13// æ°å¢å¹¶æå
¥å个èç¹14function createElm() {}15// 跨平å°ãå°è£
ç®åAPI16const nodeOps = {17 // èç¹ç移å¨å¹¶æå
¥æä½18 insertBefore() {}19};20// å¦ä½æµè¯å¢ï¼æä¼æè¿ä¸ªæ¹æ³ç½®æ¢æºä»£ç çupdateChildrenæ¹æ³ï¼ä¸äºå·¥å
·å½æ°å¦createKeyToOldIdxï¼æä¼æå®å£°æå¨å½æ°ççä½ç¨åå
ï¼æ¢ä¿è¯å½æ°æ§è¡çé»è¾ï¼åä¸å½±åå
¶ä»äººå¼ç¨21// æä¸èètransition22// 以èèç¹ä¸ºåºå23// eslint-disable-next-line no-unused-vars24function updateChildren(parentElm, oldList, newList) {25 function log(list) {26 console.log(list.map(({ key }) => key));27 }28 log(oldList);29 log(newList);30 // å
å设èç¹æ°ç»é½ækeyä¸keyä¸éå¤31 // çækeyçä¸æ 32 // { key1: 1, key2: 3, key3: 4}33 function createKeyToOldIdx(oldList, oldStart, oldEnd) {34 const map = {};35 for (let i = oldStart; i <= oldEnd; i++) {36 const { key } = oldList[i];37 if (isDef(key)) map[key] = i;38 }39 return map;40 }41 // å¤çèç¹æ²¡ækeyçæ
åµ æ²¡ækeyç´æ¥éåæ¯è¾ è¿åä¸æ æ¤æ¶æ¶é´å¤æ度å为O(n^2)42 function findIdxInOld(vnode, list, beginIdx, endIdx) {43 for (let i = beginIdx; i < endIdx; i++) {44 const c = list[i];45 if (isDef(c) && sameVnode(vnode, c)) return i;46 }47 }48 const lastIndex = arr => arr.length - 1;49 let [oldStartIdx, oldEndIdx] = [0, lastIndex(oldList)];50 let [newStartIdx, newEndIdx] = [0, lastIndex(newList)];51 // 两两交åæ¯è¾52 let [newStartVnode, newEndVnode] = [newList[newStartIdx], newList[newEndIdx]];53 let [oldStartVnode, oldEndVnode] = [oldList[oldStartIdx], oldList[oldEndIdx]];54 // çæèèç¹ keyåä¸æ çæ å°55 let oldKeyToIdx;56 // 循ç¯è³å
¶ä¸ä¸ä¸ªæ°ç»éåå®æ57 while (newStartIdx <= newEndIdx && oldStartIdx <= oldEndIdx) {58 // å¤çä¸äºå¼å¸¸ èé¦æèæ«ä¸åå¨ å继ç»å¾ªç¯59 if (isUndef(oldStartVnode)) {60 oldStartVnode = oldList[++oldStartIdx];61 } else if (isUndef(oldEndVnode)) {62 oldEndVnode = oldList[--oldEndIdx];63 // èé¦ == æ°é¦ ä¸ç¨ç§»å¨ç´æ¥æ´æ°64 } else if (sameVnode(oldStartVnode, newStartVnode)) {65 patchVnode(oldStartVnode, newStartVnode);66 newStartVnode = newList[++newStartIdx];67 oldStartVnode = oldList[++oldStartIdx];68 // èæ« == æ°æ« ä¸ç¨ç§»å¨ç´æ¥æ´æ°69 } else if (sameVnode(oldEndVnode, newEndVnode)) {70 patchVnode(oldEndVnode, newEndVnode);71 newEndVnode = newList[--newEndIdx];72 oldEndVnode = oldList[--oldEndIdx];73 // èé¦ == æ°æ«74 } else if (sameVnode(oldStartVnode, newEndVnode)) {75 // å
æ§è¡èç¹å±æ§æ´æ°76 patchVnode(oldStartVnode, newEndVnode);77 // 注æï¼insertBeforeãappendChildé½æ¯èç¹ç§»å¨æä½78 // æèé¦ç§»å¨å°oldEndIdxä½ç½®;79 // insertä¹å没ææ¹åä¸æ 80 // 没ææä½vdom81 // è¿é对èç¹æå
¥æä½åäºä¸äºå°è£
ï¼1. åæï¼è¦ä¿è¯ä¸¤ç«¯è¿è¡ã 2. ç®åAPIï¼æ«å°¾æå
¥ä½¿ç¨çå
¶å®æ¯appendChild82 nodeOps.insertBefore(83 parentElm,84 oldStartVnode.elm,85 nodeOps.nextSibling(oldEndVnode.elm)86 );87 // è¿éè¦ç§»å¨ä¸æ 88 oldStartVnode = oldList[++oldStartIdx];89 newEndVnode = newList[--newEndIdx];90 // èæ« == æ°é¦91 } else if (sameVnode(oldEndVnode, newStartVnode)) {92 patchVnode(oldEndVnode, newStartVnode);93 // æèæ«ç§»å¨å°oldStartIndex94 nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);95 oldEndVnode = oldList[--oldEndIdx];96 newStartVnode = newList[++newStartIdx];97 // 以ä¸æææ
åµå
¶å®é½æ¯å¯¹å¸¸è§åºæ¯çä¼åï¼å°±æ¯æ¯å¦èç¹å¢å ï¼æ¶é´å¤æ度é½æ¯O(n)98 // 对äºèç¹äº¤æ¢ä½ç½®ï¼å¯è½ä¼è§¦å以ä¸ç®æ³ï¼å°±æ¯å¸¸è§çéåæ¯è¾ç§»å¨ç®æ³ï¼å¦æækeyæ¶é´å¤æ度ä¹æ¯O(n)ï¼ä½è½åå°å·®å¼æå°å99 // 54231 => 14532 å°53 => 42ä¼è¿å
¥100 // å©ç¨äºéåçå¯ä¸key101 } else {102 // æ å°åªçæä¸æ¬¡103 if (isUndef(oldKeyToIdx))104 oldKeyToIdx = createKeyToOldIdx(oldList, oldStartIdx, oldEndIdx);105 // è¿éå设åèç¹é½æå¯ä¸key106 const idxInOld = isDef(newStartVnode.key)107 ? oldKeyToIdx[newStartVnode.key]108 : findIdxInOld(newStartVnode, oldList, oldStartIdx, oldEndIdx);109 if (isUndef(idxInOld)) {110 // å¦ææ°é¦å¨èèç¹ä¸ä¸åå¨ è¿è¡æ°å¢å¹¶æå
¥æä½111 // æå
¥å¹¶æ°å¢èç¹112 createElm(newStartVnode, [], parentElm, oldStartVnode.elm);113 } else {114 // å¦åå°±æ¯æ´æ°æä½115 // æ¾å°éè¦æ´æ°çèç¹116 const vnodeToMove = oldList[idxInOld];117 // ä¿é©èµ·è§è¿éè¿éè¦æ¯è¾ä¸æ¬¡ï¼é²æ¢åºç°keyç¸åï¼ä½èç¹ç±»åä¸åæ
åµ118 if (sameVnode(vnodeToMove, newStartVnode)) {119 // èè§ç©å
æ§è¡å±æ§æ´æ°120 patchVnode(vnodeToMove, newStartVnode);121 // è¿ä¸æ¥å¾å
³é® å 为èç¹å·²ç»è¢«ç§»å¨äº 置空å¯ä»¥å¨ä¸æ¬¡å¾ªç¯æ¶è¿æ»¤æ å¨ä¸é¢122 oldList[idxInOld] = undefined;123 // å次强è°ï¼insertBeforeæ¯ç§»å¨æä½124 nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm);125 } else {126 // å¦æèç¹keyç¸å ä½ç±»åä¸å é£ä¹ç¸å½äºæå
¥äºæ°èç¹127 // æå
¥å¹¶æ°å¢èç¹128 createElm(newStartVnode, [], parentElm, oldStartVnode.elm);129 }130 }131 // while(i) {++i} 循ç¯ç»ææ¶i+=1132 newStartVnode = newList[++newStartIdx];133 }134 }135 // 循ç¯ç»ææ¶å¯è½åºç°ä¸ç§æ
åµ: 1. èèç¹æªéåå® 2. æ°èç¹æªéåå®. 3. å
¨é¨èç¹é½éåå®æ136 // 为ä»ä¹ä¸ç¨oldEndIdx > oldStartIdx ? æ¥å¤æèèç¹æªéåå® æè§å¾é½è¡137 if (oldStartIdx > oldEndIdx) {138 // èèç¹éåå®æ æ°èç¹å¯è½è¿æªéåå®æ æªå®æçç´æ¥æ¹éæå
¥å°oldStartIdxåoldEndIdx交éçä½ç½®139 // æå
¸åçåºæ¯å°±æ¯ä¸é´è¿ç»èç¹æ°å¢çæ
åµ140 const refElm = isUndef(newList[newEndIdx + 1])141 ? null142 : newList[newEndIdx + 1].elm;143 // è¿ä¸ªå½æ°ç»ç»ä¸æ³éé¢åºè¯¥æ¶åå°ä¸ä¸ªVDomçæä½ ä¸differæ¬èº«æ å
³ æ以就ç´æ¥å¤ç¨äº144 addVnodes(parentElm, refElm, newList, newStartIdx, newEndIdx, []);145 } else if (newStartIdx > newEndIdx) {146 // å¦ææ°èç¹å
éåå® åæå¤çèèç¹å
¨é¨å é¤æ147 // æå
¸åçå°±æ¯æ¹éèç¹å é¤æ
åµ148 // è¿æä¸ç§å
¨é¨é½èµ°elseçæ
åµ149 removeVnodes(parentElm, oldList, oldStartIdx, oldEndIdx);150 }151}152if (sameVnode(oldStartVnode, newStartVnode)) {153 patchVnode(oldStartVnode, newStartVnode);154 newStartVnode = newList[++newStartIdx];155 oldStartVnode = oldList[++oldStartIdx];156 // èæ« == æ°æ« ä¸ç¨ç§»å¨ç´æ¥æ´æ°157} else if (sameVnode(oldEndVnode, newEndVnode)) {158 patchVnode(oldEndVnode, newEndVnode);159 newEndVnode = newList[--newEndIdx];160 oldEndVnode = oldList[--oldEndIdx];161 // èé¦ == æ°æ«162} else if (sameVnode(oldStartVnode, newEndVnode)) {163 // å
æ§è¡èç¹å±æ§æ´æ°164 patchVnode(oldStartVnode, newEndVnode);165 nodeOps.insertBefore(166 parentElm,167 oldStartVnode.elm,168 nodeOps.nextSibling(oldEndVnode.elm)169 );170 // è¿éè¦ç§»å¨ä¸æ 171 oldStartVnode = oldList[++oldStartIdx];172 newEndVnode = newList[--newEndIdx];173 // èæ« == æ°é¦174} else if (sameVnode(oldEndVnode, newStartVnode)) {175 patchVnode(oldEndVnode, newStartVnode);176 // æèæ«ç§»å¨å°oldStartIndex177 nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);178 oldEndVnode = oldList[--oldEndIdx];179 newStartVnode = newList[++newStartIdx];...
diff_patch.js
Source: diff_patch.js
...41 addVnodes(parentElm, null, vnode, 0, vnode.length - 1);42 } else if (!vnode) {43 removeVnodes(parentElm, oldVnode, 0, oldVnode.length - 1);44 } else {45 if (sameVnode(oldVNode, vnode)) {46 patchVnode(oldVNode, vnode);47 } else {48 removeVnodes(parentElm, oldVnode, 0, oldVnode.length - 1);49 addVnodes(parentElm, null, vnode, 0, vnode.length - 1);50 }51 }52 }53}54{ 55 /**56 * å¨å½æ°è VNode èç¹é½æ¯ isStaticï¼éæçï¼ï¼å¹¶ä¸ key ç¸åæ¶ï¼åªè¦å° componentInstance ä¸ elm ä»è VNode èç¹âæ¿è¿æ¥âå³å¯ã57 * 58 * è¿éç isStatic ä¹å°±æ¯åé¢æå°è¿çãç¼è¯ãçæ¶åä¼å°éæèç¹æ è®°åºæ¥ï¼è¿æ ·å°±å¯ä»¥è·³è¿æ¯å¯¹çè¿ç¨ã59 */60 function patchVnode (oldVnode, vnode) {61 if (oldVnode === vnode) {62 return;63 }64 if (vnode.isStatic && oldVnode.isStatic && vnode.key === oldVnode.key) {65 vnode.elm = oldVnode.elm;66 vnode.componentInstance = oldVnode.componentInstance;67 return;68 }69 const elm = vnode.elm = oldVnode.elm;70 const oldCh = oldVnode.children;71 const ch = vnode.children;72 if (vnode.text) {73 nodeOps.setTextContent(elm, vnode.text);74 } else {75 if (oldCh && ch && (oldCh !== ch)) {76 updateChildren(elm, oldCh, ch);77 } else if (ch) {78 if (oldVnode.text) nodeOps.setTextContent(elm, '');79 addVnodes(elm, null, ch, 0, ch.length - 1);80 } else if (oldCh) {81 removeVnodes(elm, oldCh, 0, oldCh.length - 1)82 } else if (oldVnode.text) {83 nodeOps.setTextContent(elm, '')84 }85 }86 }87}88{89 function updateChildren (parentElm, oldCh, newCh) {90 let oldStartIdx = 0;91 let newStartIdx = 0;92 let oldEndIdx = oldCh.length - 1;93 let oldStartVnode = oldCh[0];94 let oldEndVnode = oldCh[oldEndIdx];95 let newEndIdx = newCh.length - 1;96 let newStartVnode = newCh[0];97 let newEndVnode = newCh[newEndIdx];98 let oldKeyToIdx, idxInOld, elmToMove, refElm;99 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {100 if (!oldStartVnode) {101 oldStartVnode = oldCh[++oldStartIdx];102 } else if (!oldEndVnode) {103 oldEndVnode = oldCh[--oldEndIdx];104 } else if (sameVnode(oldStartVnode, newStartVnode)) {105 patchVnode(oldStartVnode, newStartVnode);106 oldStartVnode = oldCh[++oldStartIdx];107 newStartVnode = newCh[++newStartIdx];108 } else if (sameVnode(oldEndVnode, newEndVnode)) {109 patchVnode(oldEndVnode, newEndVnode);110 oldEndVnode = oldCh[--oldEndIdx];111 newEndVnode = newCh[--newEndIdx];112 } else if (sameVnode(oldStartVnode, newEndVnode)) {113 patchVnode(oldStartVnode, newEndVnode);114 nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm));115 oldStartVnode = oldCh[++oldStartIdx];116 newEndVnode = newCh[--newEndIdx];117 } else if (sameVnode(oldEndVnode, newStartVnode)) {118 patchVnode(oldEndVnode, newStartVnode);119 nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);120 oldEndVnode = oldCh[--oldEndIdx];121 newStartVnode = newCh[++newStartIdx];122 } else {123 let elmToMove = oldCh[idxInOld];124 if (!oldKeyToIdx) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);125 idxInOld = newStartVnode.key ? oldKeyToIdx[newStartVnode.key] : null;126 if (!idxInOld) {127 createElm(newStartVnode, parentElm);128 newStartVnode = newCh[++newStartIdx];129 } else {130 elmToMove = oldCh[idxInOld];131 if (sameVnode(elmToMove, newStartVnode)) {132 patchVnode(elmToMove, newStartVnode);133 oldCh[idxInOld] = undefined;134 nodeOps.insertBefore(parentElm, newStartVnode.elm, oldStartVnode.elm);135 newStartVnode = newCh[++newStartIdx];136 } else {137 createElm(newStartVnode, parentElm);138 newStartVnode = newCh[++newStartIdx];139 }140 }141 }142 }143 if (oldStartIdx > oldEndIdx) {144 refElm = (newCh[newEndIdx + 1]) ? newCh[newEndIdx + 1].elm : null;145 addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx);...
vdom.js
Source: vdom.js
...86 if (!oldStartVnode) {87 oldStartVnode = [++oldStartIdx]88 } else if (!oldEndVnode) {89 oldEndVnode = [--oldEndIdx]90 } else if (sameVnode(oldStartVnode, newStartVnode)) {91 patchVnode(oldStartVnode, newStartVnode)92 oldStartVnode = oldCh[++oldStartIdx]93 newStartVnode = newCh[++newStartIdx]94 } else if (sameVnode(oldEndVnode, newEndVnode)) {95 patchVnode(oldEndVnode, newEndVnode)96 oldEndVnode = oldCh[--oldEndIdx]97 newEndVnode = newCh[--newEndIdx]98 } else if (sameVnode(oldStartVnode, newEndVnode)) {99 // è头 æ°å°¾100 patchVnode(oldStartVnode, newEndVnode)101 nodeOps.insertBefore(102 parentElm,103 oldStartVnode.elm,104 nodeOps.nextSibling(oldEndVnode.elm)105 )106 oldStartVnode = oldCh[++oldStartIdx]107 newEndVnode = newCh[--newEndIdx]108 } else if (sameVnode(oldEndVnode, newStartVnode)) {109 patchVnode(oldEndVnode, newStartVnode)110 nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)111 oldEndVnode = oldCh[--oldEndIdx]112 newStartVnode = newCh[++newStartIdx]113 } else {114 // å¦æ以ä¸é½æ²¡å¹é
å°ï¼å°±æ ¹æ®æ°çkey ä»èçèç¹é æå®æ¾åºæ¥ï¼ç¶åæªå° oldStartIdx çä½ç½®ï¼å¹¶æ¸
空115 let idxInOld116 for (let i = oldStartIdx; i <= oldEndIdx; ++i) {117 if (oldCh[i] && newStartVnode.key == oldCh[i].key) {118 idxInOld = i119 break120 }121 }122 if (!idxInOld) {123 createElm(newStartVnode, parentElm, oldStartVnode.elm)124 } else {125 let vnodeToMove = oldCh[idxInOld]126 if (sameVnode(vnodeToMove, newStartVnode)) {127 patchVnode(vnodeToMove, newStartVnode)128 oldCh[idxInOld] = undefined129 nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)130 } else {131 createElm(newStartVnode, parentElm, oldStartVnode.elm)132 }133 }134 newStartVnode = newCh[++newStartIdx]135 }136 }137 if (oldStartIdx > oldEndIdx) {138 refElm = !newCh[newEndIdx + 1] ? null : newCh[newEndIdx + 1].elm139 addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx)140 } else if (newStartIdx > newEndIdx) {141 removeVnodes(oldCh, oldStartIdx, oldEndIdx)142 }143}144function addVnodes(parentElm, refElm, vnodes, startIdx, endIdx) {145 for (; startIdx <= endIdx; ++startIdx) {146 createElm(vnodes[startIdx], parentElm, refElm)147 }148}149function removeVnodes(vnodes, startIdx, endIdx) {150 for (; startIdx <= endIdx; ++startIdx) {151 const ch = vnodes[startIdx]152 if (ch) {153 removeNode(ch.elm)154 }155 }156}157function removeNode(el) {158 const parent = nodeOps.parentNode(el)159 if (parent) {160 nodeOps.removeChild(parent, el)161 }162}163function sameVnode(a, b) {164 return a.key === b.key && a.tag === b.tag...
patch.js
Source: patch.js
...81 if (isUndef(oldStartVnode)) {82 oldStartVnode = oldCh[++oldStartIdx] // Vnode has been moved left83 } else if (isUndef(oldEndVnode)) {84 oldEndVnode = oldCh[--oldEndIdx]85 } else if (sameVnode(oldStartVnode, newStartVnode)) {86 patchVnode(oldStartVnode, newStartVnode)87 oldStartVnode = oldCh[++oldStartIdx]88 newStartVnode = newCh[++newStartIdx]89 } else if (sameVnode(oldEndVnode, newEndVnode)) {90 patchVnode(oldEndVnode, newEndVnode)91 oldEndVnode = oldCh[--oldEndIdx]92 newEndVnode = newCh[--newEndIdx]93 } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right94 patchVnode(oldStartVnode, newEndVnode)95 const oldEndNext = nodeOps.nextSibling(oldEndVnode.elm)96 nodeOps.insertBefore(parentElm, oldStartVnode.elm, oldEndNext)97 oldStartVnode = oldCh[++oldStartIdx]98 newEndVnode = newCh[--newEndIdx]99 } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left100 patchVnode(oldEndVnode, newStartVnode)101 nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)102 oldEndVnode = oldCh[--oldEndIdx]103 newStartVnode = newCh[++newStartIdx]104 } else {105 // create oldKeyToIdx106 if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx) }107 108 const idxInOld = oldKeyToIdx[newStartVnode.key]109 if (isDef(idxInOld) && sameVnode(newStartVnode, oldCh[idxInOld])) {110 const vnodeToMove = oldCh[idxInOld]111 patchVnode(vnodeToMove, newStartVnode)112 oldCh[idxInOld] = undefined113 nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)114 newStartVnode = newCh[++newStartIdx]115 } else { // New element116 const elm = createElm(newStartVnode)117 nodeOps.insertBefore(parentElm, elm, oldStartVnode.elm)118 newStartVnode = newCh[++newStartIdx]119 }120 }121 }122 123 if (oldStartIdx > oldEndIdx) {124 const before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm125 addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx)126 } else if (newStartIdx > newEndIdx) {127 removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)128 }129}130/**131 * patchVnode åè®¾äº sameVnode(oldVnode, vnode) === true132 * äºå®ä¸ä¹æ¯å¦æ¤133 */134function patchVnode (oldVnode, vnode) {135 if (oldVnode === vnode) { return }136 137 const elm = vnode.elm = oldVnode.elm138 139 if (isUndef(vnode.text)) {140 const oldCh = oldVnode.children141 const ch = vnode.children142 updateChildren(elm, oldCh, ch)143 } else if (oldVnode.text !== vnode.text) {144 nodeOps.setTextContent(elm, vnode.text)145 }146}147export default function patch (oldVnode, vnode) {148 149 if (isUndef(oldVnode) && isUndef(vnode)) { return }150 if (isUndef(oldVnode)) { createElm(vnode); return }151 const oldElm = oldVnode.elm152 const parent = nodeOps.parentNode(oldElm)153 if (isUndef(vnode)) { removeVnodes(parent, [oldVnode], 0, 0); return }154 if (sameVnode(oldVnode, vnode)) { patchVnode(oldVnode, vnode); return }155 else {156 const newElm = createElm(vnode)157 nodeOps.insertBefore(parent, newElm, nodeOps.nextSibling(oldElm))158 removeVnodes(parent, [oldVnode], 0, 0)159 return160 }...
patchVNode.js
Source: patchVNode.js
1import createElement from './createElement.js'2import sameVNode from './sameVNode.js'3import createKeyToOldIdx from './createKeyToOldIdx.js'4export default function patchVNode(oldVNode,newVNode){5 newVNode.elm = oldVNode.elm6 if(newVNode===oldVNode){7 return8 }else if(newVNode.text&&(newVNode.children===undefined||newVNode.children.length===0)){9 if(newVNode.text!==oldVNode.text)10 oldVNode.elm.innerText = newVNode.text11 }else if(oldVNode.children===undefined||oldVNode.children.length===0){12 oldVNode.elm.innerText = ''13 for(let d of newVNode.children){14 const node = createElement(d)15 oldVNode.elm.appendChild(node)16 }17 }else{18 newVNode.elm = oldVNode.elm19 let startIndex = 020 let endIndex = oldVNode.children.length-121 let newStartIndex = 022 let newEndIndex = newVNode.children.length-123 let oldKeyToIdx , idxInOld24 while(startIndex<=endIndex&&newStartIndex<=newEndIndex){25 if(oldVNode.children[startIndex]===undefined){26 startIndex++27 }else if(oldVNode.children[endIndex]===undefined){28 endIndex--29 }else if(sameVNode(oldVNode.children[startIndex],newVNode.children[newStartIndex])){30 patchVNode(oldVNode.children[startIndex],newVNode.children[newStartIndex])31 startIndex++32 newStartIndex++33 }else if(sameVNode(oldVNode.children[endIndex],newVNode.children[newEndIndex])){34 patchVNode(oldVNode.children[endIndex],newVNode.children[newEndIndex])35 endIndex --36 newEndIndex -- 37 }else if(sameVNode(oldVNode.children[startIndex],newVNode.children[newEndIndex])){38 patchVnode(oldVNode.children[startIndex], newVNode.children[newEndIndex])39 oldVNode.elm.insertBefore(oldVNode.children[startIndex], oldVNode.children[endIndex].nextSibling)40 startIndex++41 newEndIndex--42 }else if(sameVNode(oldVNode.children[endIndex],newVNode.children[newStartIndex])){43 patchVnode(oldVNode.children[endIndex], newVNode.children[newStartIndex])44 oldVNode.elm.insertBefore(oldVNode.children[endIndex], oldVNode.children[startIndex])45 newStartIndex++46 endIndex-- 47 }else{48 if(!oldKeyToIdx){49 oldKeyToIdx = createKeyToOldIdx(oldVNode.children,startIndex,endIndex)50 }51 idxInOld =newVNode.children[newStartIndex].key ? oldKeyToIdx[newVNode.children[newStartIndex].key]52 : findIdxInOld(newVNode.children[newStartIndex], oldCh, startIndex, endIndex)53 if (!idxInOld) { 54 const node = createElement(newVNode.children[newStartIndex])55 oldVNode.elm.insertBefore(node, oldVNode.children[startIndex].elm)56 } else {57 let vnodeToMove = oldVNode.children[idxInOld]58 if (sameVNode(oldVNode.children[idxInOld], newVNode.children[newStartIndex])) {59 patchVNode(oldVNode.children[idxInOld], newVNode.children[newStartIndex])60 oldCh[idxInOld] = undefined61 oldVNode.elm.insertBefore(oldVNode.children[i].elm, oldVNode.children[startIndex].elm)62 } else {63 const node = createElement(newVNode.children[newStartIndex])64 oldVNode.elm.insertBefore(node, oldVNode.children[startIndex].elm)65 }66 }67 newStartIndex++68 }69 }70 if(startIndex>endIndex){71 for(;newStartIndex<=newEndIndex;newStartIndex++){72 const node = createElement(newVNode.children[newStartIndex])73 oldVNode.elm.appendChild(node)74 }75 }else if(newStartIndex>newEndIndex){76 for(;startIndex<=endIndex;startIndex++){77 if(oldVNode.children[startIndex])78 oldVNode.elm.removeChild(oldVNode.children[startIndex].elm)79 }80 }81 }...
patchChildren.js
Source: patchChildren.js
...30 if (ch1[oldStartIndex] == undefined) {31 oldStartIndex++;32 } else if (ch1[oldEndIndex] == undefined) {33 oldEndIndex--;34 } else if (sameVnode(ch2[newStartIndex], ch1[oldStartIndex])) {35 patchVnode(ch2[newStartIndex], ch1[oldStartIndex]);36 newStartIndex++;37 oldStartIndex++;38 } else if (sameVnode(ch2[newEndIndex], ch1[oldEndIndex])) {39 patchVnode(ch2[newEndIndex], ch1[oldEndIndex]);40 newEndIndex--;41 oldEndIndex--;42 } else if (sameVnode(ch2[newEndIndex], ch1[oldStartIndex])) {43 patchVnode(ch2[newEndIndex], ch1[oldStartIndex]);44 insertAfter(parent, ch1[oldStartIndex].elm, ch1[oldEndIndex].elm);45 newEndIndex--;46 oldStartIndex++;47 } else if (sameVnode(ch2[newStartIndex], ch1[oldEndIndex])) {48 patchVnode(ch2[newStartIndex], ch1[oldEndIndex]);49 insertBefore(parent, ch1[oldEndIndex].elm, ch1[oldStartIndex].elm);50 newStartIndex++;51 oldEndIndex--;52 } else {53 let flag = true;54 for (let i = oldStartIndex; i <= oldEndIndex; i++) {55 if (sameVnode(ch2[newStartIndex], ch1[i])) {56 patchVnode(ch2[newStartIndex], ch1[i]);57 insertBefore(parent, ch1[i].elm, ch1[oldStartIndex].elm);58 ch1[i] = undefined;59 flag = false;60 break;61 }62 }63 if (flag) {64 let dom = createElement(ch2[newStartIndex]);65 insertBefore(parent, dom, ch1[oldStartIndex].elm);66 }67 newStartIndex++;68 }69 }...
updateChildren.js
Source: updateChildren.js
...13 // 循ç¯ç»æ¢æ¡ä»¶14 while(oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {15 16 // æ§å å æ°åæ¯è¾ æ¯å¦ç¸å17 if(sameVnode(oldStartVnode, newStartVnode)) {18 19 oldStartVnode = oldCh[++oldStartIdx];20 newStartVnode = newCh[++newStartIdx];21 } else if(sameVnode(oldEndVnode, newEndVnode)) {22 oldEndVnode = oldCh[--oldEndIdx]23 newEndVnode = newCh[--newEndIdx]24 } else if (sameVnode(oldStartVnode, newEndVnode)) {25 oldStartVnode = oldCh[++oldStartIdx]26 newEndVnode = newCh[--newEndIdx]27 } else if (sameVnode(oldEndVnode, newStartVnode)) {28 oldEndVnode = oldCh[--oldEndIdx]29 newStartVnode = newCh[++newStartIdx]30 } else {31 // 没ææ¾å° å©ç¨å¾ªç¯æ¥æ¥æ¾32 }33 }...
Using AI Code Generation
1const { sameVnode } = require('playwright/lib/server/dom.js');2const { sameVnode } = require('playwright/lib/server/dom.js');3const { sameVnode } = require('playwright/lib/server/dom.js');4const { sameVnode } = require('playwright/lib/server/dom.js');5const { sameVnode } = require('playwright/lib/server/dom.js');6const { sameVnode } = require('playwright/lib/server/dom.js');7const { sameVnode } = require('playwright/lib/server/dom.js');8const { sameVnode } = require('playwright/lib/server/dom.js');9const { sameVnode } = require('playwright/lib/server/dom.js');
Using AI Code Generation
1const { sameVnode } = require('playwright/lib/server/dom.js');2const { test } = require('@playwright/test');3test('test', async ({ page }) => {4 const a = await page.$('a');5 const b = await page.$('a');6});
Using AI Code Generation
1const { sameVnode } = require('playwright/lib/server/dom.js');2const { parse } = require('playwright/lib/utils/selectorParser.js');3const { ElementHandle } = require('playwright/lib/server/dom.js');4const selector = parse('.foo');5const node = new ElementHandle(page, 'node');6const sameVnodeResult = sameVnode(selector, node);7console.log(sameVnodeResult);8const { sameVnode } = require('playwright/lib/server/dom.js');9const { parse } = require('playwright/lib/utils/selectorParser.js');10const { ElementHandle } = require('playwright/lib/server/dom.js');11const selector = parse('div');12const node = new ElementHandle(page, 'node');13const sameVnodeResult = sameVnode(selector, node);14console.log(sameVnodeResult);15const { sameVnode } = require('playwright/lib/server/dom.js');16const { parse } = require('playwright/lib/utils/selectorParser.js');17const { ElementHandle } = require('playwright/lib/server/dom.js');18const selector = parse('div');19const node = new ElementHandle(page, 'node');20const sameVnodeResult = sameVnode(selector, node);21console.log(sameVnodeResult);22const { sameVnode } = require('playwright/lib/server/dom.js');23const { parse } = require('playwright/lib/utils/selectorParser.js');24const { ElementHandle } = require('playwright/lib/server/dom.js');25const selector = parse('div');26const node = new ElementHandle(page, 'node');27const sameVnodeResult = sameVnode(selector, node);28console.log(sameVnodeResult);29const { sameVnode } = require('playwright/lib/server/dom.js');30const { parse } = require('playwright/lib/utils/selectorParser.js');31const { ElementHandle } = require('playwright/lib/server/dom.js');32const selector = parse('div');
Using AI Code Generation
1const { isSameVnode } = require('playwright/lib/server/sameVnode');2const { Page } = require('playwright/lib/server/page');3const { ElementHandle } = require('playwright/lib/server/frames');4const { ElementHandleChannel } = require('playwright/lib/channels');5const { isSameVnode } = require('playwright/lib/server/sameVnode');6const { Page } = require('playwright/lib/server/page');7const { ElementHandle } = require('playwright/lib/server/frames');8const { ElementHandleChannel } = require('playwright/lib/channels');9const { isSameVnode } = require('playwright/lib/server/sameVnode');10const { Page } = require('playwright/lib/server/page');11const { ElementHandle } = require('playwright/lib/server/frames');12const { ElementHandleChannel } = require('playwright/lib/channels');13const { isSameVnode } = require('playwright/lib/server/sameVnode');14const { Page } = require('playwright/lib/server/page');15const { ElementHandle } = require('playwright/lib/server/frames');16const { ElementHandleChannel } = require('playwright/lib/channels');17const { isSameVnode } = require('playwright/lib/server/sameVnode');18const { Page } = require('playwright/lib/server/page');19const { ElementHandle } = require('playwright/lib/server/frames');20const { ElementHandleChannel } = require('playwright/lib/channels');21const { isSameVnode } = require('playwright/lib/server/sameVnode');22const { Page } = require('playwright/lib/server/page');23const { ElementHandle } = require('playwright/lib/server/frames');24const { ElementHandleChannel } = require('playwright/lib/channels');25const { isSameVnode } = require('playwright/lib/server/sameVnode');26const { Page } = require('playwright/lib/server/page');27const { ElementHandle } = require('play
Using AI Code Generation
1const { sameVnode } = require('playwright/lib/server/dom.js');2const { parse } = require('playwright/lib/server/common/parser.js');3const { sameVnode } = require('playwright/lib/server/dom.js');4const { parse } = require('playwright/lib/server/common/parser.js');5const doc1 = parse(`6`);7const doc2 = parse(`8`);9const doc3 = parse(`10`);11const doc4 = parse(`12`);13const doc5 = parse(`14`);15const doc6 = parse(`16`);17const doc7 = parse(`18`);19const doc8 = parse(`20`);21const doc9 = parse(`
Using AI Code Generation
1const { sameVnode } = require('playwright/lib/server/dom.js');2const { assert } = require('chai');3const node1 = { nodeName: 'DIV', attributes: { id: 'id1' } };4const node2 = { nodeName: 'DIV', attributes: { id: 'id2' } };5const node3 = { nodeName: 'DIV', attributes: { id: 'id1' } };6assert.equal(sameVnode(node1, node2), false);7assert.equal(sameVnode(node1, node3), true);8[MIT](LICENSE)
Using AI Code Generation
1const { sameVnode } = require('playwright/lib/utils/utils');2const { ElementHandle } = require('playwright/lib/cjs/pw_api/types');3const elementHandle = new ElementHandle();4const elementHandle2 = new ElementHandle();5const res = sameVnode(elementHandle, elementHandle2);6const { sameVnode } = require('playwright/lib/utils/utils');7const { ElementHandle } = require('playwright/lib/cjs/pw_api/types');8const elementHandle = new ElementHandle();9const elementHandle2 = new ElementHandle();10const res = sameVnode(elementHandle, elementHandle2);11[MIT](
firefox browser does not start in playwright
firefox browser does not start in playwright
Running Playwright in Azure Function
Is it possible to get the selector from a locator object in playwright?
How to run a list of test suites in a single file concurrently in jest?
Jest + Playwright - Test callbacks of event-based DOM library
I found the error. It was because of some missing libraries need. I discovered this when I downgraded playwright to version 1.9 and ran the the code then this was the error msg:
(node:12876) UnhandledPromiseRejectionWarning: browserType.launch: Host system is missing dependencies!
Some of the Universal C Runtime files cannot be found on the system. You can fix
that by installing Microsoft Visual C++ Redistributable for Visual Studio from:
https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
Full list of missing libraries:
vcruntime140.dll
msvcp140.dll
Error
at Object.captureStackTrace (D:\Projects\snkrs-play\node_modules\playwright\lib\utils\stackTrace.js:48:19)
at Connection.sendMessageToServer (D:\Projects\snkrs-play\node_modules\playwright\lib\client\connection.js:69:48)
at Proxy.<anonymous> (D:\Projects\snkrs-play\node_modules\playwright\lib\client\channelOwner.js:64:61)
at D:\Projects\snkrs-play\node_modules\playwright\lib\client\browserType.js:64:67
at BrowserType._wrapApiCall (D:\Projects\snkrs-play\node_modules\playwright\lib\client\channelOwner.js:77:34)
at BrowserType.launch (D:\Projects\snkrs-play\node_modules\playwright\lib\client\browserType.js:55:21)
at D:\Projects\snkrs-play\index.js:4:35
at Object.<anonymous> (D:\Projects\snkrs-play\index.js:7:3)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:12876) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:12876) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
A list of missing libraries was provided. After successful installments, firefox ran fine. I upgraded again to version 1.10 and firefox still works.
Check out the latest blogs from LambdaTest on this topic:
In addition to the four values, the Agile Manifesto contains twelve principles that are used as guides for all methodologies included under the Agile movement, such as XP, Scrum, and Kanban.
When working on web automation with Selenium, I encountered scenarios where I needed to refresh pages from time to time. When does this happen? One scenario is that I needed to refresh the page to check that the data I expected to see was still available even after refreshing. Another possibility is to clear form data without going through each input individually.
Before we discuss Scala testing, let us understand the fundamentals of Scala and how this programming language is a preferred choice for your development requirements.The popularity and usage of Scala are rapidly rising, evident by the ever-increasing open positions for Scala developers.
Testing is a critical step in any web application development process. However, it can be an overwhelming task if you don’t have the right tools and expertise. A large percentage of websites still launch with errors that frustrate users and negatively affect the overall success of the site. When a website faces failure after launch, it costs time and money to fix.
Software Risk Management (SRM) combines a set of tools, processes, and methods for managing risks in the software development lifecycle. In SRM, we want to make informed decisions about what can go wrong at various levels within a company (e.g., business, project, and software related).
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!!