Git Product home page Git Product logo

Comments (5)

RubyLouvre avatar RubyLouvre commented on June 3, 2024
function clearRefsAndMounts(queue) {
        queue.forEach(function (el) {
          var arr = el._pendingRefs;
          if (arr) {
            if (el._hasDidMount) {
              return;
          }
            for (var i = 0, n = arr.length; i < n; i += 2) {
              var obj = arr[i];
              var value = arr[i + 1];
              obj.ref(value);
          }
            arr.length = 0;
            if (el.componentDidMount) {
              el.componentDidMount();
              el.componentDidMount = null;
          }
            setTimeout(function () {
              el._pendingCallbacks.splice(0).forEach(function (fn) {
                fn.call(el);
            });
          });
        }
          el._hasDidMount = true;
      });
        queue.length = 0;
    }

一个重要的修正,通过instance._updating立即返回元素

function refreshComponent(instance, mountQueue) {
    // shouldComponentUpdate为false时不能阻止setState/forceUpdate cb的触发
        var dom = instance._currentElement._hostNode;
        if (instance._updating) {
            console.log('正在更新中');
            return dom;
        }
        dom = _refreshComponent(instance, dom, mountQueue);
        instance._forceUpdate = false;

        instance._pendingCallbacks.splice(0).forEach(function (fn) {
            fn.call(instance);
        });
        var f = instance.after;
        if (f) {
            f.splice(0).forEach(function (el) {
                if (el._currentElement._hostNode) {
                    console.log('立即更新');
                    refreshComponent(el, []);
                } else {
                    console.warn('此组件没有_hostNode');
                    console.warn(el);
                }
            });
        }
        return dom;
    }

from anu.

RubyLouvre avatar RubyLouvre commented on June 3, 2024

暂时没有用到的

function sameVnode(a, b) {
  return a.type === b.type && a.key === b.key
}
function patchVnode(lastVnode, nextVnode, args) {
  return updateVnode(lastVnode, nextVnode, lastVnode._hostNode, args[0], args[1])
}
function updateChildren(lastVnode, nextVnode, parentNode, parentContext, mountQueue) {
  let newCh = nextVnode.props.children
  let oldCh = lastVnode.props.children
  let oldStartIdx = 0;
  let newStartIdx = 0;
  let oldEndIdx = oldCh.length - 1;
  let oldStartVnode = oldCh[0];
  let oldEndVnode = oldCh[oldEndIdx];
  let newEndIdx = newCh.length - 1;
  let newStartVnode = newCh[0];
  let newEndVnode = newCh[newEndIdx];
  let oldKeyMap, idxInOld, dom, ref, elmToMove;

  var args = [parentContext, mountQueue]
  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {

    if (sameVnode(oldStartVnode, newStartVnode)) {
      dom = patchVnode(oldStartVnode, newStartVnode, args);
      ref = childNodes[newStartIdx]
      if (dom !== ref) {
        parentNode.replaceChild(dom, ref)
        oldStartVnode._hostNode = dom
      }
      oldStartVnode = oldCh[++oldStartIdx];
      newStartVnode = newCh[++newStartIdx];
    } else if (sameVnode(oldEndVnode, newEndVnode)) {
      dom = patchVnode(oldEndVnode, newEndVnode, args);
      ref = childNodes[newEndIdx]
      if (dom !== ref) {
        parentNode.replaceChild(dom, ref)
        oldEndVnode._hostNode = dom
        // insertDOM(parentNode, dom, ref)
      }
      oldEndVnode = oldCh[--oldEndIdx];
      newEndVnode = newCh[--newEndIdx];
    } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
      //如果新的最后一个等于旧的第一个
      dom = patchVnode(oldStartVnode, newEndVnode, args);
      parentNode.insertBefore(dom, oldStartVnode._hostNode.nextSibling)
      //  api.insertBefore(parentNode, oldStartVnode._hostNode as Node,
      // api.nextSibling(oldEndVnode._hostNode as Node));
      oldStartVnode = oldCh[++oldStartIdx];
      newEndVnode = newCh[--newEndIdx];
    } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
      dom = patchVnode(oldEndVnode, newStartVnode, args);
      parentNode.insertBefore(oldEndVnode._hostNode, oldStartVnode._hostNode);
      oldEndVnode = oldCh[--oldEndIdx];
      newStartVnode = newCh[++newStartIdx];
    } else {
      if (oldKeyMap === undefined) {
        oldKeyMap = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
      }
      idxInOld = oldKeyMap[newStartVnode.key];
      if (isUndef(idxInOld)) { // New element
        dom = mountVnode(newStartVnode, parentContext, null, mountQueue)
        parentNode.insertBefore(dom, oldStartVnode._hostNode);
        newStartVnode = newCh[++newStartIdx];
      } else {
        elmToMove = oldCh[idxInOld];
        if (elmToMove.type !== newStartVnode.type) {
          dom = mountVnode(newStartVnode, parentContext, null, mountQueue)
          parentNode.insertBefore(parentNode, dom, oldStartVnode._hostNode);
        } else {
          patchVnode(elmToMove, newStartVnode, mountQueue);
          oldCh[idxInOld] = undefined;
          parentNode.insertBefore(parentNode, (elmToMove._hostNode), oldStartVnode._hostNode);
        }
        newStartVnode = newCh[++newStartIdx];
      }
    }
  }
  if (oldStartIdx > oldEndIdx) {
    let before = newCh[newEndIdx + 1] == null
      ? null
      : newCh[newEndIdx + 1]._hostNode;
    addVnodes(parentNode, before, newCh, newStartIdx, newEndIdx, mountQueue);
  } else if (newStartIdx > newEndIdx) {
    removeVnodes(parentNode, oldCh, oldStartIdx, oldEndIdx);
  }
}

