@twobirds/microcomponents 0.0.12 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -44
- package/assets/documentation/ajaxian-1.png +0 -0
- package/assets/documentation/ajaxian-2.png +0 -0
- package/assets/documentation/ajaxian-3.png +0 -0
- package/assets/documentation/history.md +436 -0
- package/assets/documentation/how_tos.md +0 -0
- package/assets/documentation/introduction.md +0 -0
- package/{microcomponents_magic.md → assets/documentation/magic.md} +1 -1
- package/assets/documentation/rnd0023-1.jpg +0 -0
- package/assets/documentation/rnd0023-2.jpg +0 -0
- package/assets/documentation/rnd0023-3.jpg +0 -0
- package/assets/documentation/tB_react.md +369 -0
- package/package.json +2 -2
- package/public/documentation/ajaxian-1.png +0 -0
- package/public/documentation/ajaxian-2.png +0 -0
- package/public/documentation/ajaxian-3.png +0 -0
- package/public/documentation/functional_requirements.md +8 -0
- package/public/documentation/history.md +436 -0
- package/public/documentation/how_tos.md +0 -0
- package/public/documentation/introduction.md +0 -0
- package/public/documentation/magic.md +87 -0
- package/public/documentation/proposal_draft.md +37 -0
- package/public/documentation/rnd0023-1.jpg +0 -0
- package/public/documentation/rnd0023-2.jpg +0 -0
- package/public/documentation/rnd0023-3.jpg +0 -0
- package/public/documentation/tB_react.md +369 -0
- package/public/documentation/usage.md +142 -0
- package/public/documentation/why.md +25 -0
- package/public/test.js +20 -18
- package/src/test.js +22 -20
- package/dist/test.d.ts +0 -36
- package/dist/test.d.ts.map +0 -1
- package/dist/test.js +0 -214
- /package/{microcomponents_functional_requirements.md → assets/documentation/functional_requirements.md} +0 -0
- /package/{MicroComponentProposal_draft.md → assets/documentation/proposal_draft.md} +0 -0
- /package/{microcomponents_usage.md → assets/documentation/usage.md} +0 -0
- /package/{microcomponents_why.md → assets/documentation/why.md} +0 -0
package/README.md
CHANGED
|
@@ -9,8 +9,8 @@ Importing a custom MC in your client side code:
|
|
|
9
9
|
import MyButton from '@mySampleLib/Button';
|
|
10
10
|
```
|
|
11
11
|
... is equivalent to:
|
|
12
|
-
```
|
|
13
|
-
npm i
|
|
12
|
+
```shell
|
|
13
|
+
npm i @mySampleLib/Button
|
|
14
14
|
```
|
|
15
15
|
... on the server side.
|
|
16
16
|
|
|
@@ -21,28 +21,30 @@ Imagine your micro components to be organized like a "node_modules" directory th
|
|
|
21
21
|
**On the server side** MCs can be used to organize your code, too.
|
|
22
22
|
|
|
23
23
|
## Status
|
|
24
|
-
WIP. Should be done soon. In [manual testing](http://twobirds.gitlab.io/microcomponents/test.html).
|
|
24
|
+
WIP. Should be done soon. In [manual testing](http://twobirds.gitlab.io/microcomponents/test.html), also working a lot on the documentation.
|
|
25
25
|
|
|
26
26
|
## Disclaimer
|
|
27
27
|
I decided to extract this functionality from the [twoBirds framework](https://www.npmjs.com/package/twobirds-core), since it is framework agnostic, and relies solely on the standard DOM and native javascript or typescript, and is a useful tool in itself. Later this will be backported into twoBirds as a dependency, and twoBirds will become completely modularized on the base of MCs.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Read the [history](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/history.md) to see how it all started in 2004. It contains some fun stuff.
|
|
30
|
+
|
|
31
|
+
This is a massive undertaking. MCs are just the foundation of what I do. **I am about to dump** [20+ years of javascript programming](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/magic.md?ref_type=heads#things-i-already-did-with-this-in-my-own-framework-twobirds-or-in-apps-that-i-developed-with-it) **into open source libraries**, so feel free to [fund this](https://gofund.me/076c614c). The better this is funded, the faster it will be done. Given enough resources, I will start a crowdfunded company that will develop a new ecosystem for javascript/typescript programming.
|
|
30
32
|
|
|
31
33
|
By **"Open Source"** I mean **really free and open**, as **you get all my inner source code with it**. Once you understand the Micro Component principle, you are back in command of your software, no matter what MC functionality you import in your system. Since **Micro Components** are encapsuled, off-shoring and near-shoring is no problem, and reusability is guaranteed. Your external coders do not need to access your code repository or your toolchain. They only need to understand MCs.
|
|
32
34
|
|
|
33
|
-
**Established frameworks**, as opposed to MCs, **provide a documented interface to a hidden layer of closed source inner functionality**. MCs can be used to **add an interface to components you developed using other frameworks**. So you can still use your existing code, and MCs in it. But you
|
|
35
|
+
**Established frameworks**, as opposed to MCs, **provide a documented interface to a hidden layer of closed source inner functionality**. MCs can be used to **add an interface to components you developed using other frameworks**. So you can still use your existing code, and MCs in it. But you be tempted to migrate it ASAP, since MCs work with any FW.
|
|
34
36
|
|
|
35
37
|
## General
|
|
36
38
|
|
|
37
|
-
Using micro components enforces **DRY, KISS and SOLID** principles in Javascript programming. Read this [RFC](https://gitlab.com/twoBirds/microcomponents/-/blob/main/
|
|
39
|
+
Using micro components enforces **DRY, KISS and SOLID** principles in Javascript programming. Read this [RFC](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/proposal_draft.md?ref_type=heads) for the shortest info, and [click here to see why you may want to use it](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/why.md?ref_type=heads).
|
|
38
40
|
|
|
39
41
|
This is a low-level approach. It consists of a single class with 3 static methods and 5 selector methods, and weights in at ~2 kB. Also there is an ES3 version to help e.g. [hbbtv](https://en.wikipedia.org/wiki/Hybrid_Broadcast_Broadband_TV) modular JS coding, or any other device that relies on ES3. The latter is WIP, backporting is currently last on my list.
|
|
40
42
|
|
|
41
|
-
For a short usage description goto [Micro Component Usage](https://gitlab.com/twoBirds/microcomponents/-/blob/main/
|
|
43
|
+
For a short usage description goto [Micro Component Usage](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/usage.md?ref_type=heads).
|
|
42
44
|
|
|
43
45
|
Check the [typedoc API reference](http://twobirds.gitlab.io/microcomponents/classes/microcomponents.MC.html) if you want to drill into the source code.
|
|
44
46
|
|
|
45
|
-
To see what can be done, go to [additional concepts](https://gitlab.com/twoBirds/microcomponents/-/blob/main/
|
|
47
|
+
To see what can be done, go to [additional concepts](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/magic.md?ref_type=heads) which shows what it already has been used for.
|
|
46
48
|
|
|
47
49
|
## Simple Usage:
|
|
48
50
|
|
|
@@ -55,67 +57,47 @@ before:
|
|
|
55
57
|
|
|
56
58
|
code:
|
|
57
59
|
```typescript
|
|
58
|
-
// create an inner micro component class
|
|
59
|
-
class MyInnerMC extends MC{
|
|
60
|
-
|
|
61
|
-
constructor( target ){
|
|
62
|
-
super( target );
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
doSomething(){
|
|
66
|
-
console.log( this, 'something done' )
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
60
|
// create a custom micro component class
|
|
71
61
|
class MyMC extends MC{
|
|
72
62
|
|
|
73
|
-
private myInner: MyInnerMC;
|
|
74
|
-
|
|
75
63
|
constructor( target ){
|
|
76
64
|
super( target );
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
//add a private inner micro component
|
|
80
|
-
this.myInner = new MyInnerMC( target );
|
|
65
|
+
}
|
|
81
66
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
'myPublicInnerMC',
|
|
85
|
-
new MyInnerMC( target )
|
|
86
|
-
);
|
|
67
|
+
helloWorld(){
|
|
68
|
+
console.log( 'Hello World' );
|
|
87
69
|
}
|
|
70
|
+
|
|
88
71
|
}
|
|
89
72
|
|
|
90
73
|
// get some element from the DOM
|
|
91
74
|
const element = document.querySelector('div')
|
|
92
75
|
|
|
93
76
|
// Add the custom micro component instance to the target element
|
|
94
|
-
|
|
77
|
+
MC.add(
|
|
95
78
|
element,
|
|
96
79
|
'myMC',
|
|
97
80
|
new MyMC( element )
|
|
98
81
|
);
|
|
99
82
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
console.log( topLevelMC.siblings() );
|
|
107
|
-
// [ { target: (element), _mc: { myPublicInnerMC: {...} } } ]
|
|
83
|
+
// Hello World
|
|
84
|
+
element
|
|
85
|
+
._mc
|
|
86
|
+
.myMC
|
|
87
|
+
.helloWorld();
|
|
108
88
|
```
|
|
109
89
|
|
|
110
90
|
after:
|
|
111
91
|
```HTML
|
|
112
|
-
<div _mc></
|
|
92
|
+
<div _mc></div>
|
|
113
93
|
```
|
|
114
|
-
_mc indicates that this HTML element contains at least one micro component. This is needed for the
|
|
94
|
+
_mc indicates that this HTML element contains at least one micro component. This is needed for the selectors.
|
|
95
|
+
|
|
96
|
+
the _mc attribute and properties are the only interference with the DOM, so every other system should be happy to work with this.
|
|
115
97
|
|
|
116
98
|
## Contact
|
|
117
99
|
Feel free to contact me for any questions or inquiries:
|
|
118
100
|
|
|
119
|
-
email [Frank Thürigen](mailto:fthuerigen@gmail.com?subject=Micro%20Components) or [Skype](skype
|
|
101
|
+
email [Frank Thürigen](mailto:fthuerigen@gmail.com?subject=Micro%20Components) or [Skype](skype://frank.thuerigen)
|
|
120
102
|
|
|
121
|
-
And
|
|
103
|
+
And again, you can [fund this](https://gofund.me/076c614c).
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
## History
|
|
2
|
+
|
|
3
|
+
### Content
|
|
4
|
+
|
|
5
|
+
- [Before 2006](#before-2006)
|
|
6
|
+
- [DOM and Javascript in 2006](#dom-and-javascript-in-2006)
|
|
7
|
+
- [How it started](#how-it-started)
|
|
8
|
+
- [Initial Specification](#initial-specification)
|
|
9
|
+
- [Unforeseen Problems](#unforeseen-problems)
|
|
10
|
+
- [The Result](#the-result)
|
|
11
|
+
- [Release on Ajaxian](#release-on-ajaxian)
|
|
12
|
+
- [First SPA ever](#first-spa-ever)
|
|
13
|
+
- [Some Code Snippets](#some-code-snippets)
|
|
14
|
+
- [The Fallout](#the-fallout)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Before 2006
|
|
18
|
+
|
|
19
|
+
Starting 1980, I programmed client-server or standalone applications for DOS and MS Windows.
|
|
20
|
+
|
|
21
|
+
Around 1995 I switched to web programming.
|
|
22
|
+
|
|
23
|
+
Before 2006 I was working on server side modular components using PHP, with little client side automation using Javascript.
|
|
24
|
+
|
|
25
|
+
Starting 2004 I developed twoBirds v1, vaguely centered around a web component idea.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## DOM and Javascript in 2006
|
|
29
|
+
|
|
30
|
+
The Internet has just existed for a couple of years for private use.
|
|
31
|
+
|
|
32
|
+
Douglas Crockford had released the [JSON specification](https://en.wikipedia.org/wiki/JSON) in 2000.
|
|
33
|
+
|
|
34
|
+
The [XMLHttpRequest](https://en.wikipedia.org/wiki/XMLHttpRequest) was specified by Microsoft in 2001. As of IE7 (2006) it was adopted by every browser, albeit buggy in IE(!).
|
|
35
|
+
|
|
36
|
+
The Javascript engines and the DOM model in contemporary browsers slightly differed from each other then.
|
|
37
|
+
|
|
38
|
+
John Resig had released [jQuery](https://en.wikipedia.org/wiki/JQuery). [Prototype](https://en.wikipedia.org/wiki/Prototype_JavaScript_Framework) was its main competitor then.
|
|
39
|
+
|
|
40
|
+
Both of these libraries were immensely helpful, since they allowed for cross-browser access to the DOM and leveraged Javascript inconsistencies.
|
|
41
|
+
|
|
42
|
+
I was a self-employed full-stack programmer then. **PHP** and **Javascript** knowledge was all it took in these lucky days to call yourself a full stack programmer.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## How it started
|
|
46
|
+
|
|
47
|
+
With a call, obviously. The requirements were: convert an Excel sheet into a web application, so insurance company staff could plan customer appointments and the company could automate monthly travel expense refunds.
|
|
48
|
+
|
|
49
|
+
Easy, of course I can do that. LAMP and jQuery will do it for me. Until it didn't.
|
|
50
|
+
|
|
51
|
+
jQuery doesn't help you in any way structuring complex code. But my existing twoBirds v1 could. I saw the chance to let this project fund twoBirds v2.
|
|
52
|
+
|
|
53
|
+
I called back the customer and explained. In essence we agreed to this: the customer will pay the same sum, but it will take double as long. The updated twoBirds v2 library will continue to be my royalty, but he is given a lifelong license to it.
|
|
54
|
+
|
|
55
|
+
The project was a grossly underestimated, as I found out. Estimated at 6 month, it finally took 12 and most of this was twoBirds, especially the cross-browser part. Spoiler: it worked in the end.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Initial Specification
|
|
59
|
+
|
|
60
|
+
twoBirds was to fulfill these requirements:
|
|
61
|
+
|
|
62
|
+
- **cross browser**.
|
|
63
|
+
|
|
64
|
+
This led to some unforseen consequences, which I will describe below.
|
|
65
|
+
- **on-demand loading** of Javascript files.
|
|
66
|
+
|
|
67
|
+
Also on-demand loading of associated **HTML templates** and **CSS**. This must be **recursive**, so MCs can recursively load other MCs and their requirements.
|
|
68
|
+
- **internal Micro Component repository** in the resulting application to avoid multiple loading for multiple instances of a MC in the page.
|
|
69
|
+
- **leverage XMLHttpRequest inconsistencies**, especially the famous "closure bug" that led to memory leaks in IE.
|
|
70
|
+
- **jQuery** as the selector engine.
|
|
71
|
+
|
|
72
|
+
Thanks again John, without your code it would have been much harder. We all stand on the shoulders of giants.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## Unforseen Problems
|
|
76
|
+
|
|
77
|
+
Browsers tested:
|
|
78
|
+
- **IE5.5**+
|
|
79
|
+
- **Netscape Communicator**, later **Firefox** also
|
|
80
|
+
- **Chrome**
|
|
81
|
+
- **Opera**
|
|
82
|
+
- **Safari** ( Safari for Windows at least, see below)
|
|
83
|
+
- **Konqueror**, since I was working on OpenSUSE.
|
|
84
|
+
|
|
85
|
+
This resulted in some problems, i.e. (list is not complete):
|
|
86
|
+
|
|
87
|
+
### No debuggers
|
|
88
|
+
|
|
89
|
+
Firebug wasn't there yet. When it finally arrived as a firefox extension, I was really cooking.
|
|
90
|
+
|
|
91
|
+
Other than that there was no reflection mechanism, so no runtime introspection for most browsers. The Proxy() class didn't exist yet.
|
|
92
|
+
|
|
93
|
+
Microsofts skript debugger didnt help a lot with other browsers.
|
|
94
|
+
|
|
95
|
+
### Missing equipment
|
|
96
|
+
|
|
97
|
+
Since I had no Apple hardware, I couldn't reliably test for Safari on MAC. Safari for Windows was slightly different from Safari on MAC.
|
|
98
|
+
|
|
99
|
+
At least I got it working there but could not promise for MAC hardware. I was told by others it worked there as well, though.
|
|
100
|
+
|
|
101
|
+
### Meager internal documentation for browsers
|
|
102
|
+
|
|
103
|
+
It took me month to find out the best way to on-demand load Javascript code, templates and CSS, and how to avoid FOUC.
|
|
104
|
+
|
|
105
|
+
### timeout()
|
|
106
|
+
|
|
107
|
+
Cross-browser support in 2006 meant Konqueror also.
|
|
108
|
+
|
|
109
|
+
But Konqueror v1 had a funny bug: it could only handle one (1) timeout via setTimeout() at a time. I had to come up with a workaround.
|
|
110
|
+
|
|
111
|
+
So I implemented tb.timer() which used a single timeout to poll a list of timestamped callbacks every 100 ms.
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
tb.timer = {
|
|
115
|
+
destroylist: [],
|
|
116
|
+
addlist: [],
|
|
117
|
+
list: [],
|
|
118
|
+
ms: 100,
|
|
119
|
+
|
|
120
|
+
// public
|
|
121
|
+
|
|
122
|
+
add: function( pCallback, pTimeMs ) {
|
|
123
|
+
var myDate = new Date();
|
|
124
|
+
var myIdentifier = '_to'+tb.misc.getid();
|
|
125
|
+
var myTime = myDate.getTime() + pTimeMs;
|
|
126
|
+
var myArray = [ myTime, '( '+pCallback+' )', myIdentifier ];
|
|
127
|
+
tb.timer.addlist.push( myArray );
|
|
128
|
+
if (tb.timer.list.length === 0 ) {
|
|
129
|
+
window.setTimeout( 'tb.timer.timeout()', 10);
|
|
130
|
+
}
|
|
131
|
+
return myIdentifier;
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
abort: function( pIdentifier ) {
|
|
135
|
+
tb.timer.destroylist.push( pIdentifier );
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
//private
|
|
139
|
+
|
|
140
|
+
destroy: function( pIdentifier ) {
|
|
141
|
+
var myNewlist = [];
|
|
142
|
+
var i=0;
|
|
143
|
+
for ( i in tb.timer.list ) {
|
|
144
|
+
if ( tb.timer.list[i][2] !== pIdentifier ) {
|
|
145
|
+
var myObj = tb.misc.cloneObj( tb.timer.list[i] );
|
|
146
|
+
myNewlist.push( myObj );
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
tb.timer.list = myNewlist;
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
timeout: function() {
|
|
153
|
+
while ( tb.timer.addlist.length > 0 ) {
|
|
154
|
+
tb.timer.list.push( tb.timer.addlist.pop() );
|
|
155
|
+
}
|
|
156
|
+
while ( tb.timer.destroylist.length > 0 ) {
|
|
157
|
+
tb.timer.destroy( tb.timer.destroylist.pop() );
|
|
158
|
+
}
|
|
159
|
+
if ( tb.timer.list.length < 1 ) {
|
|
160
|
+
tb.timer.ms = 100;
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
var myNewList = [];
|
|
165
|
+
var myMinVal = 0;
|
|
166
|
+
while ( tb.timer.list.length > 0 ) {
|
|
167
|
+
var myDate = new Date();
|
|
168
|
+
var myTime = myDate.getTime();
|
|
169
|
+
if ( tb.timer.list[0][0] <= myTime ) {
|
|
170
|
+
var myEval = tb.timer.list[0][1];
|
|
171
|
+
eval( '( ' + myEval + ' )' );
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
if ( tb.timer.list[0][1] < myMinVal || myMinVal === 0 ) {
|
|
175
|
+
myMinVal = tb.timer.list[0][1];
|
|
176
|
+
}
|
|
177
|
+
myNewList.push( tb.timer.list[0] );
|
|
178
|
+
}
|
|
179
|
+
tb.timer.list.shift();
|
|
180
|
+
}
|
|
181
|
+
tb.timer.list = myNewList;
|
|
182
|
+
if ( myMinVal > 0 ) {
|
|
183
|
+
myDate = new Date();
|
|
184
|
+
tb.timer.ms = myMinVal - myDate.getTime();
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
tb.timer.ms = 100;
|
|
188
|
+
}
|
|
189
|
+
while ( tb.timer.addlist.length > 0 ) {
|
|
190
|
+
tb.timer.list.push( tb.timer.addlist.pop() );
|
|
191
|
+
}
|
|
192
|
+
window.setTimeout( 'tb.timer.timeout()', tb.timer.ms);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
};
|
|
197
|
+
window.setTimeout( 'tb.timer.timeout()', 0);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Then I implemented ...
|
|
201
|
+
- **tb.timeout()** to use tb.timer().
|
|
202
|
+
|
|
203
|
+
- **tb.interval()** also, which used tb.timeout(). This I did with the added benefit that my implementation avoided runovers if the implemented functionality lasted longer than the interval.
|
|
204
|
+
|
|
205
|
+
While I was at it, I also implemented...
|
|
206
|
+
- **tb.wait()**, which used tb.interval() to wait for a condition to be true, and then called the callback.
|
|
207
|
+
|
|
208
|
+
- **tb.observe()**, which was a tb.interval() implementation of tb.wait().
|
|
209
|
+
|
|
210
|
+
At this point I had a solution polling **Observables** in 2006.
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
## The Result
|
|
214
|
+
|
|
215
|
+
So far I had a solution for **requirement loading**, **templating**, **observables** and **web components** as early as 2006.
|
|
216
|
+
|
|
217
|
+
- **tb.require()** probably influenced [requireJs](https://requirejs.org/) and in turn the CommonJS specification.
|
|
218
|
+
|
|
219
|
+
- **Templates** are now a coding standard and implemented in various ways using backtick strings ( `string with ${placeholder}` ) and the DOM template tag.
|
|
220
|
+
|
|
221
|
+
- **Observables** are now a coding standard and implemented in various ways using getters/setters or the Proxy() object.
|
|
222
|
+
|
|
223
|
+
- [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) initially contained a definition for user built in custom elements, which was a functional copy of twoBirds web components.
|
|
224
|
+
|
|
225
|
+
Look at the screenshots attached at the end of this document. That is the application I developed, with a code example attached.
|
|
226
|
+
|
|
227
|
+
## Release on Ajaxian
|
|
228
|
+
|
|
229
|
+
twoBirds v2 was open sourced and anounced on ajaxian.com on April 2nd 2007, you can find the original article on archive.org.
|
|
230
|
+
|
|
231
|
+

|
|
232
|
+

|
|
233
|
+
|
|
234
|
+
Which led to this comment:
|
|
235
|
+
|
|
236
|
+

|
|
237
|
+
|
|
238
|
+
RTFM, man. Oh nevermind, Dean. I forget to add one. Autists...
|
|
239
|
+
|
|
240
|
+
twoBirds as a framework will be dissolved into modular micro component based functionality. RIP. It served me well for 20 years.
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
## First SPA ever
|
|
244
|
+
|
|
245
|
+
The first web component based single page application (SPA) that ever existed - to my knowledge. Prove me otherwise ;-).
|
|
246
|
+
|
|
247
|
+
;
|
|
248
|
+
;
|
|
249
|
+
;
|
|
250
|
+
|
|
251
|
+
Yes, I contemplated programming a web based Excel, as in Google Calc.
|
|
252
|
+
|
|
253
|
+
And web component based cockpit instruments for airplanes.
|
|
254
|
+
|
|
255
|
+
As I think of it: **SpaceX** uses **Web Components** for cockpit instruments in their **Dragon Capsule**. ;-)
|
|
256
|
+
|
|
257
|
+
## Some Code Snippets
|
|
258
|
+
|
|
259
|
+
This is the code for the left part of the table shown in the pictures above.
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
self.tourtable.leftcolumn = { // new object
|
|
263
|
+
|
|
264
|
+
showcounter: 0,
|
|
265
|
+
datecache: [], // cache für HTML code
|
|
266
|
+
|
|
267
|
+
init: function (pDivId) {
|
|
268
|
+
//tb.element.show( null, 'tourtable', 'leftcolumnline'); // preload line code
|
|
269
|
+
tb.element.require(
|
|
270
|
+
[ [ 'css', 'tourtable', 'leftcolumn'],
|
|
271
|
+
[ 'tpl', 'tourtable', 'leftcolumn'] ],
|
|
272
|
+
'tourtable.leftcolumn.display("' + pDivId + '")',
|
|
273
|
+
true );
|
|
274
|
+
},
|
|
275
|
+
|
|
276
|
+
display: function (pDivId) {
|
|
277
|
+
|
|
278
|
+
if ( tourtable.middlecolumn.day == -1 ) { // clear HTML array
|
|
279
|
+
tourtable.leftcolumn.datecache = [];
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
tourtable.leftcolumn.datecache[tourtable.middlecolumn.day] = '';
|
|
283
|
+
var pDay = tourtable.middlecolumn.day;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
var myDiv = document.getElementById( pDivId );
|
|
288
|
+
}
|
|
289
|
+
catch (e) {
|
|
290
|
+
tb.timer.add( 'tourtable.leftcolumn.display("'+pDivId+'")', 100 );
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
tourtable.leftcolumn.showcounter = 1;
|
|
294
|
+
//tb.debug.add("<p>Element <font color='magenta'><b> display: </b></font> tourtable.leftcolumn in " + pDivId + "</p>");
|
|
295
|
+
var myHtml = tb.loader.tplget('tourtable','leftcolumn');
|
|
296
|
+
var myNewRegEx = new RegExp('%tourtableleftrows%');
|
|
297
|
+
myHtml = myHtml.replace(myNewRegEx, '');
|
|
298
|
+
tb.div.replace(pDivId,myHtml);
|
|
299
|
+
myHtml = tb.loader.tplget('tourtable','leftcolumn');
|
|
300
|
+
|
|
301
|
+
var myDate = new tb.tbDate();
|
|
302
|
+
myDate.setDate(1);
|
|
303
|
+
var myMonth = myDate.getMonth();
|
|
304
|
+
var myRows = '';
|
|
305
|
+
var myDateRows = '';
|
|
306
|
+
var myId = 1;
|
|
307
|
+
var myLastDate='';
|
|
308
|
+
var createDate='';
|
|
309
|
+
|
|
310
|
+
//tb.debug.add('<p>leftcolumn <font color="blue">Act:</font> '+middlecolumn.getlength()+'</p>');
|
|
311
|
+
|
|
312
|
+
//var myDateList = '';
|
|
313
|
+
if ( tourtable.middlecolumn.getlength() > 0 )
|
|
314
|
+
for ( x=0; x < tourtable.middlecolumn.getlength(); x++ ) {
|
|
315
|
+
var thisRecord = tourtable.middlecolumn.act.Data.data[0][x];
|
|
316
|
+
if ( tourtable.middlecolumn.currentId == null ) {
|
|
317
|
+
tourtable.middlecolumn.currentId = thisRecord.id;
|
|
318
|
+
}
|
|
319
|
+
var myDate = new tb.tbDate();
|
|
320
|
+
myDate.setFromMysqlDateString( thisRecord.datum );
|
|
321
|
+
var thisDateIndex = myDate.getDate();
|
|
322
|
+
if ( ! tourtable.leftcolumn.datecache[thisDateIndex] ) { // create if necessary
|
|
323
|
+
tourtable.leftcolumn.datecache[thisDateIndex] = '';
|
|
324
|
+
}
|
|
325
|
+
if ( tourtable.leftcolumn.datecache[thisDateIndex] == '') { // create if necessary
|
|
326
|
+
createDate = thisDateIndex;
|
|
327
|
+
}
|
|
328
|
+
var myNextDate = ( x == tourtable.middlecolumn.getlength()-1 || tourtable.middlecolumn.act.Data.data[0][x+1].datum != thisRecord.datum ) ? true : false;
|
|
329
|
+
if ( !pDay || thisDateIndex == pDay || createDate == thisDateIndex ) { // pdate not given or this is the given date
|
|
330
|
+
tourtable.leftcolumn.datecache[thisDateIndex] += tourtable.leftcolumnline.make( thisRecord.id, ( myLastDate == thisRecord.datum ? false : true ), myNextDate, myDate, thisRecord.ort );
|
|
331
|
+
}
|
|
332
|
+
myLastDate = thisRecord.datum;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
myRows = tourtable.leftcolumn.datecache.join('');
|
|
336
|
+
|
|
337
|
+
myNewRegEx = new RegExp('%tourtableleftrows%');
|
|
338
|
+
myHtml = myHtml.replace(myNewRegEx, myRows);
|
|
339
|
+
|
|
340
|
+
//tb.div.replace(pDivId,myHtml);
|
|
341
|
+
tb.misc.innerHTML(pDivId,myHtml);
|
|
342
|
+
|
|
343
|
+
tourtable.leftcolumn.showcounter = 0;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
};
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
This is the example code they referred to on ajaxian.com:
|
|
350
|
+
|
|
351
|
+
```javascript
|
|
352
|
+
index = {};
|
|
353
|
+
|
|
354
|
+
user = {};
|
|
355
|
+
|
|
356
|
+
tourtable = {};
|
|
357
|
+
|
|
358
|
+
index.index_body = {
|
|
359
|
+
|
|
360
|
+
init: function (pDivId) {
|
|
361
|
+
tb.element.require(
|
|
362
|
+
[ [ 'css', 'index', 'index_body'],
|
|
363
|
+
[ 'tpl', 'index', 'index_body']
|
|
364
|
+
],
|
|
365
|
+
'index.index_body.display("' + pDivId + '")',
|
|
366
|
+
true );
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
display: function (pDivId) {
|
|
370
|
+
var myHtml = tb.loader.tplget('index','index_body');
|
|
371
|
+
tb.div.replace( pDivId, myHtml );
|
|
372
|
+
tb.element.require(
|
|
373
|
+
[ [ 'js', 'tourtable', 'ddata'] ,
|
|
374
|
+
[ 'js', 'tourtable', 'rightcolumn'] ,
|
|
375
|
+
[ 'js', 'tourtable', 'leftcolumn'] ,
|
|
376
|
+
[ 'js', 'tourtable', 'leftcolumnline'] ,
|
|
377
|
+
[ 'js', 'tourtable', 'middlecolumn1line'] ,
|
|
378
|
+
[ 'js', 'tourtable', 'middlecolumn2line'] ,
|
|
379
|
+
[ 'js', 'tourtable', 'middlecolumn3line'] ,
|
|
380
|
+
[ 'js', 'tourtable', 'middlecolumn1'] ,
|
|
381
|
+
[ 'js', 'tourtable', 'middlecolumn2'] ,
|
|
382
|
+
[ 'js', 'tourtable', 'middlecolumn3'] ,
|
|
383
|
+
[ 'js', 'user', 'user_login'] ,
|
|
384
|
+
[ 'js', 'tb', 'pos'] ,
|
|
385
|
+
[ 'js', 'tb', 'md5'] ,
|
|
386
|
+
[ 'js', 'tb', 'tbDate'] ,
|
|
387
|
+
[ 'js', 'tb', 'tbCurrency'] ,
|
|
388
|
+
[ 'css', 'tourtable', 'middlecolumn'] ,
|
|
389
|
+
[ 'css', 'tourtable', 'rightcolumn'] ,
|
|
390
|
+
[ 'css', 'tourtable', 'leftcolumn'] ,
|
|
391
|
+
[ 'css', 'tourtable', 'leftcolumnline'] ,
|
|
392
|
+
[ 'css', 'tourtable', 'middlecolumn1'] ,
|
|
393
|
+
[ 'css', 'tourtable', 'middlecolumn2'] ,
|
|
394
|
+
[ 'css', 'tourtable', 'middlecolumn3'] ,
|
|
395
|
+
[ 'css', 'tourtable', 'middlecolumn1line'] ,
|
|
396
|
+
[ 'css', 'tourtable', 'middlecolumn2line'] ,
|
|
397
|
+
[ 'css', 'tourtable', 'middlecolumn3line'] ,
|
|
398
|
+
[ 'tpl', 'tourtable', 'rightcolumn'] ,
|
|
399
|
+
[ 'tpl', 'tourtable', 'leftcolumn'] ,
|
|
400
|
+
[ 'tpl', 'tourtable', 'leftcolumnline'] ,
|
|
401
|
+
[ 'tpl', 'tourtable', 'middlecolumn1line'] ,
|
|
402
|
+
[ 'tpl', 'tourtable', 'middlecolumn2line'] ,
|
|
403
|
+
[ 'tpl', 'tourtable', 'middlecolumn3line'] ,
|
|
404
|
+
[ 'tpl', 'tourtable', 'middlecolumn1'] ,
|
|
405
|
+
[ 'tpl', 'tourtable', 'middlecolumn2'] ,
|
|
406
|
+
[ 'tpl', 'tourtable', 'middlecolumn3'] ,
|
|
407
|
+
[ 'tpl', 'tourtable', 'middlecolumn'] ,
|
|
408
|
+
[ 'js', 'tourtable', 'middlecolumn']
|
|
409
|
+
] );
|
|
410
|
+
tb.element.show( 'toprightcontainer', 'user', 'user_login' );
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
When I find the time I will turn into standalone web component using local storage, since it is a historic archievement IMHO. For now I have more pressing tasks to do.
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
## The Fallout
|
|
421
|
+
|
|
422
|
+
I am an autist, which I didn't know back then BTW.
|
|
423
|
+
|
|
424
|
+
Above all that means, if you focus on something, you keep focussed for life. And I focused on twoBirds, really.
|
|
425
|
+
|
|
426
|
+
So I was burnt as a programmer, because I have a hard time working with the current standard frameworks.
|
|
427
|
+
|
|
428
|
+
Now try to find a programmer job without using standard frameworks.
|
|
429
|
+
|
|
430
|
+
In the end I lost my existence 3 times over the past 20 years, with all the consequences.
|
|
431
|
+
|
|
432
|
+
No pity requested, I always pulled myself out of the mud. Thats just the way things go. But if feel tempted, you can [fund this](https://gofund.me/076c614c).
|
|
433
|
+
|
|
434
|
+
I really want **Micro Components** to become a web standard also.
|
|
435
|
+
|
|
436
|
+
I don't regret still working on the basic idea. As long as I can, I will continue doing so.
|
|
File without changes
|
|
File without changes
|
|
@@ -52,7 +52,7 @@ It doesnt get more standard compliant than that.
|
|
|
52
52
|
|
|
53
53
|
## Things I already did with this, in my own framework twoBirds, or in apps that I developed with it:
|
|
54
54
|
|
|
55
|
-
- `
|
|
55
|
+
- `encapsulated and modular 3D rendering` in an HTMLElement viewport.
|
|
56
56
|
- `Data Driven Workflow` with micro components using tB specific observables.
|
|
57
57
|
- `DOM handling` in general, lots of `UI functionality`
|
|
58
58
|
- `2 way Data Binding` between forms and observable objects representing the form data
|
|
Binary file
|
|
Binary file
|
|
Binary file
|