This repository was archived by the owner on May 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlaxar-react-adapter.js
More file actions
124 lines (96 loc) · 3.85 KB
/
laxar-react-adapter.js
File metadata and controls
124 lines (96 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/**
* Copyright 2017 aixigo AG
* Released under the MIT license.
* http://laxarjs.org/license
*/
/**
* Implements the LaxarJS adapter API for the integration technology "react":
* https://github.com/LaxarJS/laxar/blob/master/docs/manuals/adapters.md
*
* @module laxar-react-adapter
*/
import React from 'react';
import * as ReactDom from 'react-dom';
export { AxWidgetArea } from './lib/components/widget-area';
const randomIdentifier = () => (`00${Math.ceil(Math.random() * 255).toString(16)}`).substr(-2);
const Symbol = window.Symbol || (name => `Symbol(${name}-${randomIdentifier})`);
const injectionsProperty = Symbol('injections');
export const technology = 'react';
export { injectionsProperty as injections };
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
export function bootstrap( { widgets }, { adapterUtilities } ) {
const widgetModules = {};
const activitySet = {};
widgets.forEach( ({ descriptor, module }) => {
widgetModules[ descriptor.name ] = module;
if( descriptor.integration.type === 'activity' ) {
activitySet[ descriptor.name ] = true;
}
} );
return {
create
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////
function create( { widgetName, anchorElement, services, provideServices } ) {
const element = createElement();
return {
domAttachTo( areaElement ) {
ReactDom.render( element, anchorElement );
areaElement.appendChild( anchorElement );
},
domDetach() {
ReactDom.unmountComponentAtNode( anchorElement );
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////
function createElement() {
// backwards compatibility with old-style AMD widgets:
const module = widgetModules[ widgetName ].default || widgetModules[ widgetName ];
if( !module ) {
throw adapterUtilities.unknownWidget( { technology, widgetName } );
}
const Component = module.create ?
wrapModule( module ) :
module;
let component;
const reactServices = {
axReactRender() {
if( component ) {
component.forceUpdate();
}
}
};
const injectionsByName = {};
const injections = ( Component[ injectionsProperty ] || [] ).map( injection => {
const value = reactServices[ injection ] || services[ injection ];
if( value === undefined ) {
throw adapterUtilities.unknownInjection( { technology, injection, widgetName } );
}
if( injection === 'axReactRender' && activitySet[ widgetName ] ) {
throw adapterUtilities.activityAccessingDom( { technology, injection, widgetName } );
}
injectionsByName[ injection ] = value;
return value;
} );
provideServices( injectionsByName );
if( module.create ) {
Component.prototype.render = module.create( ...injections ) || (() => null);
}
return React.createElement( Component, {
injections,
ref( c ) {
component = c;
}
}, null );
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
function wrapModule( { name = widgetName, injections = [] } ) {
class Component extends React.Component {
}
Component.displayName = name;
Component[ injectionsProperty ] = injections;
return Component;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
}
}