function createKeyToOldIdx(children, beginIdx, endIdx) {
  let map = {}
  for (let i = beginIdx; i <= endIdx; ++i) {
    let ch = children[i];
    key = ch.key;
    if (key !== undefined) {
      map[key] = i;
    }
  }
  return map;
}

function addVnodes(parentElm, before, vnodes, startIdx, endIdx, parentContext, mountQueue) {
  for (; startIdx <= endIdx; ++startIdx) {
    const ch = vnodes[startIdx];
    dom = mountVnode(newStartVnode, parentContext, null, mountQueue)
    parentElm.insertBefore(dom, before);
  }
}

from anu.

RubyLouvre avatar RubyLouvre commented on June 3, 2024
import { document, win } from "./browser";
//innerMap_start
var innerMap = win.Map;

function getID(a) {
  if (a.uniqueID) {
    return "Node" + a.uniqueID;
  } else {
    a.uniqueID = "_" + uniqueID++;
    return "Node" + a.uniqueID;
  }
}

try {
  var testNode = document.createComment("");
  var map = new innerMap(),
    value = "anujs";
  map.set(testNode, value);
  if (map.get(testNode) !== value) {
    throw "使用自定义Map";
  }
} catch (e) {
  var uniqueID = 1;
  innerMap = function() {
    this.map = {};
  };
  innerMap.prototype = {
    get: function(a) {
      var id = getID(a);
      return this.map[id];
    },
    set: function(a, v) {
      var id = getID(a);
      this.map[id] = v;
    },
    delete: function(a) {
      var id = getID(a);
      delete this.map[id];
    }
  };
}
//innerMap_end
export var instanceMap = new innerMap();

整个被废掉

from anu.

RubyLouvre avatar RubyLouvre commented on June 3, 2024
import { options, typeNumber } from "./util";

if (0 === [1, 2].splice(0).length) {
  console.warn("请引入polyfill进行修复"); // eslint-disable-line
}

export var scheduler = {
  list: [],
  add: function (el) {
    this.count = this.list.push(el);
  },
  addAndRun: function (fn) {
    this.add(fn);
    setTimeout(function () {
      scheduler.run();
    }, 0);
  },
  run: function () {
    if (this.count === 0) return;
    this.count = 0;
    this.list.splice(0).forEach(function (instance) {
      if (typeNumber(instance) === 5) {
        instance(); //处理ref方法
        return;
      }
      if (instance._pendingCallbacks.length) {
        //处理componentWillMount产生的回调
        instance._pendingCallbacks.splice(0).forEach(function (fn) {
          fn.call(instance);
        });
      }
      if (instance.componentDidMount) {
        instance._updating = true;
        instance.componentDidMount();
        instance.componentDidMount = instance._updating = false;
        instance._hasDidMount = true;
        //处理componentDidMount里调用 setState产生重绘
        if (instance._pendingStates.length && !instance._disableSetState) {
          options.refreshComponent(instance);
        }
      }
    });
  }
};

