Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
it('Should always unmount/mount if ReCreate flag is set', () => {
const spyObj = { fn: () => {} };
const spyObj2 = { fn: () => {} };
const spy1 = sinon.spy(spyObj, 'fn');
const spy2 = sinon.spy(spyObj2, 'fn');
const div = createVNode(VNodeFlags.HtmlElement | VNodeFlags.ReCreate, 'div', null, createTextVNode('1'), ChildFlags.HasVNodeChildren, null, null, spy1);
render(div, container);
let firstDiv = container.firstChild;
expect(container.innerHTML).toEqual('<div>1</div>');
expect(spy1.callCount).toBe(1);
expect(spy1.getCall(0).args.length).toBe(1);
expect(spy1.getCall(0).args[0]).toEqual(firstDiv);
const div2 = createVNode(VNodeFlags.HtmlElement | VNodeFlags.ReCreate, 'div', null, createTextVNode('1'), ChildFlags.HasVNodeChildren, null, null, spy2);
render(div2, container);
expect(firstDiv).not.toBe(container.firstChild); // Div is different
const spyObj2 = { fn: () => {} };
const spy1 = sinon.spy(spyObj, 'fn');
const spy2 = sinon.spy(spyObj2, 'fn');
const div = createVNode(VNodeFlags.HtmlElement | VNodeFlags.ReCreate, 'div', null, createTextVNode('1'), ChildFlags.HasVNodeChildren, null, null, spy1);
render(div, container);
let firstDiv = container.firstChild;
expect(container.innerHTML).toEqual('<div>1</div>');
expect(spy1.callCount).toBe(1);
expect(spy1.getCall(0).args.length).toBe(1);
expect(spy1.getCall(0).args[0]).toEqual(firstDiv);
const div2 = createVNode(VNodeFlags.HtmlElement | VNodeFlags.ReCreate, 'div', null, createTextVNode('1'), ChildFlags.HasVNodeChildren, null, null, spy2);
render(div2, container);
expect(firstDiv).not.toBe(container.firstChild); // Div is different
// Html is the same
expect(container.innerHTML).toEqual('<div>1</div>');
// Verify all callbacks were called
expect(spy1.callCount).toBe(2);
expect(spy1.getCall(1).args.length).toBe(1);
expect(spy1.getCall(1).args[0]).toEqual(null);
expect(spy2.callCount).toBe(1);
expect(spy2.getCall(0).args.length).toBe(1);
expect(spy2.getCall(0).args[0]).toEqual(container.firstChild);
function unstable_renderSubtreeIntoContainer(parentComponent, vNode, container, callback) {
const wrapperVNode: VNode = createComponentVNode(VNodeFlags.ComponentClass, WrapperComponent, {
children: vNode,
context: parentComponent.context
});
render(wrapperVNode, container, null);
const component = vNode.children;
if (callback) {
// callback gets the component as context, no other argument.
callback.call(component);
}
return component;
}
}
renderedString += `>`;
if (String(type).match(/[\s\n\/='"\0<>]/)) {
throw renderedString;
}
// Voided element, push directly to queue
if (isVoidElement) {
this.addToQueue(renderedString, position);
// Regular element with content
} else {
// Element has children, build them in
const childFlags = vNode.childFlags;
if (childFlags === ChildFlags.HasVNodeChildren) {
this.addToQueue(renderedString, position);
this.renderVNodeToQueue(children, context, position);
this.addToQueue('', position);
return;
} else if (childFlags === ChildFlags.HasTextChildren) {
this.addToQueue(renderedString, position);
this.addToQueue(children === '' ? ' ' : escapeText(children + ''), position);
this.addToQueue('', position);
return;
} else if (childFlags & ChildFlags.MultipleChildren) {
this.addToQueue(renderedString, position);
for (let i = 0, len = children.length; i < len; ++i) {
this.renderVNodeToQueue(children[i], context, position);
}
this.addToQueue('', position);
return;
break;
}
}
if (type === 'option' && typeof props.value !== 'undefined' && props.value === parent.props.value) {
// Parent value sets children value
renderedString += ` selected`;
}
}
if (isVoidElement) {
renderedString += `>`;
} else {
renderedString += `>`;
const childFlags = vNode.childFlags;
if (childFlags === ChildFlags.HasVNodeChildren) {
renderedString += renderVNodeToString(children, vNode, context);
} else if (childFlags & ChildFlags.MultipleChildren) {
for (let i = 0, len = children.length; i < len; ++i) {
renderedString += renderVNodeToString(children[i], vNode, context);
}
} else if (childFlags === ChildFlags.HasTextChildren) {
renderedString += children === '' ? ' ' : escapeText(children);
} else if (html) {
renderedString += html;
}
if (!isVoidElement) {
renderedString += ``;
}
}
if (String(type).match(/[\s\n\/='"\0<>]/)) {
public renderVNodeToQueue(vNode, context, position) {
const flags = vNode.flags;
const type = vNode.type;
const props = vNode.props || EMPTY_OBJ;
const children = vNode.children;
// Handles a component render
if ((flags & VNodeFlags.Component) > 0) {
const isClass = flags & VNodeFlags.ComponentClass;
// Render the
if (isClass) {
const instance = new type(props, context);
const hasNewAPI = Boolean(type.getDerivedStateFromProps);
instance.$BS = false;
instance.$SSR = true;
let childContext;
if (!isUndefined(instance.getChildContext)) {
childContext = instance.getChildContext();
}
if (!isNullOrUndef(childContext)) {
context = combineFrom(context, childContext);
}
if (instance.props === EMPTY_OBJ) {
instance.props = props;
}
} else {
const renderOutput = type(props, context);
if (isInvalid(renderOutput)) {
this.addToQueue('', position);
} else if (isString(renderOutput)) {
this.addToQueue(escapeText(renderOutput), position);
} else if (isNumber(renderOutput)) {
this.addToQueue(renderOutput + '', position);
} else {
this.renderVNodeToQueue(renderOutput, context, position);
}
}
// If an element
} else if ((flags & VNodeFlags.Element) > 0) {
let renderedString = `<${type}`;
let html;
const isVoidElement = voidElements.has(type);
const className = vNode.className;
if (isString(className)) {
renderedString += ` class="${escapeText(className)}"`;
} else if (isNumber(className)) {
renderedString += ` class="${className}"`;
}
if (!isNull(props)) {
for (const prop in props) {
const value = props[prop];
switch (prop) {
this.renderVNodeToQueue(children[i], context, position);
}
this.addToQueue('', position);
return;
}
if (html) {
this.addToQueue(renderedString + html + '', position);
return;
}
// Close element if it's not void
if (!isVoidElement) {
this.addToQueue(renderedString + '', position);
}
}
// Push text directly to queue
} else if ((flags & VNodeFlags.Text) > 0) {
this.addToQueue(children === '' ? ' ' : escapeText(children), position);
// Handle errors
} else {
if (process.env.NODE_ENV !== 'production') {
if (typeof vNode === 'object') {
throwError(`renderToString() received an object that's not a valid VNode, you should stringify it first. Object: "${JSON.stringify(vNode)}".`);
} else {
throwError(`renderToString() expects a valid VNode, instead it received an object with the type "${typeof vNode}".`);
}
}
throwError();
}
}
}
parentNode.appendChild(document.createTextNode(children as string));
} else if (parentNode.childNodes.length !== 1 || currentNode.nodeType !== 3) {
parentNode.textContent = children as string;
} else {
if (currentNode.nodeValue !== children) {
currentNode.nodeValue = children as string;
}
}
currentNode = null;
} else if (childFlags & ChildFlags.MultipleChildren) {
let prevVNodeIsTextNode = false;
for (let i = 0, len = (children as VNode[]).length; i < len; ++i) {
const child = (children as VNode[])[i];
if (isNull(currentNode) || (prevVNodeIsTextNode && (child.flags & VNodeFlags.Text) > 0)) {
_M(child as VNode, parentNode, context, isSVG, currentNode, lifecycle);
} else {
currentNode = hydrateVNode(child as VNode, parentNode, currentNode as Element, context, isSVG, lifecycle);
currentNode = currentNode ? currentNode.nextSibling : null;
}
prevVNodeIsTextNode = (child.flags & VNodeFlags.Text) > 0;
}
}
// clear any other DOM nodes, there should be only a single entry for the root
if ((flags & VNodeFlags.Fragment) === 0) {
let nextSibling: Node | null = null;
while (currentNode) {
nextSibling = currentNode.nextSibling;
}
currentNode = null;
} else if (childFlags & ChildFlags.MultipleChildren) {
let prevVNodeIsTextNode = false;
for (let i = 0, len = (children as VNode[]).length; i < len; ++i) {
const child = (children as VNode[])[i];
if (isNull(currentNode) || (prevVNodeIsTextNode && (child.flags & VNodeFlags.Text) > 0)) {
_M(child as VNode, parentNode, context, isSVG, currentNode, lifecycle);
} else {
currentNode = hydrateVNode(child as VNode, parentNode, currentNode as Element, context, isSVG, lifecycle);
currentNode = currentNode ? currentNode.nextSibling : null;
}
prevVNodeIsTextNode = (child.flags & VNodeFlags.Text) > 0;
}
}
// clear any other DOM nodes, there should be only a single entry for the root
if ((flags & VNodeFlags.Fragment) === 0) {
let nextSibling: Node | null = null;
while (currentNode) {
nextSibling = currentNode.nextSibling;
parentNode.removeChild(currentNode);
currentNode = nextSibling;
}
}
} else if (!isNull(parentNode.firstChild) && !isSamePropsInnerHTML(parentNode, props)) {
parentNode.textContent = ''; // dom has content, but VNode has no children remove everything from DOM
if (flags & VNodeFlags.FormElement) {