Comments and fix recording selectors for some components (and add one for VueComponent)
This commit is contained in:
parent
9c4653ffd4
commit
cc1be34263
|
@ -190,15 +190,34 @@ class ReactComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReactComponent.important = Symbol('BD.ReactComponent.important');
|
||||||
|
|
||||||
export class ReactComponents {
|
export class ReactComponents {
|
||||||
|
/** @type {ReactComponent[]} */
|
||||||
static get components() { return this._components || (this._components = []) }
|
static get components() { return this._components || (this._components = []) }
|
||||||
|
|
||||||
|
/** @type {Reflection.modules.React.Component[]} */
|
||||||
static get unknownComponents() { return this._unknownComponents || (this._unknownComponents = []) }
|
static get unknownComponents() { return this._unknownComponents || (this._unknownComponents = []) }
|
||||||
|
|
||||||
|
/** @type {{id: string, listeners: function[]}[]} */
|
||||||
static get listeners() { return this._listeners || (this._listeners = []) }
|
static get listeners() { return this._listeners || (this._listeners = []) }
|
||||||
|
|
||||||
|
/** @type {<{name: string, filter: function}[]>} */
|
||||||
static get nameSetters() { return this._nameSetters || (this._nameSetters = []) }
|
static get nameSetters() { return this._nameSetters || (this._nameSetters = []) }
|
||||||
static get componentAliases() { return this._componentAliases || (this._componentAliases = []) }
|
|
||||||
|
/** @type {Object.<string, string>} */
|
||||||
|
static get componentAliases() { return this._componentAliases || (this._componentAliases = {}) }
|
||||||
|
|
||||||
static get ReactComponent() { return ReactComponent }
|
static get ReactComponent() { return ReactComponent }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a React component.
|
||||||
|
* @param {Reflection.modules.React.Component} component The React component class
|
||||||
|
* @param {object} retVal
|
||||||
|
* @param {object} important
|
||||||
|
* @param {string} important.selector A query selector the component will render elements matching (used to select all component instances to force them to rerender)
|
||||||
|
* @return {ReactComponent}
|
||||||
|
*/
|
||||||
static push(component, retVal, important) {
|
static push(component, retVal, important) {
|
||||||
if (!(component instanceof Function)) return null;
|
if (!(component instanceof Function)) return null;
|
||||||
const { displayName } = component;
|
const { displayName } = component;
|
||||||
|
@ -212,6 +231,8 @@ export class ReactComponents {
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!important) important = component[ReactComponent.important];
|
||||||
|
|
||||||
const c = new ReactComponent(displayName, component, retVal, important);
|
const c = new ReactComponent(displayName, component, retVal, important);
|
||||||
this.components.push(c);
|
this.components.push(c);
|
||||||
|
|
||||||
|
@ -226,16 +247,19 @@ export class ReactComponents {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a component from the components array or by waiting for it to be mounted.
|
* Finds a component from the components array or by waiting for it to be mounted.
|
||||||
* @param {String} name The component's name
|
* @param {string} name The component's name
|
||||||
* @param {Object} important An object containing a selector to look for
|
* @param {object} important An object containing a selector to look for
|
||||||
* @param {Function} filter A function to filter components if a single element is rendered by multiple components
|
* @param {function} filter A function to filter components if a single element is rendered by multiple components
|
||||||
* @return {Promise => ReactComponent}
|
* @return {Promise<ReactComponent>}
|
||||||
*/
|
*/
|
||||||
static async getComponent(name, important, filter) {
|
static async getComponent(name, important, filter) {
|
||||||
name = this.getComponentName(name);
|
name = this.getComponentName(name);
|
||||||
|
|
||||||
const have = this.components.find(c => c.id === name);
|
const have = this.components.find(c => c.id === name);
|
||||||
if (have) return have;
|
if (have) {
|
||||||
|
if (!have.important) have.important = important;
|
||||||
|
return have;
|
||||||
|
}
|
||||||
|
|
||||||
if (important) {
|
if (important) {
|
||||||
const callback = () => {
|
const callback = () => {
|
||||||
|
@ -321,6 +345,11 @@ export class ReactComponents {
|
||||||
return this.nameSetters.push({ name, filter });
|
return this.nameSetters.push({ name, filter });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a React component that isn't known.
|
||||||
|
* @param {Reflection.modules.React.Component} component
|
||||||
|
* @param {} retVal
|
||||||
|
*/
|
||||||
static processUnknown(component, retVal) {
|
static processUnknown(component, retVal) {
|
||||||
for (const [fi, filter] of this.nameSetters.entries()) {
|
for (const [fi, filter] of this.nameSetters.entries()) {
|
||||||
if (filter.filter.filter(component)) {
|
if (filter.filter.filter(component)) {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Reflection } from 'modules';
|
import { Reflection, ReactComponents } from 'modules';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
export default class {
|
export default class {
|
||||||
|
@ -16,12 +16,12 @@ export default class {
|
||||||
/**
|
/**
|
||||||
* Creates a new Vue object and mounts it in the passed element.
|
* Creates a new Vue object and mounts it in the passed element.
|
||||||
* @param {HTMLElement} root The element to mount the new Vue object at
|
* @param {HTMLElement} root The element to mount the new Vue object at
|
||||||
* @param {Object} options Options to pass to Vue
|
* @param {Object} options Options to pass to Vue (see https://vuejs.org/v2/api/#Options-Data)
|
||||||
* @param {BdNode} bdnode The element to append
|
* @param {BdNode} bdnode The element to append
|
||||||
* @return {Vue}
|
* @return {Vue}
|
||||||
*/
|
*/
|
||||||
static inject(root, options, bdnode) {
|
static inject(root, options, bdnode) {
|
||||||
if(bdnode) bdnode.appendTo(root);
|
if (bdnode) bdnode.appendTo(root);
|
||||||
|
|
||||||
const vue = new Vue(options);
|
const vue = new Vue(options);
|
||||||
|
|
||||||
|
@ -37,18 +37,18 @@ export default class {
|
||||||
* @return {React.Element}
|
* @return {React.Element}
|
||||||
*/
|
*/
|
||||||
static createReactElement(component, props, mountAtTop) {
|
static createReactElement(component, props, mountAtTop) {
|
||||||
const { React } = Reflection.modules;
|
return Reflection.modules.React.createElement(this.ReactCompatibility, {component, mountAtTop, props});
|
||||||
return React.createElement(this.ReactCompatibility, {component, mountAtTop, props});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get ReactCompatibility() {
|
static get ReactCompatibility() {
|
||||||
if (this._ReactCompatibility) return this._ReactCompatibility;
|
const { React, ReactDOM } = Reflection.modules;
|
||||||
|
|
||||||
const { React, ReactDOM} = Reflection.modules;
|
/**
|
||||||
|
* A React component that renders a Vue component.
|
||||||
return this._ReactCompatibility = class VueComponent extends React.Component {
|
*/
|
||||||
|
const ReactCompatibility = class VueComponent extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return React.createElement('span');
|
return React.createElement('span', {className: 'bd-reactVueComponent'});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -89,7 +89,13 @@ export default class {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// Add a name for ReactComponents
|
||||||
|
ReactCompatibility.displayName = 'BD.VueComponent';
|
||||||
|
ReactCompatibility[ReactComponents.ReactComponent.important] = {selector: '.bd-reactVueComponent'};
|
||||||
|
|
||||||
|
return Object.defineProperty(this, 'ReactCompatibility', {value: ReactCompatibility}).ReactCompatibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
static install(Vue) {
|
static install(Vue) {
|
||||||
|
@ -98,6 +104,9 @@ export default class {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Vue component that renders a React component.
|
||||||
|
*/
|
||||||
export const ReactComponent = {
|
export const ReactComponent = {
|
||||||
props: ['component', 'component-props', 'component-children', 'react-element'],
|
props: ['component', 'component-props', 'component-children', 'react-element'],
|
||||||
render(createElement) {
|
render(createElement) {
|
||||||
|
|
Loading…
Reference in New Issue