scheduler模块被整个废掉

from anu.

RubyLouvre avatar RubyLouvre commented on June 3, 2024
function sameVnode(a, b) {
    return a.type === b.type && a.key === b.key
}
function patchVnode(lastVnode, nextVnode, args) {
    return updateVnode(lastVnode, nextVnode, lastVnode._hostNode, args[0], args[1])
}
function updateChildren(lastVnode, nextVnode, parentNode, parentContext, mountQueue) {
    let newCh = nextVnode.props.children
    let oldCh = lastVnode.props.children
    let oldStartIdx = 0;
    let newStartIdx = 0;
    let oldEndIdx = oldCh.length - 1;
    let oldStartVnode = oldCh[0];
    let oldEndVnode = oldCh[oldEndIdx];
    let newEndIdx = newCh.length - 1;
    let newStartVnode = newCh[0];
    let newEndVnode = newCh[newEndIdx];
    let keyMap, idxInOld, dom, ref, elmToMove;

    var args = [parentContext, mountQueue]
    while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {

        if (sameVnode(oldStartVnode, newStartVnode)) {
            dom = patchVnode(oldStartVnode, newStartVnode, args);
            ref = childNodes[newStartIdx]
            if (dom !== ref) {
                parentNode.replaceChild(dom, ref)
            }
            oldStartVnode = oldCh[++oldStartIdx];
            newStartVnode = newCh[++newStartIdx];
        } else if (sameVnode(oldEndVnode, newEndVnode)) {
            dom = patchVnode(oldEndVnode, newEndVnode, args);
            ref = childNodes[newEndIdx]
            if (dom !== ref) {
                parentNode.replaceChild(dom, ref)
            }
            oldEndVnode = oldCh[--oldEndIdx];
            newEndVnode = newCh[--newEndIdx];
        } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
            //如果新的最后一个等于旧的第一个
            dom = patchVnode(oldStartVnode, newEndVnode, args);
            parentNode.insertBefore(dom, oldStartVnode._hostNode.nextSibling)
            oldStartVnode = oldCh[++oldStartIdx];
            newEndVnode = newCh[--newEndIdx];
        } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
            dom = patchVnode(oldEndVnode, newStartVnode, args);
            parentNode.insertBefore(oldEndVnode._hostNode, oldStartVnode._hostNode);
            oldEndVnode = oldCh[--oldEndIdx];
            newStartVnode = newCh[++newStartIdx];
        } else {
            if (keyMap === void 666) {
                keyMap = createKeyMap(oldCh, oldStartIdx, oldEndIdx);
            }
            var arr = oldKeyMap[newStartVnode.key];
            if (arr === void 666) { // New element
                dom = mountVnode(newStartVnode, parentContext, null, mountQueue)
                parentNode.insertBefore(dom, oldStartVnode._hostNode);
                newStartVnode = newCh[++newStartIdx];
            } else {
                var index = arr.shift()
                elmToMove = oldCh[index];
                if (elmToMove.type !== newStartVnode.type) {
                    dom = mountVnode(newStartVnode, parentContext, null, mountQueue)
                    parentNode.insertBefore(parentNode, dom, oldStartVnode._hostNode);
                } else {
                    patchVnode(elmToMove, newStartVnode, mountQueue);
                    oldCh[idxInOld] = undefined;
                    parentNode.insertBefore(parentNode, (elmToMove._hostNode), oldStartVnode._hostNode);
                }
                newStartVnode = newCh[++newStartIdx];
            }
        }
    }
    if (oldStartIdx > oldEndIdx) {
        let before = newCh[newEndIdx + 1] == null
            ? null
            : newCh[newEndIdx + 1]._hostNode;
        addVnodes(parentNode, before, newCh, newStartIdx, newEndIdx, mountQueue);
    } else if (newStartIdx > newEndIdx) {
        removeVnodes(parentNode, oldCh, oldStartIdx, oldEndIdx);
    }
}



function createKeyMap(children, beginIdx, endIdx) {
    let i, map = {}, key, ch;
    for (i = beginIdx; i <= endIdx; ++i) {
        ch = children[i];
        key = ch.key;
        if (key !== void 666)
            if (map[key]) {
                map[key].push(i)
            } else {
                map[key] = [i]
            }
    }
    return map;
}

from anu.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.