Best JavaScript code snippet using playwright-internal
patch.js
Source: patch.js
...21 // 4. å¦åæè½½æ°çåèç¹22 // mountChildren(...)23 }24}25function isSameVNodeType(n1, n1) {26 //27}28export function patchkeyedChildren(c1, c2) {29 let i = 0;30 const l2 = c2.length;31 let e1 = c1.length - 1; // prev ending index32 let e2 = l2 - 1; // next ending index33 // i <= 2 && i <= 334 // ä»å·¦åå³diff35 while (i <= e1 && i <= e2) {36 const n1 = c1[i];37 const n2 = c2[i];38 if (isSameVNodeType(n1, n2)) {39 // å¦ææ¯ç¸åçèç¹ç±»åï¼åè¿è¡éå½patch40 // patch(...)41 } else {42 // å¦åéåº43 break;44 }45 i++;46 }47 // i <= 2 && i <= 348 // ä»ååå·¦diff49 // ç»æåï¼ e1 = 0 e2 = 150 while (i <= e1 && i <= e2) {51 const n1 = c1[e1];52 const n2 = c2[e2];53 if (isSameVNodeType(n1, n2)) {54 // ç¸åçèç¹ç±»å55 // patch(...)56 } else {57 // å¦åéåº58 break;59 }60 e1--;61 e2--;62 }63 // 3. common sequence + mount64 // (a b)65 // (a b) c66 // i = 2, e1 = 1, e2 = 267 // (a b)68 // c (a b)69 // i = 0, e1 = -1, e2 = 070 if (i > e1) {71 if (i <= e2) {72 const nextPos = e2 + 1;73 // nextPos < l2ï¼è¯´ææå·²ç»patchè¿å°¾é¨èç¹ï¼74 // å¦åä¼è·åç¶èç¹ä½ä¸ºéç¹75 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;76 while (i <= e2) {77 patch(null, c2[i], anchor, ...others);78 i++;79 }80 }81 }82 // 4. common sequence + unmount83 // (a b) c84 // (a b)85 // i = 2, e1 = 2, e2 = 186 // a (b c)87 // (b c)88 // i = 0, e1 = 0, e2 = -189 // å
Œ
±åºå å¸è½½æ§ç90 else if (i > e2) {91 while (i <= e1) {92 unmount(c1[i], parentComponent, parentSuspense, true);93 i++;94 }95 }96 // 5. ä¹±åºçæ
åµ97 // [i ... e1 + 1]: a b [c d e] f g98 // [i ... e2 + 1]: a b [e d c h] f g99 // i = 2, e1 = 4, e2 = 5100 const s1 = i; // s1 = 2101 const s2 = i; // s2 = 2102 // 5.1 build key:index map for newChildren103 // é¦å
为æ°çåèç¹æ建å¨æ°çååºåä¸ keyï¼index çæ å°104 // éè¿map å建çæ°çåèç¹105 const keyToNewIndexMap = new Map();106 // éåæ°çèç¹ï¼ä¸ºæ°èç¹è®¾ç½®key107 // i = 2; i <= 5108 for (i = s2; i <= e2; i++) {109 // è·åçæ¯æ°åºåä¸çåèç¹110 const nextChild = c2[i];111 if (nextChild.key != null) {112 // nextChild.key å·²åå¨113 // a b [e d c h] f g114 // e:2 d:3 c:4 h:5115 keyToNewIndexMap.set(nextChild.key, i);116 }117 }118 // 5.2 loop through old children left to be patched and try to patch119 // matching nodes & remove nodes that are no longer present120 // ä»æ§çåèç¹ç左侧å¼å§å¾ªç¯éåè¿è¡patchã121 // 并ä¸patchå¹é
çèç¹ å¹¶ç§»é¤ä¸åå¨çèç¹122 // å·²ç»patchçèç¹ä¸ªæ°123 let patched = 0;124 // éè¦patchçèç¹æ°é125 // 以ä¸å¾ä¸ºä¾ï¼e2 = 5; s2 = 2; ç¥ééè¦patchçèç¹ä¸ªæ°126 // toBePatched = 4127 const toBePatched = e2 - s2 + 1;128 // ç¨äºå¤æèç¹æ¯å¦éè¦ç§»å¨129 // å½æ°æ§éåä¸åºç°å¯å¤ç¨èç¹äº¤åæ¶ï¼moved = true130 let moved = false;131 // used to track whether any node has moved132 // ç¨äºè®°å½èç¹æ¯å¦å·²ç»ç§»å¨133 let maxNewIndexSoFar = 0;134 // works as Map<newIndex, oldIndex>135 // ä½æ°æ§èç¹çä¸æ æ å°136 // Note that oldIndex is offset by +1137 // 注æ æ§èç¹ç index è¦åå³å移ä¸ä¸ªä¸æ 138 // and oldIndex = 0 is a special value indicating the new node has139 // no corresponding old node.140 // 并ä¸æ§èç¹Index = 0 æ¯ä¸ä¸ªç¹æ®çå¼ï¼ç¨äºè¡¨ç¤ºæ°çèç¹ä¸æ²¡æ对åºçæ§èç¹141 // used for determining longest stable subsequence142 // newIndexToOldIndexMap ç¨äºç¡®å®æé¿éå¢ååºå143 // æ°ä¸æ ä¸æ§ä¸æ çmap144 const newIndexToOldIndexMap = new Array(toBePatched);145 // å°ææçå¼åå§å为0146 // [0, 0, 0, 0]147 for (i = 0; i < toBePatched; i++) newIndexToOldIndexMap[i] = 0;148 // éåæªå¤çæ§åºåä¸åèç¹149 for (i = s1; i <= e1; i++) {150 // è·åæ§èç¹151 // ä¼é个è·å c d e152 const prevChild = c1[i];153 // å¦æå·²ç»patch çæ°é >= éè¦è¿è¡patchçèç¹ä¸ªæ°154 // patchedåå¼å§ä¸º 0155 // patched >= 4156 if (patched >= toBePatched) {157 // all new children have been patched so this can only be a removal158 // è¿è¯´æææçæ°èç¹å·²ç»è¢«patch å æ¤å¯ä»¥ç§»é¤æ§ç159 unmount(prevChild, parentComponent, parentSuspense, true);160 continue;161 }162 }163 // æ°èç¹ä¸æ 164 let newIndex;165 if (prevChild.key != null) {166 // æ§çèç¹è¯å®ækey,167 // æ ¹æ®æ§èç¹key è·åç¸åç±»åçæ°çåèç¹ å¨ æ°çéåä¸å¯¹åºèç¹ä½ç½®168 // è¿ä¸ªæ¶å å 为c d e æ¯åæ¥çèç¹ å¹¶ä¸ækey169 // h æ¯æ°å¢èç¹ æ§èç¹ä¸æ²¡æ è·åä¸å° 对åºçindex ä¼èµ°else170 // æ以newIndexå¨å¼å§æ¶ä¼æå¦ä¸æ
åµ171 /**172 * node newIndex173 * c 4174 * d 3175 * e 2176 * */177 // è¿éæ¯å¯ä»¥è·åå°newIndexç178 newIndex = keyToNewIndexMap.get(prevChild.key);179 }180 // key-less node, try to locate a key-less node of the same type181 // å¦ææ§çèç¹æ²¡ækey182 // åä¼æ¥æ¾æ²¡ækeyç ä¸ä¸ºç¸åç±»åçæ°èç¹å¨ æ°èç¹éåä¸ çä½ç½®183 // j = 2: j <= 5184 for (j = s2; j <= e2; j++) {185 if (186 newIndexToOldIndexMap[j - s2] === 0 &&187 // å¤ææ¯å¦æ¯æ°æ§èç¹æ¯å¦ç¸å188 isSameVNodeType(prevChild, c2[j])189 ) {190 // è·åå°ç¸åç±»åèç¹çä¸æ 191 newIndex = j;192 break;193 }194 }195 if (newIndex === undefined) {196 // 没æ对åºçæ°èç¹ å¸è½½æ§ç197 unmount(prevChild, parentComponent, parentSuspense, true);198 }199 // è¿éå¤çè·åå°newIndexçæ
åµ200 // å¼å§æ´çæ°èç¹ä¸æ Index å¯¹äº ç¸åç±»åæ§èç¹å¨ æ§éåä¸çæ å°201 // æ°èç¹ä¸æ ä» s2=2 å¼å§ï¼å¯¹åºçæ§èç¹ä¸æ éè¦å移ä¸ä¸ªä¸æ 202 // 0 表示å½åèç¹æ²¡æ对åºçæ§èç¹...
renderer.js
Source: renderer.js
1import { createApp } from './createApp'2import { ShapeFlags } from '../shared/utils'3import { createComponentInstance, setupComponent } from './component'4import { effect } from '../reactivity'5export function createRenderer(options) {6 console.log(options)7 return baseCreateRenderer(options)8}9function baseCreateRenderer(options) {10 const {11 createElement: hostCreateElement,12 patchProp: hostPatchProp,13 setElementText: hostSetElementText,14 insetElement: hostInsert,15 removeChild: hostRemove16 } = options17 const mountElement = (vnode, container, anchor) => {18 let { shapeFlag, props } = vnode19 let el = vnode.el = hostCreateElement(vnode.type);20 // å建ååèç¹21 if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {22 hostSetElementText(el, vnode.children)23 } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {24 mountChildren(vnode.children, el)25 }26 if (props) {27 // æ·»å å±æ§28 for (let key in props) {29 hostPatchProp(el, key, null, props[key])30 }31 }32 hostInsert(el, container, anchor)33 }34 const mountChildren = (children, container) => {35 for (let i = 0; i < children.length; i++) {36 patch(null, children[i], container)37 }38 }39 const patchProps = (oldProps, newProps, el) => {40 if (oldProps !== newProps) {41 // æ°å±æ§è¦çèå±æ§42 for (let key in newProps) {43 const prev = oldProps[key],44 next = newProps[key];45 if (prev !== next) {46 hostPatchProp(el, key, prev, next)47 }48 }49 // èå¾æå±æ§ï¼æ°ç没æ,éè¦å é¤å±æ§50 for (let key in oldProps) {51 if (!(key in newProps)) {52 hostPatchProp(el, key, oldProps[key], null)53 }54 }55 }56 }57 const patchKeydChildren = (c1, c2, el) => {58 // å
é¨ä¼åçç¥ å¤´å°¾åæé59 // ab i=260 // abcd61 let i = 0;62 let e1 = c1.length - 1,63 e2 = c2.length - 1;64 // ä»åå¾å65 while (i <= e1 && i <= e2) {66 const n1 = c1[i], n2 = c2[i];67 if (isSameVnodeType(n1, n2)) {68 patch(n1, n2, el)69 } else {70 break;71 }72 i++;73 }74 // ä»åå¾å75 // abc76 // dabc77 while (i <= e1 && i <= e2) {78 const n1 = c1[e1], n2 = c2[e2];79 if (isSameVnodeType(n1, n2)) {80 patch(n1, n2, el)81 } else {82 break;83 }84 e1--;85 e2--;86 }87 // åªèèå
ç´ æ°å¢åå é¤çæ
åµ88 // abc=>abcd (i=3,e1=2,e2=3) abc=>dabc (i=0 e1=-1 e2=0)89 // è§å¾ï¼åªè¦i>e1 æ°å¢å
ç´ 90 if (i > e1) {91 // æ°å¢é¨å92 if (i <= e2) {93 // æ ¹æ®e2çä¸ä¸ä¸ªå
ç´ åæ°ç»é¿åº¦æ¯è¾94 const nextPos = e2 + 1;95 const anchor = nextPos < c2.length ? c2[nextPos].el : null;96 while (i <= e2) {97 patch(null, c2[i], el, anchor);98 i++;99 }100 }101 } else if (i > e2) {// abcd=>abc (i=3,e1=3,e2=2) å é¤èç¹102 while (i <= e1) {103 hostRemove(c1[i].el)104 i++;105 }106 } else {107 // æ è§å¾æ
åµ108 const s1 = i, s2 = i;109 // æ°ç´¢å¼åkeyçä¸ä¸ªæ å°110 const keyToNewIndexMap = new Map();111 for (let i = s2; i < e2; i++) {112 const nextchild = c2[i];113 keyToNewIndexMap.set(nextchild.key, i);114 }115 console.log(keyToNewIndexMap)116 const toBePatched = e2 - s2 + 1;117 const newIndexToOldMapIndex = new Array(toBePatched).fill(0);118 for (let i = s1; i <= e1; i++) {119 const prevChild = c1[i];120 let newIndex = keyToNewIndexMap.get(prevChild.key);121 if (newIndex == undefined) {122 // å é¤123 hostRemove(prevChild.el)124 } else {125 newIndexToOldMapIndex[newIndex - s2] = i + 1;126 patch(prevChild, c2[newIndex], el)127 }128 }129 // æé¿å¢é¿åºå130 const increasingIndexSequence=getSequence(newIndexToOldMapIndex);131 let j=increasingIndexSequence.length-1;132 for (let i = toBePatched - 1; i >= 0; i--) {133 const nextIndex = s2 + i;134 const nextChild = c2[nextIndex];135 const anchor = nextIndex + 1 < c2.length ? c2[nextIndex + 1].el : null;// å½åå
ç´ çä¸ä¸ä¸ªå
ç´ 136 if (newIndexToOldMapIndex[i] === 0) {// è¿æ¯æ°å
ç´ ï¼ç´æ¥æå
¥137 patch(null, nextChild, el, anchor)138 } else {139 // ä¸é¢æ¹å¼éè¦åå¤ç§»å¨å
ç´ ï¼æ§è½è¾å·®ï¼å¯åèå®æ¹ä¼åæ段 å©ç¨render.tsä¸çgetSequenceæ¹æ³140 // hostInsert(nextChild.el, el, anchor)141 // æç
§vue3æºç å®ç°142 if(j<0 || i!=increasingIndexSequence[j]){143 hostInsert(nextChild.el, el, anchor)144 }else{145 j--146 }147 }148 }149 }150 }151 const patchChildren = (n1, n2, el) => {152 const c1 = n1.children,153 c2 = n2.children;154 const prevShapeFlag = n1.shapeFlag,155 shapeFlag = n2.shapeFlag;156 // èèç¹æ¯ææ¬ï¼æ°èç¹ä¹æ¯ææ¬ï¼ç´æ¥è¦ç157 // èèç¹æ¯æ°ç»ï¼æ°èç¹æ¯ææ¬ï¼ç´æ¥è¦ç158 if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {159 if (c2 !== c1) {160 hostSetElementText(el, c2)161 }162 } else {163 // èèç¹æ¯æ°ç»ï¼æ°èç¹æ¯æ°ç»ï¼ååæ°ç»diff164 if (prevShapeFlag & ShapeFlags.ARRAY_CHILDREN) {165 console.log('æ ¸å¿diff')166 patchKeydChildren(c1, c2, el)167 } else {168 // èèç¹æ¯ææ¬ï¼æ°èç¹æ¯æ°ç»169 if (prevShapeFlag & ShapeFlags.TEXT_CHILDREN) {170 // 移é¤èçææ¬171 hostSetElementText(el, '')172 }173 if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {174 // æå
¥æ°çæ°ç»175 for (let i = 0; i < c2.length; i++) {176 patch(null, c2[i], el)177 }178 }179 }180 }181 }182 const patchElement = (n1, n2, container) => {183 console.log('å
ç´ æ´æ°')184 let el = (n2.el = n1.el);185 const oldProps = n1.props || {};186 const newProps = n2.props || {};187 patchProps(oldProps, newProps, el);188 patchChildren(n1, n2, el)189 }190 const processElement = (n1, n2, container, anchor) => {191 if (n1 === null) {192 // å次渲ææè½½193 mountElement(n2, container, anchor)194 } else {195 // æ´æ°196 patchElement(n1, n2, container, anchor)197 }198 }199 const processComponent = (n1, n2, container) => {200 if (n1 === null) {201 // å次渲ææè½½202 mountComponent(n2, container)203 } else {204 // æ´æ°205 updateComponent(n1, n2, container)206 }207 }208 // ç»ä»¶mount209 const mountComponent = (initialVnode, container) => {210 // æ¥éª¤ï¼1ãå建ç»ä»¶å®ä¾ã2ãæ¾å°ç»ä»¶renderæ¹æ³3ãæ§è¡render211 const instance = initialVnode.component = createComponentInstance(initialVnode);212 setupComponent(instance)213 // ç»ç»ä»¶å建ä¸ä¸ªeffectï¼ç¨äºæ¸²æ,类似äºvue2 ä¸æ¸²æwatcher214 setupRenderEffect(instance, initialVnode, container)215 }216 // ç»ä»¶æ´æ°217 const updateComponent = (n1, n2, container) => {218 console.log('ç»ä»¶æ´æ°')219 }220 const setupRenderEffect = (instance, initialVnode, container) => {221 effect(function componentEffect() {222 if (!instance.isMounted) {223 // ä¿å渲æç»ä»¶ç»æå°subTree224 const subTree = instance.subTree = instance.render();225 patch(null, subTree, container)226 instance.isMounted = true;227 } else {228 // æ´æ°æä½229 let prev = instance.subTree;230 let next = instance.render();231 patch(prev, next, container)232 }233 })234 }235 const isSameVnodeType = (n1, n2) => {236 return n1.type === n2.type && n1.key === n2.key;237 }238 const patch = (n1, n2, container, anchor = null) => {239 const { shapeFlag } = n2;240 if (n1) {241 if (isSameVnodeType(n1, n2)) {242 // èç¹ç¸åï¼å¯ä»¥å¤ç¨243 console.log('å¤ç¨')244 } else {245 // èç¹ç±»åä¸å246 hostRemove(n1.el);247 n1 = null;248 }249 }250 if (shapeFlag & ShapeFlags.ELEMENT) {251 console.log('å
ç´ èç¹', container)252 processElement(n1, n2, container, anchor)253 } else if (shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {254 console.log('ç»ä»¶', container)255 processComponent(n1, n2, container)256 }257 }258 const render = (vnode, container) => {259 console.log('渲æå¨', vnode, container)260 patch(null, vnode, container)261 }262 return {263 createApp: createApp(render)264 }265}266// vue3 æºç ä¸å®ç°ï¼packages/runtime-core/src/renderer.ts267// https://en.wikipedia.org/wiki/Longest_increasing_subsequence268function getSequence(arr){269 const p = arr.slice()270 const result = [0]271 let i, j, u, v, c272 const len = arr.length273 for (i = 0; i < len; i++) {274 const arrI = arr[i]275 if (arrI !== 0) {276 j = result[result.length - 1]277 if (arr[j] < arrI) {278 p[i] = j279 result.push(i)280 continue281 }282 u = 0283 v = result.length - 1284 while (u < v) {285 c = ((u + v) / 2) | 0286 if (arr[result[c]] < arrI) {287 u = c + 1288 } else {289 v = c290 }291 }292 if (arrI < arr[result[u]]) {293 if (u > 0) {294 p[i] = result[u - 1]295 }296 result[u] = i297 }298 }299 }300 u = result.length301 v = result[u - 1]302 while (u-- > 0) {303 result[u] = v304 v = p[v]305 }306 return result...
index.js
Source: index.js
1/**2 * 3 * vdom èæèç¹4 * old èçèç¹5 * new æ°çèç¹6 * 7 * 8 * mountElement æ°å¢å
ç´ 9 * patch å¤ç¨å
ç´ 10 * unmoubt å é¤å
ç´ 11 * move å
ç´ ç§»å¨12 * 13 * @param {*} c1 14 * @param {*} c2 15 * @param {*} param2 16 */17exports.diffArray = (c1, c2, { mountElement, patch, unmount, move }) => {18 // é»è®¤åä¸å±çº§19 function isSameVnodeType(n1, n2) {20 return n1.key === n2.key // && n1.type === n2.type 21 }22 let l1 = c1.length // èèç¹çé¿åº¦23 let l2 = c2.length // æ°èç¹çé¿åº¦24 let i = 025 let e1 = l1 - 1 // èèç¹æåä¸ä¸ªèç¹çç´¢å¼26 let e2 = l2 - 1 // æ°èç¹æåä¸ä¸ªèç¹çç´¢å¼27 // 1. ä»å·¦è¾¹æ¥æ¾ 28 while (i <= e1 && i <= e2) {29 const n1 = c1[i]30 const n2 = c2[i]31 if (isSameVnodeType(n1, n2)) {32 patch(n1.key)33 } else {34 break35 }36 i++37 }38 // 2. ä»å³è¾¹å¼å§æ¥æ¾39 while (i <= e1 && i <= e2) {40 const n1 = c1[e1]41 const n2 = c2[e2]42 if (isSameVnodeType(n1, n2)) {43 patch(n1.key)44 } else {45 break46 }47 e1--48 e2--49 }50 // 3. èèç¹æ²¡æäºï¼ æ°èç¹å¨ åæ°å¢51 if (i > e1) {52 if (i <= e2) {53 while (i <= e2) {54 const n2 = c2[i]55 mountElement(n2.key)56 i++57 }58 }59 }60 // 4. èèç¹åå¨ æ°èç¹æ²¡æ å移é¤61 else if (i > e2) {62 if (i <= e1) {63 while (i <= e1) {64 const n1 = c1[i]65 unmount(n1.key)66 i++67 }68 }69 }70 // 5. æ°èèç¹é½æï¼ é¡ºåºä¸ç¨³å®71 else {72 const s1 = i73 const s2 = i74 // å©ä¸çå°±æ¯ä¸é´ä¹±åºçæ°ç»è¿è¡å¯¹æ¯ï¼75 // 1.æ´åè§£æ³ ååééå æ¶é´å¤æ度 O(n)76 // 2.æ建ä¸ä¸ªmapæ å°è¡¨ æ¯æ¬¡éåèçèç¹å»è¿ä¸ªæ å°è¡¨ä¸å»æ¥æ¾77 const keyToNewIndexMap = new Map()78 // {79 // e: 2,80 // c: 3,81 // d: 4, 82 // h: 583 // }84 for (i = s2; i <= e2; i++) {85 const nextChild = c2[i]86 keyToNewIndexMap.set(nextChild.key, i)87 }88 // è®°å½æ°èç¹æå¤å°ä¸ªéè¦å¤ç89 const toBePatched = e2 - s2 + 190 let patched = 091 // æ建ä¸ä¸ªæ°ç»è®°å½ä¸ä¸èçèç¹å¨æ°èç¹ä¸çä½ç½®92 const newIndexToOldIndexMap = new Array(toBePatched)93 // æ°ç»çä¸æ è®°å½çæ¯æ°å
ç´ çç¸å¯¹ä¸æ 94 // æ°æ®çå¼å¦ææ¯0 è¯æè¿ä¸ªå¼æ¯éè¦æ°å¢ç95 // [5, 3, 4, 0]96 for (let i = 0; i < toBePatched; i++) {97 newIndexToOldIndexMap[i] = 098 }99 let moved = false100 let maxNewIndexSoFar = 0101 // éåèèç¹ï¼ å»mapå¾ä¸æ¥æ¾èç¹ï¼ç¡®å®æ¯å¤ç¨è¿æ¯å é¤102 for (i = s1; i <= e1; i++) {103 const prevChild = c1[i]104 // newIndex èèç¹å¨æ°èç¹ä¸å¯¹åºçç´¢å¼105 const newIndex = keyToNewIndexMap.get(prevChild.key)106 // å¦æèçèç¹å¨mapå¾ä¸æ²¡ææ¾å°ï¼è¯´æè¿ä¸ªèç¹éè¦ç§»é¤107 if (newIndex === undefined) {108 unmount(prevChild.key)109 } else {110 // maxNewIndexSoFarè®°å½éä¼æåä¸ä¸ªå
ç´ çä¸æ 111 if (newIndex >= maxNewIndexSoFar) {112 maxNewIndexSoFar = newIndex113 } else {114 moved = true115 }116 // å¦æèçèç¹å¨mapå¾ä¸æ¾å°äºï¼å说æè¿ä¸ªèç¹å¯ä»¥å¤ç¨117 newIndexToOldIndexMap[newIndex - s2] = i + 1118 patch(prevChild.key)119 patched++120 }121 }122 // éåæ°å
ç´ ç¡®å®æ¯æ°å¢è¿æ¯ç§»å¨123 // è·åæé¿éå¢ååºå124 // [1,2]125 const increasingNewIndexSequence = moved ? getSequence(newIndexToOldIndexMap) : []126 let lastIndex = increasingNewIndexSequence.length - 1127 for (i = toBePatched - 1; i >= 0; i--) {128 // iæ¯ææ°å
ç´ çç¸å¯¹ä¸æ 129 const newChild = c2[s2 + i]130 // å¤æèç¹æ¯æ°å¢è¿æ¯ç§»å¨131 if (newIndexToOldIndexMap[i] === 0) {132 mountElement(newChild.key)133 } else {134 if (lastIndex < 0 || i !== increasingNewIndexSequence[lastIndex]) {135 move(newChild.key)136 } else {137 lastIndex--138 }139 }140 }141 }142 // è¿åä¸éè¦ç§»å¨çèç¹143 // å¾å°æé¿éå¢ååºålisï¼ç®æ³+å®é
åºç¨ï¼è·³è¿0ï¼ï¼è¿åè·¯å¾144 function getSequence(arr) {145 // return [1, 2];146 // æé¿éå¢ååºåè·¯å¾, æåºéå¢147 const lis = [0];148 // ç¸å½äºå¤å¶ä¸ä»½arræ°ç»ï¼æ¤æ°ç»ç¨äºç¨åçº æ£lisç¨ç149 const recordIndexOfI = arr.slice();150 const len = arr.length;151 for (let i = 0; i < len; i++) {152 const arrI = arr[i];153 // å¦æå
ç´ å¼ä¸º0ï¼è¯æèç¹æ¯æ°å¢çï¼èdomä¸æ²¡æï¼è¯å®ä¸éè¦ç§»å¨ï¼æ以跳è¿0ï¼ä¸å¨lisé154 if (arrI !== 0) {155 // å¤æarrIæå
¥å°lisåªé156 const last = lis[lis.length - 1];157 // arrIæ¯lisæåä¸ä¸ªå
ç´ è¿å¤§ï¼åæææé¿éå¢158 if (arr[last] < arrI) {159 // è®°å½ç¬¬i次çæ¶åï¼æ¬æ¥çå
ç´ æ¯ä»ä¹ï¼åé¢è¦åå溯ç160 recordIndexOfI[i] = last;161 lis.push(i);162 continue;163 }164 // äºåæ¥æ¾æå
¥å
ç´ 165 let left = 0,166 right = lis.length - 1;167 while (left < right) {168 const mid = (left + right) >> 1;169 // 0 1 2 3 4 (1.5)170 if (arr[lis[mid]] < arrI) {171 // mid< ç®æ å
ç´ ï¼ å¨å³è¾¹172 left = mid + 1;173 } else {174 right = mid;175 }176 }177 if (arrI < arr[lis[left]]) {178 // ä»lisä¸æ¾å°äºæ¯arrI大çå
ç´ éæå°çé£ä¸ªï¼å³arr[lis[left]]ã179 // å¦åå没ææ¾å°æ¯arrI大çå
ç´ ï¼å°±ä¸éè¦åä»ä¹äº180 if (left > 0) {181 // è®°å½ç¬¬i次çæ¶åï¼ä¸æ¬¡çå
ç´ çæ¯ä»ä¹ï¼ä¾¿äºåé¢å溯182 recordIndexOfI[i] = lis[left - 1];183 }184 lis[left] = i;185 }186 }187 }188 // éålisï¼çº æ£ä½ç½®189 let i = lis.length;190 let last = lis[i - 1];191 while (i-- > 0) {192 lis[i] = last;193 last = recordIndexOfI[last];194 }195 return lis;196 }...
longestIncreasingSubsequence.js
Source: longestIncreasingSubsequence.js
...17 * å¤æ两个èç¹æ¯å¦ç¸å key å type18 * @param {*} n119 * @param {*} n220 */21 function isSameVNodeType(n1, n2) {22 // n1.key === n2.key && n1.type === n2.type;23 // è¿éåªæ¨¡æ key24 return n1.key === n2.key25 }26 let i = 027 // æ°å
ç´ é¿åº¦28 const l2 = c2.length29 // æåä¸ä¸ªèå
ç´ èç¹ä¸æ 30 let e1 = c1.length - 131 // æåä¸ä¸ªæ°å
ç´ èç¹ä¸æ 32 let e2 = l2 - 133 // 1. 左边æåºæ¥æ¾ï¼ å¦æèç¹ä¸è½å¤ç¨ï¼ååæ¢34 while (i <= e1 && i <= e2) {35 const n1 = c1[i]36 const n2 = c2[i]37 if (isSameVNodeType(n1, n2)) {38 patch(n1.key)39 } else {40 break41 }42 i++43 }44 // 2. å³è¾¹æåºæ¥æ¾ï¼å¦æèç¹ä¸è½å¤ç¨ï¼ååæ¢45 while (i <= e1 && i <= e2) {46 const n1 = c1[e1]47 const n2 = c2[e2]48 if (isSameVNodeType(n1, n2)) {49 patch(n1.key)50 } else {51 break52 }53 e1--54 e2--55 }56 // 3. èèç¹æ²¡äº57 if (i > e1) {58 // æ°èç¹è¿æ, ææ°èç¹æè½½å°èèç¹59 if (i <= e2) {60 while (i <= e2) {61 const n2 = c2[i]62 mountElement(n2.key)...
vue-diff.js
Source: vue-diff.js
1// dom2// old array a b c d e f g3// new array a b e c d h f g4// mountElement æ°å¢å
ç´ h5// patch å¤ç¨å
ç´ a b c d e f g6// unmount å é¤å
ç´ 7// todo8// move å
ç´ ç§»å¨ ?9exports.diffArray = (c1, c2, { mountElement, patch, unmount, move }) => {10 function isSameVnodeType(n1, n2) {11 return n1.key === n2.key; //&& n1.type === n2.type;12 }13 let i = 0;14 const l1 = c1.length;15 const l2 = c2.length;16 let e1 = l1 - 1;17 let e2 = l2 - 1;18 // *1. ä»å·¦è¾¹å¾å³æ¥æ¾ï¼å¦æèç¹å¯ä»¥å¤ç¨ï¼å继ç»å¾å³ï¼ä¸è½å°±åæ¢å¾ªç¯19 while (i <= e1 && i <= e2) {20 const n1 = c1[i];21 const n2 = c2[i];22 if (isSameVnodeType(n1, n2)) {23 patch(n1.key);24 } else {25 break;26 }27 i++;28 }29 // *2. ä»å³è¾¹å¾å·¦è¾¹æ¥æ¾ï¼å¦æèç¹å¯ä»¥å¤ç¨ï¼å继ç»å¾å·¦ï¼ä¸è½å°±åæ¢å¾ªç¯30 while (i <= e1 && i <= e2) {31 const n1 = c1[e1];32 const n2 = c2[e2];33 if (isSameVnodeType(n1, n2)) {34 patch(n1.key);35 } else {36 break;37 }38 e1--;39 e2--;40 }41 // *3.1 èèç¹æ²¡äºï¼æ°èç¹è¿æ42 if (i > e1) {43 if (i <= e2) {44 while (i <= e2) {45 const n2 = c2[i];46 mountElement(n2.key);47 i++;48 }49 }50 }51 // *3.2 èèç¹è¿æï¼æ°èç¹æ²¡äº52 else if (i > e2) {53 while (i <= e1) {54 const n1 = c1[i];55 unmount(n1.key);56 i++;57 }58 } else {59 // *4 æ°èèç¹é½æï¼ä½æ¯é¡ºåºä¸ç¨³å®60 // éåæ°èèç¹61 // iæ¯æ°èå
ç´ çèµ·å§ä½ç½®62 // *4.1 ææ°å
ç´ åæMapå¾ï¼key: value(index)63 const s1 = i;64 const s2 = i;65 //66 const keyToNewIndexMap = new Map();67 for (i = s2; i <= e2; i++) {68 const nextChild = c2[i];69 keyToNewIndexMap.set(nextChild.key, i);70 }71 // *4.2 å½åè¿æå¤å°æ°å
ç´ è¦è¢«patch(æ°å¢ãæ´æ°)72 const toBePatched = e2 - s2 + 1;73 let patched = 0;74 const newIndexToOldIndexMap = new Array(toBePatched);75 // ä¸æ æ¯æ°å
ç´ çç¸å¯¹ä¸æ ï¼å¼æ¯èå
ç´ çä¸æ +176 for (i = 0; i < toBePatched; i++) {77 newIndexToOldIndexMap[i] = 0;78 }79 // *4.3 å
éåèå
ç´ æ£æ¥èå
ç´ æ¯å¦è¦è¢«å¤ç¨ï¼å¦æå¤ç¨å°±patchï¼å¦æä¸è½å¤ç¨å°±å é¤80 let moved = false;81 let maxNewIndexSoFar = 0;82 for (i = s1; i <= e1; i++) {83 const prevChild = c1[i];84 if (patched >= toBePatched) {85 unmount(prevChild.key);86 continue;87 }88 const newIndex = keyToNewIndexMap.get(prevChild.key);89 if (newIndex === undefined) {90 // èç¹æ²¡æ³å¤ç¨91 unmount(prevChild.key);92 } else {93 //移å¨åçå¨è¿éï¼è¿éçèç¹å¯è½è¦è¢«ç§»å¨ï¼ecdï¼94 if (newIndex >= maxNewIndexSoFar) {95 maxNewIndexSoFar = newIndex;96 } else {97 // ç¸å¯¹ä½ç½®åçåå98 moved = true;99 }100 newIndexToOldIndexMap[newIndex - s2] = i + 1;101 patch(prevChild.key);102 patched++;103 }104 }105 // *4.4 éåæ°å
ç´ mount move106 // è¿åä¸éè¦ç§»å¨çèç¹107 const increasingNewIndexSequece = moved108 ? getSequence(newIndexToOldIndexMap)109 : [];110 let lastIndex = increasingNewIndexSequece.length - 1;111 // ç¸å¯¹ä¸æ 112 for (i = toBePatched - 1; i >= 0; i--) {113 const nextChildIndex = s2 + i;114 const nextChild = c2[nextChildIndex];115 // å¤ænextChildæ¯mountè¿æ¯move116 // å¨èå
ç´ ä¸åºç°çå
ç´ å¯è½è¦moveï¼æ²¡æåºç°è¿çè¦mount117 if (newIndexToOldIndexMap[i] === 0) {118 mountElement(nextChild.key);119 } else {120 // å¯è½move121 if (lastIndex < 0 || i !== increasingNewIndexSequece[lastIndex]) {122 move(nextChild.key);123 } else {124 lastIndex--;125 }126 }127 }128 }129 // è¿åä¸éè¦ç§»å¨çèç¹130 // å¾å°æé¿éå¢ååºålisï¼ç®æ³+å®é
åºç¨ï¼è·³è¿0ï¼ï¼è¿åè·¯å¾131 function getSequence(arr) {132 // return [1, 2];133 // æé¿éå¢ååºåè·¯å¾, æåºéå¢134 const lis = [0];135 // ç¸å½äºå¤å¶ä¸ä»½arræ°ç»ï¼æ¤æ°ç»ç¨äºç¨åçº æ£lisç¨ç136 const recordIndexOfI = arr.slice();137 const len = arr.length;138 for (let i = 0; i < len; i++) {139 const arrI = arr[i];140 // å¦æå
ç´ å¼ä¸º0ï¼è¯æèç¹æ¯æ°å¢çï¼èdomä¸æ²¡æï¼è¯å®ä¸éè¦ç§»å¨ï¼æ以跳è¿0ï¼ä¸å¨lisé141 if (arrI !== 0) {142 // å¤æarrIæå
¥å°lisåªé143 const last = lis[lis.length - 1];144 // arrIæ¯lisæåä¸ä¸ªå
ç´ è¿å¤§ï¼åæææé¿éå¢145 if (arr[last] < arrI) {146 // è®°å½ç¬¬i次çæ¶åï¼æ¬æ¥çå
ç´ æ¯ä»ä¹ï¼åé¢è¦åå溯ç147 recordIndexOfI[i] = last;148 lis.push(i);149 continue;150 }151 // äºåæ¥æ¾æå
¥å
ç´ 152 let left = 0,153 right = lis.length - 1;154 while (left < right) {155 const mid = (left + right) >> 1;156 // 0 1 2 3 4 (1.5)157 if (arr[lis[mid]] < arrI) {158 // mid< ç®æ å
ç´ ï¼ å¨å³è¾¹159 left = mid + 1;160 } else {161 right = mid;162 }163 }164 if (arrI < arr[lis[left]]) {165 // ä»lisä¸æ¾å°äºæ¯arrI大çå
ç´ éæå°çé£ä¸ªï¼å³arr[lis[left]]ã166 // å¦åå没ææ¾å°æ¯arrI大çå
ç´ ï¼å°±ä¸éè¦åä»ä¹äº167 if (left > 0) {168 // è®°å½ç¬¬i次çæ¶åï¼ä¸æ¬¡çå
ç´ çæ¯ä»ä¹ï¼ä¾¿äºåé¢å溯169 recordIndexOfI[i] = lis[left - 1];170 }171 lis[left] = i;172 }173 }174 }175 // éålisï¼çº æ£ä½ç½®176 let i = lis.length;177 let last = lis[i - 1];178 while (i-- > 0) {179 lis[i] = last;180 last = recordIndexOfI[last];181 }182 return lis;183 }...
vue_diff.js
Source: vue_diff.js
1// dom2// old array a b c d e f g3// new array a b e c d h f g4// mountElement æ°å¢å
ç´ h5// patch å¤ç¨å
ç´ a b c d e f g6// unmount å é¤å
ç´ 7// todo8// move å
ç´ ç§»å¨ ?9exports.diffArray = (c1, c2, { mountElement, patch, unmount, move }) => {10 function isSameVnodeType(n1, n2) {11 return n1.key === n2.key; // && n1.type === n2.type12 }13 let i = 0;14 const l1 = c1.lenght;15 const l2 = c2.length;16 let e1 = l1 - 1; // å°¾é¨åæ 17 let e2 = l2 - 1;18 // 1. ä»å·¦å¾å³æ¥æ¾å¤ç¨å
ç´ ï¼æ头ï¼19 while (i <= e1 && i <= e2) {20 const n1 = c1[i];21 const n2 = c2[i];22 if (isSameVnodeType(n1, n2)) {23 patch(n1.key);24 } else {25 break;26 }27 i++;28 }29 // 2. ä»å³å¾å·¦æ¥æ¾å¤ç¨å
ç´ ï¼å»å°¾ï¼30 while (i <= e1 && i <= e2) {31 const n1 = c1[i];32 const n2 = c2[i];33 if (isSameVnodeType(n1, n2)) {34 patch(n1.key);35 } else {36 break;37 }38 e1--;39 e2--;40 }41 // 3.1 èèç¹éåå®æ¯ï¼è¿ææ°èç¹42 if (i > e1) {43 if (i <= e2) {44 while (i <= e2) {45 const n2 = c2[i];46 mountElement(n2.key);47 i++;48 }49 }50 }51 // 3.2 æ°èç¹éåå®æ¯è¿æèèç¹52 else if (i > e2) {53 if (i <= e1) {54 while (i <= e1) {55 const n1 = c1[i];56 unmount(n1.key);57 i++;58 }59 }60 }61 // 4. æ°èèç¹é½æï¼ä½æ¯é¡ºåºä¸ç¨³å®62 // éåæ°èèç¹63 // i æ¯æ°èèç¹çèµ·å§ä½ç½®64 else {65 // 4.1 éè¦è®°å½ç¸å¯¹ä½ç½®å
³ç³»ï¼å°æ°å
ç´ ä½ä¸ºMapï¼keyï¼value(index)66 const s1 = i;67 const s2 = i;68 const keyToNewIndexMap = new Map();69 for (i = s2; i <= e2; i++) {70 const nextChild = c2[i];71 keyToNewIndexMap.set(nextChild.key, i);72 }73 // è®°å½å½åè¿æå¤å°æ°å
ç´ éè¦è¢«patch74 const toBePatched = e2 - s2 + 1;75 // å½åæ´æ°é76 let patched = 0;77 const newIndexToOldIndexMap = new Array(toBePatched);78 // ä¸æ æ¯æ°å
ç´ çç¸å¯¹ä¸æ ï¼å¼æ¯èå
ç´ çä¸æ +179 for (i = 0; i < toBePatched; i++) {80 newIndexToOldIndexMap[i] = 0;81 }82 // *4.2 å
éåèå
ç´ æ£æ¥èå
ç´ æ¯å¦è¦è¢«å¤ç¨ï¼å¦æå¤ç¨å°±patchï¼å¦æä¸è½å¤ç¨å°±å é¤83 let moved = false;84 let maxNewIndexSoFar = 0;85 for (i = s1; i <= e1; i++) {86 const prevChild = c1[i];87 // å¦æéæä½å
ç´ æä½å®æ¯ï¼åå é¤å©ä½å
ç´ 88 if (patched >= toBePatched) {89 unmount(prevChild.key);90 continue;91 }92 const newIndex = keyToNewIndexMap.get(prevChild.key);93 // æªå¤ç¨94 if (newIndex === undefined) {95 unmount(prevChild.key);96 }97 // å¤ç¨äºåéè¦ç§»å¨98 else {99 if (newIndex >= maxNewIndexSoFar) {100 maxNewIndexSoFar = newIndex;101 } else {102 moved = true;103 }104 newIndexToOldIndexMap[newIndex - s2] = i + 1;105 patch(prevChild.key);106 patched++;107 }108 }109 // 4.3 éåæ°å
ç´ mount move110 // è¿åä¸éè¦ç§»å¨çèç¹111 const increasingNewIndexSequece = moved112 ? getSequence(newIndexToOldIndexMap)113 : [];114 let lastIndex = increasingNewIndexSequece.length - 1;115 // ç¸å¯¹ä¸æ 116 for (i = toBePatched - 1; i >= 0; i--) {117 const nextChildIndex = s2 + i;118 const nextChild = c2[nextChildIndex];119 // å¤ænextChildæ¯mountè¿æ¯move120 // å¨èå
ç´ ä¸åºç°çå
ç´ å¯è½è¦moveï¼æ²¡æåºç°è¿çè¦mount121 if (newIndexToOldIndexMap[i] === 0) {122 mountElement(nextChild.key);123 } else {124 // å¯è½move125 if (lastIndex < 0 || i !== increasingNewIndexSequece[lastIndex]) {126 move(nextChild.key);127 } else {128 lastIndex--;129 }130 }131 }132 }133 // è¿åä¸éè¦ç§»å¨çèç¹134 // å¾å°æé¿éå¢ååºålisï¼ç®æ³+å®é
åºç¨ï¼è·³è¿0ï¼ï¼è¿åè·¯å¾135 function getSequence(arr) {136 // return [1, 2];137 // æé¿éå¢ååºåè·¯å¾, æåºéå¢138 const lis = [0];139 // ç¸å½äºå¤å¶ä¸ä»½arræ°ç»ï¼æ¤æ°ç»ç¨äºç¨åçº æ£lisç¨ç140 const recordIndexOfI = arr.slice();141 const len = arr.length;142 for (let i = 0; i < len; i++) {143 const arrI = arr[i];144 // å¦æå
ç´ å¼ä¸º0ï¼è¯æèç¹æ¯æ°å¢çï¼èdomä¸æ²¡æï¼è¯å®ä¸éè¦ç§»å¨ï¼æ以跳è¿0ï¼ä¸å¨lisé145 if (arrI !== 0) {146 // å¤æarrIæå
¥å°lisåªé147 const last = lis[lis.length - 1];148 // arrIæ¯lisæåä¸ä¸ªå
ç´ è¿å¤§ï¼åæææé¿éå¢149 if (arr[last] < arrI) {150 // è®°å½ç¬¬i次çæ¶åï¼æ¬æ¥çå
ç´ æ¯ä»ä¹ï¼åé¢è¦åå溯ç151 recordIndexOfI[i] = last;152 lis.push(i);153 continue;154 }155 // äºåæ¥æ¾æå
¥å
ç´ 156 let left = 0,157 right = lis.length - 1;158 while (left < right) {159 const mid = (left + right) >> 1;160 // 0 1 2 3 4 (1.5)161 if (arr[lis[mid]] < arrI) {162 // mid< ç®æ å
ç´ ï¼ å¨å³è¾¹163 left = mid + 1;164 } else {165 right = mid;166 }167 }168 if (arrI < arr[lis[left]]) {169 // ä»lisä¸æ¾å°äºæ¯arrI大çå
ç´ éæå°çé£ä¸ªï¼å³arr[lis[left]]ã170 // å¦åå没ææ¾å°æ¯arrI大çå
ç´ ï¼å°±ä¸éè¦åä»ä¹äº171 if (left > 0) {172 // è®°å½ç¬¬i次çæ¶åï¼ä¸æ¬¡çå
ç´ çæ¯ä»ä¹ï¼ä¾¿äºåé¢å溯173 recordIndexOfI[i] = lis[left - 1];174 }175 lis[left] = i;176 }177 }178 }179 // éålisï¼çº æ£ä½ç½®180 let i = lis.length;181 let last = lis[i - 1];182 while (i-- > 0) {183 lis[i] = last;184 last = recordIndexOfI[last];185 }186 return lis;187 }...
diff.js
Source: diff.js
...14 let e2 = c2.length - 1;15 while (i <= e1 && i <= e2) {16 const prevChild = c1[i];17 const nextChild = c2[i];18 if (!isSameVNodeType(prevChild, nextChild)) {19 console.log("两个 child ä¸ç¸ç(ä»å·¦å¾å³æ¯å¯¹)");20 break;21 }22 console.log("两个 child ç¸çï¼æ¥ä¸æ¥å¯¹æ¯ç两个 child èç¹(ä»å·¦å¾å³æ¯å¯¹)");23 patch(prevChild, nextChild, container);24 i++;25 }26 while (i <= e1 && i <= e2) {27 // ä»å³åå·¦åå¼28 const prevChild = c1[e1];29 const nextChild = c2[e2];30 if (!isSameVNodeType(prevChild, nextChild)) {31 console.log("两个 child ä¸ç¸ç(ä»å³å¾å·¦æ¯å¯¹)");32 break;33 }34 console.log("两个 child ç¸çï¼æ¥ä¸æ¥å¯¹æ¯ç两个 child èç¹(ä»å³å¾å·¦æ¯å¯¹)");35 patch(prevChild, nextChild, container);36 e1--;37 e2--;38 }39 if (i > e1 && i <= e2) {40 // å¦ææ¯è¿ç§æ
åµçè¯å°±è¯´æ e2 ä¹å°±æ¯æ°èç¹çæ°é大äºæ§èç¹çæ°é41 // ä¹å°±æ¯è¯´æ°å¢äº vnode42 // åºè¯¥å¾ªç¯ c243 while (i <= e2) {44 console.log(`éè¦æ°å建ä¸ä¸ª vnode: ${c2[i].key}`);...
_v3_patch.js
Source: _v3_patch.js
...11 const n1 = c1[i];12 const n2 = (c2[i] = optimized ?13 cloneIfMounted(c2[i]) :14 normalizeVNode(c2[i]));15 if (isSameVNodeType(n1, n2)) { // type and key are the same.16 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);17 } else {18 break;19 }20 i++;21 }22 // 2. sync from end23 // a (b c)24 // d e (b c)25 while (i <= e1 && i <= e2) {26 const n1 = c1[e1];27 const n2 = (c2[e2] = optimized ?28 cloneIfMounted(c2[e2]) :29 normalizeVNode(c2[e2]));30 if (isSameVNodeType(n1, n2)) { // type and key are the same.31 patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);32 } else {33 break;34 }35 e1--;36 e2--;37 }38 // [Mars] : 2. Compare the head and the tail first.39 // 3. common sequence + mount40 // (a b)41 // (a b) c42 // i = 2, e1 = 1, e2 = 243 // (a b)44 // c (a b)45 // i = 0, e1 = -1, e2 = 046 if (i > e1) {47 if (i <= e2) {48 const nextPos = e2 + 1;49 const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;50 while (i <= e2) {51 // mount new added vnodes not contained in oldChilds.52 patch(null, (c2[i] = optimized ?53 cloneIfMounted(c2[i]) :54 normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);55 i++;56 }57 }58 }59 // 4. common sequence + unmount60 // (a b) c61 // (a b)62 // i = 2, e1 = 2, e2 = 163 // a (b c)64 // (b c)65 // i = 0, e1 = 0, e2 = -166 else if (i > e2) {67 while (i <= e1) {68 unmount(c1[i], parentComponent, parentSuspense, true);69 i++;70 }71 }72 // 5. unknown sequence73 // [i ... e1 + 1]: a b [c d e] f g74 // [i ... e2 + 1]: a b [e d c h] f g75 // i = 2, e1 = 4, e2 = 576 else {77 const s1 = i; // prev starting index78 const s2 = i; // next starting index79 // 5.1 build key:index map for newChildren80 const keyToNewIndexMap = new Map(); // use hashMap, cause it's easy to search an index of a key.81 for (i = s2; i <= e2; i++) {82 const nextChild = (c2[i] = optimized ?83 cloneIfMounted(c2[i]) :84 normalizeVNode(c2[i]));85 if (nextChild.key != null) {86 if (keyToNewIndexMap.has(nextChild.key)) {87 warn$1(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);88 }89 keyToNewIndexMap.set(nextChild.key, i);90 }91 }92 // 5.2 loop through old children left to be patched and try to patch93 // matching nodes & remove nodes that are no longer present94 let j;95 let patched = 0;96 const toBePatched = e2 - s2 + 1;97 let moved = false;98 // used to track whether any node has moved99 let maxNewIndexSoFar = 0;100 // works as Map<newIndex, oldIndex>101 // Note that oldIndex is offset by +1102 // and oldIndex = 0 is a special value indicating the new node has103 // no corresponding old node.104 // used for determining longest stable subsequence105 const newIndexToOldIndexMap = new Array(toBePatched);106 for (i = 0; i < toBePatched; i++)107 newIndexToOldIndexMap[i] = 0;108 for (i = s1; i <= e1; i++) {109 const prevChild = c1[i];110 if (patched >= toBePatched) {111 // all new children have been patched so this can only be a removal112 unmount(prevChild, parentComponent, parentSuspense, true);113 continue;114 }115 let newIndex;116 if (prevChild.key != null) {117 newIndex = keyToNewIndexMap.get(prevChild.key);118 } else {119 // key-less node, try to locate a key-less node of the same type120 for (j = s2; j <= e2; j++) {121 if (newIndexToOldIndexMap[j - s2] === 0 &&122 isSameVNodeType(prevChild, c2[j])) { // type and key are the same.123 newIndex = j;124 break;125 }126 }127 }128 if (newIndex === undefined) {129 unmount(prevChild, parentComponent, parentSuspense, true);130 } else {131 newIndexToOldIndexMap[newIndex - s2] = i + 1; // n:[h,c,d,e] o:[c,d,e,h] -> newIndexToOldIndexMap: [4,1,2,3]132 z if (newIndex >= maxNewIndexSoFar) {133 maxNewIndexSoFar = newIndex;134 } else {135 moved = true;136 }...
Using AI Code Generation
1const { isSameVNodeType } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');2const { createVNode } = require('playwright/lib/server/supplements/recorder/vnode.js');3const vNode1 = createVNode('div', { 'data-test-id': 'test' }, []);4const vNode2 = createVNode('div', { 'data-test-id': 'test' }, []);5const vNode3 = createVNode('div', { 'data-test-id': 'test' }, [createVNode('span', {}, [])]);6const vNode4 = createVNode('div', { 'data-test-id': 'test' }, [createVNode('span', {}, [])]);7const vNode5 = createVNode('div', { 'data-test-id': 'test' }, [createVNode('span', { 'data-test-id': 'test' }, [])]);8const vNode6 = createVNode('div', { 'data-test-id': 'test' }, [createVNode('div', {}, [])]);9const { isSameVNodeType } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');10const { createVNode } = require('playwright/lib/server/supplements/recorder/vnode.js');11const vNode1 = createVNode('div', { 'data-test-id': 'test' }, []);12const vNode2 = createVNode('div', { 'data-test-id': 'test' }, []);13const vNode3 = createVNode('div', { 'data-test-id': 'test' }, [createVNode('span', {}, [])]);
Using AI Code Generation
1const playwright = require('playwright');2const { isSameVNodeType } = require('playwright/lib/server/dom.js');3const { chromium } = require('playwright');4(async () => {5 const browser = await chromium.launch();6 const context = await browser.newContext();7 const page = await context.newPage();8 const htmlElement = await elementHandle._elementHandle._adoptIfNeeded();9 const isSameVNodeTypeResult = await isSameVNodeType(htmlElement, 'h1');10 console.log(isSameVNodeTypeResult);11 await browser.close();12})();
Using AI Code Generation
1const { isSameVNodeType } = require('playwright/lib/server/common/dom.js');2const { parseHTML } = require('playwright/lib/server/common/html.js');3const { parseSelector } = require('playwright/lib/server/common/selectors2.js');4const { Node } = require('playwright/lib/server/common/dom.js');5`;6const document = parseHTML(html);7const { root } = document;8const { firstChild } = root;9const selector = parseSelector('.c');10const { node } = selector.match(root)[0];11console.log(isSameVNodeType(node, firstChild));12console.log(isSameVNodeType(node, node));
Using AI Code Generation
1const { isSameVNodeType } = require('playwright/lib/server/dom.js');2const vNode1 = {3 attributes: { 'data-foo': 'bar' },4};5const vNode2 = {6 attributes: { 'data-foo': 'bar' },7};8const vNode3 = {9 attributes: { 'data-foo': 'bar' },10};11const vNode4 = {12 attributes: { 'data-foo': 'bar' },13};14const vNode5 = {15 attributes: { 'data-foo': 'bar' },16};17const addBtn = await page.$(‘button:has-text(“Add”)’);
Using AI Code Generation
1const { isSameVNodeType } = require('playwright/lib/server/domServer');2const { parse } = require('playwright/lib/server/domParser');3const node1 = parse(`4`);5const node2 = parse(`6`);7console.log(isSameVNodeType(node1, node2));
Using AI Code Generation
1import { isSameVNodeType } from 'playwright/lib/server/dom';2import { Page } from 'playwright';3const page: Page = await browser.newPage();4await page.setContent(`<input type="text" />`);5const input = await page.$('input');6const handle = await input.asElement();7const element = handle._node;8const parent = element.parentElement;9const firstChild = parent.firstChild;10const firstChildHandle = firstChild._elementHandle;11const firstChildElement = firstChildHandle._node;12console.log(isSameVNodeType(element, firstChildElement));13await page.close();14I am trying to implement a method that will allow me to compare 2 elements to see if they are the same element. I am using the method isSameVNodeType() in the Playwright Internal. This method is not exposed to use by Playwright users. I am using this method to compare the element I am trying to find and the element I am trying to compare it to. I am getting the element I am trying to compare to by using page.$eval() to get the first element that matches the selector. This method returns the element as a string. I am getting the element I am trying to find by using page.$() to get the element. This method returns the element as an ElementHandle. I am then using the ElementHandle.asElement() method to get the handle of the element. I am then using the handle._node method to get the element node of the element. I am then using the method isSameVNodeType() to compare the elements. I am getting the result that the elements are not the same. I am not sure why I am getting this result. I am trying to compare the same elements. I am trying to compare the input element and the first child element. I am getting the same result when I compare the input element and the
Jest + Playwright - Test callbacks of event-based DOM library
firefox browser does not start in playwright
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?
Running Playwright in Azure Function
firefox browser does not start in playwright
This question is quite close to a "need more focus" question. But let's try to give it some focus:
Does Playwright has access to the cPicker object on the page? Does it has access to the window object?
Yes, you can access both cPicker and the window object inside an evaluate call.
Should I trigger the events from the HTML file itself, and in the callbacks, print in the DOM the result, in some dummy-element, and then infer from that dummy element text that the callbacks fired?
Exactly, or you can assign values to a javascript variable:
const cPicker = new ColorPicker({
onClickOutside(e){
},
onInput(color){
window['color'] = color;
},
onChange(color){
window['result'] = color;
}
})
And then
it('Should call all callbacks with correct arguments', async() => {
await page.goto(`http://localhost:5000/tests/visual/basic.html`, {waitUntil:'load'})
// Wait until the next frame
await page.evaluate(() => new Promise(requestAnimationFrame))
// Act
// Assert
const result = await page.evaluate(() => window['color']);
// Check the value
})
Check out the latest blogs from LambdaTest on this topic:
Native apps are developed specifically for one platform. Hence they are fast and deliver superior performance. They can be downloaded from various app stores and are not accessible through browsers.
One of the essential parts when performing automated UI testing, whether using Selenium or another framework, is identifying the correct web elements the tests will interact with. However, if the web elements are not located correctly, you might get NoSuchElementException in Selenium. This would cause a false negative result because we won’t get to the actual functionality check. Instead, our test will fail simply because it failed to interact with the correct element.
Smartphones have changed the way humans interact with technology. Be it travel, fitness, lifestyle, video games, or even services, it’s all just a few touches away (quite literally so). We only need to look at the growing throngs of smartphone or tablet users vs. desktop users to grasp this reality.
As part of one of my consulting efforts, I worked with a mid-sized company that was looking to move toward a more agile manner of developing software. As with any shift in work style, there is some bewilderment and, for some, considerable anxiety. People are being challenged to leave their comfort zones and embrace a continuously changing, dynamic working environment. And, dare I say it, testing may be the most ‘disturbed’ of the software roles in agile development.
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!!