spyne 0.19.1 → 0.20.0

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.
Files changed (129) hide show
  1. package/.eslintrc.js +4 -3
  2. package/.travis.yml +24 -11
  3. package/karma.conf.js +76 -86
  4. package/lib/spyne.esm.js +15 -0
  5. package/lib/spyne.esm.js.map +1 -0
  6. package/lib/spyne.umd.js +9565 -0
  7. package/package.json +47 -27
  8. package/rollup.config.js +26 -0
  9. package/src/spyne/channels/channel-fetch-class.js +39 -43
  10. package/src/spyne/channels/channel-payload-class.js +61 -74
  11. package/src/spyne/channels/channel-proxy.js +25 -26
  12. package/src/spyne/channels/channel.js +141 -149
  13. package/src/spyne/channels/channels-config.js +46 -47
  14. package/src/spyne/channels/channels-map.js +61 -65
  15. package/src/spyne/channels/spyne-channel-lifecycle.js +12 -12
  16. package/src/spyne/channels/spyne-channel-route.js +241 -250
  17. package/src/spyne/channels/spyne-channel-ui.js +213 -75
  18. package/src/spyne/channels/spyne-channel-window.js +157 -157
  19. package/src/spyne/spyne-app.js +32 -19
  20. package/src/spyne/spyne-plugins.js +55 -70
  21. package/src/spyne/spyne.js +23 -23
  22. package/src/spyne/utils/channel-config-validator.js +10 -10
  23. package/src/spyne/utils/channel-fetch-util.js +72 -55
  24. package/src/spyne/utils/channel-payload-filter.js +89 -100
  25. package/src/spyne/utils/deep-merge.js +31 -29
  26. package/src/spyne/utils/frp-tools.js +108 -92
  27. package/src/spyne/utils/gc.js +6 -6
  28. package/src/spyne/utils/mixins/base-core-mixins.js +17 -15
  29. package/src/spyne/utils/mixins/base-streams-mixins.js +9 -9
  30. package/src/spyne/utils/route-channel-updater.js +23 -29
  31. package/src/spyne/utils/safe-clone.js +40 -58
  32. package/src/spyne/utils/sanitize-html.js +35 -0
  33. package/src/spyne/utils/security-policy.js +11 -0
  34. package/src/spyne/utils/spyne-app-properties.js +110 -114
  35. package/src/spyne/utils/spyne-logger.js +4 -11
  36. package/src/spyne/utils/spyne-plugins-methods.js +38 -63
  37. package/src/spyne/utils/spyne-trait.js +33 -33
  38. package/src/spyne/utils/spyne-utils-channel-route-url.js +229 -153
  39. package/src/spyne/utils/spyne-utils-channel-route.js +128 -138
  40. package/src/spyne/utils/spyne-utils-channel-window.js +39 -39
  41. package/src/spyne/utils/viewstream-animations.js +12 -12
  42. package/src/spyne/utils/viewstream-observables.js +45 -45
  43. package/src/spyne/views/dom-element-template.js +111 -114
  44. package/src/spyne/views/dom-element.js +82 -84
  45. package/src/spyne/views/view-stream-broadcaster.js +66 -62
  46. package/src/spyne/views/view-stream-element.js +105 -106
  47. package/src/spyne/views/view-stream-payload.js +25 -27
  48. package/src/spyne/views/view-stream-selector.js +157 -163
  49. package/src/spyne/views/view-stream.js +416 -640
  50. package/src/tests/channels/channel-dom.test.js +15 -15
  51. package/src/tests/channels/channel-fetch.test.js +51 -62
  52. package/src/tests/channels/channel-payload-class.test.js +50 -63
  53. package/src/tests/channels/channel-payload-filter.test.js +133 -193
  54. package/src/tests/channels/channel-route.test.js +102 -112
  55. package/src/tests/channels/channel-stream-item.test.js +19 -19
  56. package/src/tests/channels/channel-ui.test.js +15 -27
  57. package/src/tests/channels/channel-util-dom.test.js +31 -31
  58. package/src/tests/channels/channel.test.js +20 -25
  59. package/src/tests/channels/route-utils.test.js +61 -66
  60. package/src/tests/channels/url-utils.test.js +151 -151
  61. package/src/tests/channels/view-stream-broadcaster.test.js +7 -7
  62. package/src/tests/import.test.js +5 -5
  63. package/src/tests/index.js +6 -7
  64. package/src/tests/index.test.js +6 -8
  65. package/src/tests/mocks/channel-payload-data.js +218 -220
  66. package/src/tests/mocks/enhancer.test.js +5 -5
  67. package/src/tests/mocks/payload-ui.js +87 -90
  68. package/src/tests/mocks/routes-data.js +264 -266
  69. package/src/tests/mocks/spyne-docs.mocks.js +3 -3
  70. package/src/tests/mocks/template-renderer.mocks.js +47 -47
  71. package/src/tests/mocks/utils-data.js +78 -79
  72. package/src/tests/mocks/viewstream-internal-payload.mocks.js +50 -50
  73. package/src/tests/mocks/window-events-arr.js +1 -1
  74. package/src/tests/package-json.spec.test.js +9 -0
  75. package/src/tests/spyne-app.test.js +15 -18
  76. package/src/tests/spyne-plugin.test.js +16 -20
  77. package/src/tests/utils/channel-action-filter.test.js +84 -86
  78. package/src/tests/utils/channel-data-packet-generator.unused.js +62 -86
  79. package/src/tests/utils/channel-fetch-util.test.js +64 -66
  80. package/src/tests/utils/frp-tools.test.js +19 -19
  81. package/src/tests/utils/plugins-methods.test.js +31 -55
  82. package/src/tests/utils/security.test.js +10 -0
  83. package/src/tests/utils/spyne-app-properties.test.js +4 -8
  84. package/src/tests/views/dom-el-selectors.test.js +112 -119
  85. package/src/tests/views/dom-el-template-proxy.test.js +7 -0
  86. package/src/tests/views/dom-el-template.test.js +186 -156
  87. package/src/tests/views/dom-el.test.js +58 -56
  88. package/src/tests/views/view-stream-enhancer-loader.test.js +2 -2
  89. package/src/tests/views/view-stream-enhancer.test.js +11 -11
  90. package/src/tests/views/view-stream.test.js +22 -33
  91. package/webpack.config.js +76 -67
  92. package/docs/-_%20Solves%20equations%20of%20the%20form%20a%20_%20x%20=%20b.html +0 -487
  93. package/docs/DomItem.html +0 -298
  94. package/docs/DomItem_DomItem.html +0 -314
  95. package/docs/ViewStream.html +0 -2249
  96. package/docs/ViewStream_ViewStream.html +0 -503
  97. package/docs/custom/css/jsdoc-viewstream.css +0 -377
  98. package/docs/custom/layout.tmpl +0 -47
  99. package/docs/dom-item.js.html +0 -213
  100. package/docs/fonts/OpenSans-Bold-webfont.eot +0 -0
  101. package/docs/fonts/OpenSans-Bold-webfont.svg +0 -1830
  102. package/docs/fonts/OpenSans-Bold-webfont.woff +0 -0
  103. package/docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  104. package/docs/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
  105. package/docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  106. package/docs/fonts/OpenSans-Italic-webfont.eot +0 -0
  107. package/docs/fonts/OpenSans-Italic-webfont.svg +0 -1830
  108. package/docs/fonts/OpenSans-Italic-webfont.woff +0 -0
  109. package/docs/fonts/OpenSans-Light-webfont.eot +0 -0
  110. package/docs/fonts/OpenSans-Light-webfont.svg +0 -1831
  111. package/docs/fonts/OpenSans-Light-webfont.woff +0 -0
  112. package/docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  113. package/docs/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
  114. package/docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  115. package/docs/fonts/OpenSans-Regular-webfont.eot +0 -0
  116. package/docs/fonts/OpenSans-Regular-webfont.svg +0 -1831
  117. package/docs/fonts/OpenSans-Regular-webfont.woff +0 -0
  118. package/docs/global.html +0 -548
  119. package/docs/index-custom.html +0 -79
  120. package/docs/index.html +0 -82
  121. package/docs/jsdoc.config.json +0 -22
  122. package/docs/scripts/linenumber.js +0 -25
  123. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  124. package/docs/scripts/prettify/lang-css.js +0 -2
  125. package/docs/scripts/prettify/prettify.js +0 -28
  126. package/docs/styles/jsdoc-default.css +0 -358
  127. package/docs/styles/prettify-jsdoc.css +0 -111
  128. package/docs/styles/prettify-tomorrow.css +0 -132
  129. package/docs/view-stream.js.html +0 -767
@@ -1,767 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>JSDoc: Source: view-stream.js</title>
6
- <link href="https://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
7
-
8
- <script src="scripts/prettify/prettify.js"> </script>
9
- <script src="scripts/prettify/lang-css.js"> </script>
10
- <!--[if lt IE 9]>
11
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
12
- <![endif]-->
13
- <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
14
- <!--
15
- <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
16
- -->
17
- <link type="text/css" rel="stylesheet" href="custom/css/jsdoc-viewstream.css">
18
-
19
-
20
- </head>
21
-
22
- <body>
23
-
24
- <div id="main">
25
- <a class="page-title spyne" href='https://www.npmjs.com/package/spyne' target='blank'>spyne</a>
26
-
27
- <!--
28
- <h1 class="page-title">Source: view-stream.js</h1>
29
- -->
30
-
31
-
32
-
33
-
34
-
35
-
36
- <section>
37
- <article>
38
- <pre class="prettyprint source linenums"><code>import {BaseCoreMixins} from '../utils/mixins/base-core-mixins';
39
- import {BaseStreamsMixins} from '../utils/mixins/base-streams-mixins';
40
- import {ifNilThenUpdate, convertDomStringMapToObj} from '../utils/frp-tools';
41
- // import {gc} from '../utils/gc';
42
- import {ViewStreamElement} from './basic-view';
43
- import {registeredStreamNames} from '../channels/channels-config';
44
- import {ViewStreamBroadcaster} from './view-stream-broadcaster';
45
- import {ViewStreamPayload} from '../channels/channels-payload';
46
- import {ViewStreamObservable} from '../utils/lifecycle-observables';
47
-
48
- const Rx = require('rxjs');
49
- const R = require('ramda');
50
-
51
- export class ViewStream {
52
- /**
53
- * @module ViewStream
54
- *
55
- * @desc
56
- * The ViewStream object creates or references a dom elment; the dom element can be as simple as a &amp;#60;p&amp;gt; tag, or the dom element can be a large dom chunk that is generated from data and an html template.
57
- * &lt;br>&lt;br>
58
- * Generally, the idea is to extend the ViewStream class and add the custom values within the constructor function, but all of the values can be passed as parameters as well.
59
- *
60
- * @example
61
- * // returns &lt;h2>Hello World&lt;/h2>
62
- * new ViewStream({tagName:'h2', data:'Hello World'};
63
- * @example
64
- * // returns
65
- * &lt;ul>
66
- * &lt;li>firstName: Jane&lt;li>
67
- * &lt;li>lastName: Doe&lt;li>
68
- * &lt;li>Age: 23&lt;li>
69
- * &lt;/ul>
70
- *
71
- * let myTemplate = '&lt;li>firstName: {{fName}}&lt;li>lastName: {{lName}}&lt;li>Age: {{age}}';
72
- * let myData = {fName: Jane, lName: Doe, age:23};
73
- * new ViewStream({tagName:'ul', data:myData, tmpl:myTemplate});
74
- *
75
- *
76
- *
77
- * @constructor
78
- * @param {object} props This json object takes in parameters to generate or reference the dom element
79
- * @property {string} props.tagName - 'div' This can be any dom tag
80
- * @property {domItem} props.el undefined, if defined, ViewStream will connect to that element
81
- * @property {string|object} props.data undefined, // string for innerText or Json object for html template
82
- * @property {boolean} props.animateIn - false, animates in View
83
- * @property {number} props.animateInTime - .5
84
- * @property {boolean} props.animateOut false, animates in View
85
- * @property {number} props.animateOutTime .5
86
- * @property {string} props.id - undefined, generates a random id if left undefined
87
- * @property {boolean} props.debug false
88
- * @property {tmpl} props.tmpl undefined, // html template
89
- *
90
- */
91
- constructor(props = {}) {
92
- this.addMixins();
93
- this.defaults = () => {
94
- let id = props.id ? props.id : this.createId();
95
- return {
96
- tagName: 'div',
97
- el: undefined,
98
- data: undefined,
99
- animateIn:false,
100
- animateInTime: 0.5,
101
- animateOut: false,
102
- animateOutTime: 0.5,
103
- cid: this.createId(),
104
- id: id,
105
- hashId: `#${id}`,
106
- viewClass: ViewStreamElement,
107
- extendedSourcesHashMethods: {},
108
- debug: false,
109
- tmpl: undefined,
110
- node: document.createDocumentFragment(),
111
- name: this.constructor.name
112
- };
113
- };
114
- this._state = {};
115
- this.$dirs = ViewStreamObservable.createDirectionalFiltersObject();
116
- this.addDefaultDirection = ViewStreamObservable.addDefaultDir;
117
- this.addDownInternalDir = ViewStreamObservable.addDownInternalDir;
118
- this.props = Object.assign({}, this.defaults(), props);
119
- this.props['domAttributes'] = R.pick(['id', 'class', 'dataset'], this.props);
120
-
121
- const channelFn = R.curry(this.onChannelMethodCall.bind(this));
122
- let createExtraStatesMethod = (arr) => {
123
- let [action, funcStr] = arr;
124
- this.props.extendedSourcesHashMethods[action] = channelFn(funcStr);
125
- };
126
- this.extendedStateMethods().forEach(createExtraStatesMethod);
127
- this.props.hashSourceMethods = this.setSourceHashMethods(this.props.extendedSourcesHashMethods);
128
- this.props.action = 'LOADED';
129
- this.sink$ = new Rx.Subject();
130
- const ViewClass = this.props.viewClass;
131
- this.view = new ViewClass(this.sink$);// new this.props.viewClass(this.sink$);
132
- this.sourceStreams = this.view.sourceStreams;
133
- this._rawSource$ = this.view.getSourceStream();
134
- this._rawSource$['viewName'] = this.props.name;
135
- this.sendEventsDownStream = this.sendEventsDownStreamFn;
136
- this.init();
137
- this.checkIfElementAlreadyExists();
138
- }
139
- checkIfElementAlreadyExists() {
140
- const elIsDomElement = el => el !== undefined &amp;&amp; el.tagName !== undefined;
141
- const elIsRendered = el => document.body.contains(el);
142
- const elIsReadyBool = R.propSatisfies(R.allPass([elIsRendered, elIsDomElement]), 'el');
143
- if (elIsReadyBool(this.props)) {
144
- this.afterRender();
145
- }
146
- }
147
-
148
- extendedStateMethods() {
149
- return [];
150
- }
151
-
152
- onChannelMethodCall(str, p) {
153
- // console.log('channelMethodCalled ', p);
154
- if (p.$dir !== undefined &amp;&amp; p.$dir.includes('child')) {
155
- // p.$dir = ['internal'];
156
- // this.sourceStreams.toChild$.next(p);
157
-
158
- let obj = Object.assign({}, p);
159
- // obj['action'] = action;
160
- obj['$dir'] = this.$dirs.C;
161
- // console.log('SEND DOWN ', obj);
162
- this.sourceStreams.raw$.next(obj);
163
-
164
- // this.sendEventsDownStreamFn('HOLDER_ROUTE_EVENT', p);
165
- }
166
-
167
- this[str](p);
168
- }
169
-
170
- setSourceHashMethods(extendedSourcesHashMethods = {}) {
171
- let hashSourceKeys = {
172
- // 'PARENT_DISPOSING' : (p) => this.onDispose(p),
173
- 'DISPOSE' : (p) => this.onDispose(p),
174
- // 'CHILD_DISPOSE' : (p) => this.onDispose(p),
175
- 'RENDERED' : (p) => this.onRendered(p),
176
- 'RENDERED_AND_ATTACHED_TO_DOM' : (p) => this.onRendered(p),
177
- 'RENDERED_AND_ATTACHED_TO_PARENT' : (p) => this.onRendered(p),
178
- // 'CHILD_RENDERED' : (p) => this.attachChildToView(p),
179
- 'READY_FOR_GC' : (p) => this.onReadyToGC(p),
180
- 'NOTHING' : () => ({})
181
- };
182
- return Object.assign({}, hashSourceKeys, extendedSourcesHashMethods);
183
- }
184
-
185
- // =====================================================================
186
- // ====================== MAIN STREAM METHODS ==========================
187
- init() {
188
- this._source$ = this._rawSource$
189
- .map((payload) => this.onMapViewSource(payload))
190
- .takeWhile(this.notGCSTATE);
191
-
192
- this.initAutoMergeSourceStreams();
193
- this.updateSourceSubscription(this._source$, true);
194
- }
195
-
196
- notGCSTATE(p) {
197
- return !p.action.includes('READY_FOR_GC');
198
- }
199
-
200
- eqGCSTATE(p) {
201
- return !p.action.includes('READY_FOR_GC');
202
- }
203
- notCOMPLETED(p) {
204
- return !p.action.includes('COMPLETED');
205
- }
206
- notGCCOMPLETE(p) {
207
- return !p.action.includes('GC_COMPLETE');
208
- }
209
-
210
- testVal(p) {
211
- console.log('TESTING VALL IS ', p);
212
- }
213
-
214
- addParentStream(obs, attachData) {
215
- let filterOutNullData = (data) => data !== undefined &amp;&amp; data.action !== undefined;
216
- let checkIfDisposeOrFadeout = (d) => {
217
- let data = Object.assign({}, d);
218
-
219
- if (data.action === 'DISPOSE_AND_READY_FOR_GC') {
220
- this.onDispose(data);
221
- data.action = 'READY_FOR_GC';
222
- }
223
- return data;
224
- };
225
-
226
- this.parent$ = obs
227
- .filter(filterOutNullData)
228
- .map(checkIfDisposeOrFadeout)
229
- .takeWhile(this.notGCCOMPLETE);
230
- this.updateSourceSubscription(this.parent$, false, 'PARENT');
231
- this.renderAndAttachToParent(attachData);
232
- }
233
-
234
- addChildStream(obs$) {
235
- let filterOutNullData = (data) => data !== undefined &amp;&amp; data.action !== undefined;
236
- let child$ = obs$
237
- .filter(filterOutNullData)
238
- .map((p) => {
239
- return p;
240
- })
241
- .takeWhile(this.notGCSTATE)
242
- .finally(p => this.onChildCompleted(child$.source));
243
- this.updateSourceSubscription(child$, true, 'CHILD');
244
- }
245
-
246
- onChildCompleted(p) {
247
- let findName = (x) => {
248
- let finalDest = (y) => {
249
- while (y.destination !== undefined) {
250
- y = finalDest(y.destination);
251
- }
252
- return y;
253
- };
254
- return finalDest(x).viewName;
255
- };
256
- // let childCompletedName = findName(p);
257
- return findName(p);
258
- }
259
-
260
- initAutoMergeSourceStreams() {
261
- // ====================== SUBSCRIPTION SOURCE =========================
262
- let subscriber = {
263
- next: this.onSubscribeToSourcesNext.bind(this),
264
- error: this.onSubscribeToSourcesError.bind(this),
265
- complete: this.onSubscribeToSourcesComplete.bind(this)
266
- };
267
- // let takeBeforeGCOld = (val) => val.action !== 'GARBAGE_COLLECTED';
268
- // let takeBeforeGC = (p) => !p.action.includes('READY_FOR_GC');
269
- // let mapToState = (val) => ({action:val});
270
- // =====================================================================
271
- // ========== METHODS TO CHECK FOR WHEN TO COMPLETE THE STREAM =========
272
- let completeAll = () => {
273
- this.uberSource$.complete();
274
- this.autoSubscriber$.complete();
275
- this.sink$.complete();
276
- this.props = undefined;
277
- };
278
- let decrementOnObservableClosed = () => {
279
- obsCount -= 1;
280
- if (obsCount === 0) {
281
- completeAll();
282
- }
283
- };
284
- // =====================================================================
285
- // ======================== INIT STREAM METHODS ========================
286
- let obsCount = 0;
287
- this.uberSource$ = new Rx.Subject();
288
- // ======================= COMPOSED RXJS OBSERVABLE ======================
289
- /* let addRelationToState = (pre, str) => {
290
- let prefix = pre !== undefined ? pre + '_' : '';
291
- return prefix + str;
292
- }; */
293
- let incrementObservablesThatCloses = () => { obsCount += 1; };
294
- this.autoMergeSubject$ = this.uberSource$
295
- .mergeMap((obsData) => {
296
- let branchObservable$ = obsData.observable
297
- .filter((p) => p !== undefined &amp;&amp; p.action !== undefined)
298
- .map(p => {
299
- // console.log('PAYLOAD IS ', p, this.constructor.name)
300
- let payload = Object.assign({}, p);
301
- payload.action = p.action;// addRelationToState(obsData.rel, p.action);
302
- return payload;
303
- });
304
-
305
- if (obsData.autoClosesBool === false) {
306
- return branchObservable$;
307
- } else {
308
- incrementObservablesThatCloses();
309
- return branchObservable$
310
- .finally(decrementOnObservableClosed);
311
- }
312
- });
313
- // ============================= SUBSCRIBER ==============================
314
- this.autoSubscriber$ = this.autoMergeSubject$
315
- // .do((p) => console.log('SINK DATA ', this.constructor.name, p))
316
- .filter((p) => p !== undefined &amp;&amp; p.action !== undefined)
317
- .subscribe(subscriber);
318
- }
319
- // ========================= MERGE STREAMS TO MAIN SUBSCRIBER =================
320
- updateSourceSubscription(obs$, autoClosesBool = false, rel) {
321
- // const directionArr = sendDownStream === true ? this.$dirs.DI : this.$dirs.I;
322
-
323
- /*
324
- let obs$1 = obs$
325
- .map(ViewStreamObservable.addDefaultDir);
326
- */
327
-
328
- let obj = {
329
- observable: obs$,
330
- autoClosesBool,
331
- rel
332
- };
333
- this.uberSource$.next(obj);
334
- }
335
- // ============================= SUBSCRIBER METHODS ==============================
336
- onSubscribeToSourcesNext(payload = {}) {
337
- let defaultToFn = R.defaultTo((p) => this.sendExtendedStreams(p));
338
-
339
- const hashAction = this.props.hashSourceMethods[payload.action];
340
- // console.log('S PAYLOAD ', this.props.name, typeof (hashAction), payload);
341
-
342
- let fn = defaultToFn(hashAction);
343
- fn(payload);
344
- // console.log(fn, payload, ' THE PAYLOAD FROM SUBSCRIBE IS ', ' ---- ', ' ---> ', this.props);
345
- }
346
- onSubscribeToSourcesError(payload = '') {
347
- console.log('ALL ERROR ', this.constructor.name, payload);
348
- }
349
-
350
- onSubscribeToSourcesComplete() {
351
- // console.log('==== ALL COMPLETED ====', this.constructor.name);
352
- this.openSpigot('GARBAGE_COLLECT');
353
- }
354
- // =======================================================================================
355
- // ============================= HASH KEY AND SPIGOT METHODS==============================
356
- get source$() {
357
- return this._source$;
358
- }
359
-
360
- sendExtendedStreams(payload) {
361
- this.openSpigot(payload.actionz, payload);
362
- }
363
- // ===================================== RENDER METHODS ==================================
364
- renderAndAttachToParent(attachData) {
365
- // let childRenderData = attachData;
366
- this.openSpigot('RENDER_AND_ATTACH_TO_PARENT', attachData);
367
- }
368
-
369
- renderView() {
370
- this.openSpigot('RENDER');
371
- }
372
- renderViewAndAttachToDom(node, type, attachType) {
373
- let attachData = {node, type, attachType};
374
- this.openSpigot('RENDER_AND_ATTACH_TO_DOM', {attachData});
375
- }
376
-
377
- attachChildToView(data) {
378
- // let childRenderData = data.attachData;
379
- // console.log('CHILD DATA ', this.constructor.name, childRenderData);
380
- // this.openSpigot('ATTACH_CHILD_TO_SELF', {childRenderData});
381
- }
382
-
383
- // ===================================== DISPOSE METHODS =================================
384
- onDispose(p) {
385
- this.openSpigot('DISPOSE');
386
- }
387
-
388
- onChildDispose(p) {
389
- }
390
-
391
- onParentDisposing(p) {
392
- // this.updateSourceSubscription(this._source$);
393
- this.openSpigot('DISPOSE');
394
- }
395
- onReadyToGC(p) {
396
- this.openSpigot('GARBAGE_COLLECT');
397
- }
398
- // ===================================== SINK$ METHODS =================================
399
-
400
- sendEventsDownStreamFn(o, action = {}) {
401
- // console.log('OBJ ACTION ', o, action);
402
- let obj = Object.assign({action}, o);
403
- // obj['action'] = action;
404
- obj['$dir'] = this.$dirs.C;
405
- // console.log('OBJ FINAL ', obj);
406
- this.sourceStreams.raw$.next(obj);
407
- }
408
-
409
- openSpigot(action, obj = {}) {
410
- if (this.props !== undefined) {
411
- this.props.action = action;
412
- let data = R.merge(this.props, obj);
413
- this.sink$
414
- .next(Object.freeze(data));
415
- }
416
- }
417
-
418
- setAttachData(attachType, query) {
419
- return {
420
- node: this.props.el,
421
- type: 'ViewStreamElement',
422
- attachType,
423
- query: this.props.el.querySelector(query)
424
- };
425
- }
426
-
427
- getParentEls(el, num) {
428
- let getElem = el => el.parentElement;
429
- let iter = 0;
430
- let parentEl = el;
431
- while (iter &lt; num) {
432
- parentEl = getElem(parentEl);
433
- iter++;
434
- }
435
- return parentEl;
436
- }
437
-
438
- setAttachParentData(attachType, query, level) {
439
- return {
440
- node: this.getParentEls(this.props.el, level),
441
- type: 'ViewStreamElement',
442
- attachType,
443
- query: this.props.el.parentElement.querySelector(query)
444
- };
445
- }
446
-
447
- onMapViewSource(payload = {}) {
448
- this.props = R.merge(this.props, payload);
449
- return payload;
450
- }
451
-
452
- // ====================== ATTACH STREAM AND DOM DATA AGGREGATORS==========================
453
- exchangeViewsWithChild(childView, attachData) {
454
- this.addChildStream(childView.sourceStreams.toParent$);
455
- childView.addParentStream(this.sourceStreams.toChild$, attachData);
456
- }
457
- /**
458
- * Appends a ViewStream object to an existing dom element.
459
- * @param {dom} node the ViewStream child that is to be attached.
460
- *
461
- * @example
462
- * // returns
463
- * &lt;body>
464
- * &lt;h2>Hello World&lt;/h2>
465
- * &lt;/body>
466
- *
467
- * let viewStream = new ViewStream('h2', 'Hello World');
468
- * viewStream.appendToDom(document.body);
469
- *
470
- */
471
- appendToDom(node) {
472
- this.renderViewAndAttachToDom(node, 'dom', 'appendChild');
473
- }
474
-
475
- /**
476
- * Prepends the current ViewStream object to an existing dom element.
477
- * @param {dom} node the ViewStream child that is to be attached.
478
- *
479
- * @example
480
- * this.prependToDom(document.body);
481
- *
482
- */
483
-
484
- prependToDom(node) {
485
- this.renderViewAndAttachToDom(node, 'dom', 'prependChild');
486
- }
487
- /**
488
- * This method appends a child ViewStream object. &lt;br>After the attachment, rxjs observables are exchanged between the parent and child ViewStream objects.&lt;br>&lt;br>
489
- * @param {ViewStream} v the ViewStream child that is to be attached.
490
- * @param {string} query a querySelector within this ViewStream.
491
- *
492
- * @example
493
- * // returns
494
- * &lt;body>
495
- * &lt;main>
496
- * &lt;h2>Hello World&lt;/h2>
497
- * &lt;/main>
498
- * &lt;/body>
499
- *
500
- *
501
- * let parentView = new ViewStream('main');
502
- * parentView.appendToDom(document.body);
503
- *
504
- * let childView = new ViewStream({tagName:'h2', data:'Hello World'};
505
- * parentView.appendView(childView)
506
- *
507
- * */
508
- appendView(v, query) {
509
- this.exchangeViewsWithChild(v, this.setAttachData('appendChild', query));
510
- }
511
-
512
- /**
513
- * This method appends a child ViewStream object to a parent ViewStream object.
514
- * @param {ViewStream} v the ViewStream parent.
515
- * @param {string} query a querySelector within this ViewStream.
516
- * @param {level} this parameters can attach the viewStream's dom element up the dom tree while still maintaining the parent-child relationship of the ViewStream objects.
517
- *
518
- * @example
519
- * // returns
520
- * &lt;body>
521
- * &lt;main>
522
- * &lt;h2>Hello World&lt;/h2>
523
- * &lt;/main>
524
- * &lt;/body>
525
- *
526
- *
527
- * let parentView = new ViewStream('main');
528
- * parentView.appendToDom(document.body);
529
- *
530
- * let childView = new ViewStream({tagName:'h2', data:'Hello World'};
531
- * childView.appendToParent(parentView)
532
- *
533
- * */
534
-
535
- appendViewToParent(v, query, level = 1) {
536
- this.exchangeViewsWithChild(v, this.setAttachParentData('appendChild', query, level));
537
- }
538
-
539
- /**
540
- * This method prepends a child ViewStream object to a parent ViewStream object.
541
- * @param {ViewStream} v the ViewStream parent.
542
- * @param {string} query a querySelector within this ViewStream.
543
- * @param {number} level this parameter can attach the viewStream's dom element up the dom tree while still maintaining the parent-child relationship of the ViewStream objects.
544
- *
545
- * @example
546
- * let parentView = new ViewStream('main');
547
- * parentView.prependToDom(document.body);
548
- *
549
- * let childView = new ViewStream({tagName:'h2', data:'Hello World'};
550
- * childView.prependViewToParent(parentView)
551
- *
552
- * */
553
- prependViewToParent(v, query, level = 1) {
554
- this.exchangeViewsWithChild(v, this.setAttachParentData('prependChild', query, level));
555
- }
556
-
557
- /**
558
- *
559
- *
560
- * This method prepends a child ViewStream object to the current ViewStream object. &lt;br>After the attachment, rxjs observables are exchanged between the parent and child ViewStream objects.&lt;br>&lt;br>
561
- * @param {ViewStream} v the ViewStream child that is to be attached.
562
- * @param {string} query a querySelector within this ViewStream.
563
- *
564
- * @example
565
- * // returns
566
- * &lt;body>
567
- * &lt;main>
568
- * &lt;h2>Hello World&lt;/h2>
569
- * &lt;/main>
570
- * &lt;/body>
571
- *
572
- * let parentView = new ViewStream('main');
573
- * parentView.appendToDom(document.body);
574
- *
575
- * let childView = new ViewStream({tagName:'h2', data:'Hello World'};
576
- * parentView.prependView(childView);
577
- *
578
- * */
579
-
580
- prependView(v, query) {
581
- this.exchangeViewsWithChild(v, this.setAttachData('prependChild', query));
582
- }
583
-
584
- onRendered(payload) {
585
- // console.log('RENDER: ', this.props.name, payload);
586
- if (payload.from$ === 'internal') {
587
- this.viewsStreamBroadcaster = new ViewStreamBroadcaster(this.props, this.broadcastEvents);
588
- // this.props['el'] = payload.el.el;
589
- this.afterRender();
590
- }
591
- }
592
-
593
- // ================================= METHODS TO BE EXTENDED ==============================
594
- /**
595
- *
596
- * This method is called once the ViewStream's domElement has been rendered and attached to the dom.
597
- * &lt;br>
598
- * This method is empty and is meant to be overridden.
599
- *
600
- * */
601
-
602
- afterRender() {
603
- }
604
-
605
- /**
606
- *
607
- * Add any query within the ViewStream's dom and any dom events to automatically be observed by the UI Channel.
608
- * &lt;br>
609
- * @example
610
- *
611
- * broadcastEvents() {
612
- * // ADD BUTTON EVENTS AS NESTED ARRAYS
613
- * return [
614
- * ['#my-button', 'mouseover'],
615
- * ['#my-input', 'change']
616
- * ]
617
- * }
618
- *
619
- *
620
- * */
621
-
622
- broadcastEvents() {
623
- // ADD BUTTON EVENTS AS NESTED ARRAYS
624
- return [
625
- ];
626
- }
627
-
628
- /**
629
- *
630
- * Automatically connect to an instance of registered channels, such as 'DOM', 'UI', and 'ROUTE' channels.
631
- *
632
- *
633
- * @example
634
- *
635
- * let uiChannel = this.getChannel('UI');
636
- *
637
- * uiChannel
638
- * .filter((p) => p.data.id==='#my-button')
639
- * .subscribe((p) => console.log('my button was clicked ', p));
640
- *
641
- * */
642
-
643
- getChannel(channel) {
644
- let isValidChannel = c => registeredStreamNames().includes(c);
645
- let error = c => console.warn(`channel name ${c} is not within ${registeredStreamNames}`);
646
- let startSubscribe = (c) => window.Spyne.channels.getStream(c).observer;// getGlobalParam('streamsController').getStream(c).observer;
647
-
648
- let fn = R.ifElse(isValidChannel, startSubscribe, error);
649
-
650
- return fn(channel);
651
- }
652
-
653
- /**
654
- *
655
- * Preferred method to connect to instances of registered channels, such as 'DOM', 'UI', and 'ROUTE' channels.
656
- *
657
- * Add Channel will automatically unsubscribe to the channel, whereas the getChannel method requires the developer to manually unsubscribe.
658
- *
659
- * @param {string} str The name of the registered Channel that was added to the Channels Controller.
660
- * @param {boolean} bool false, add true if the View should wait for this channel to unsubscribe before removing itself.
661
- * @param {sendDownStream} bool The direction where the stream is allowed to travel.
662
- *
663
- * @example
664
- *
665
- * let routeChannel = this.addChannel('ROUTE');
666
- *
667
- * extendedStateMethods() {
668
- * return [
669
- * ['CHANNEL_ROUTE_CHANGE_EVENT', 'onMapRouteEvent']
670
- * ]
671
- * }
672
- *
673
- * onMapRouteEvent(p) {
674
- * console.log('the route value is ', p);
675
- * }
676
- *
677
- *
678
- * */
679
-
680
- addChannel(str, sendDownStream = false, bool = false) {
681
- const directionArr = sendDownStream === true ? this.$dirs.CI : this.$dirs.I;
682
- const mapDirection = p => Object.assign({$dir:directionArr}, R.clone(p));
683
-
684
- let channel$ = this.getChannel(str)
685
- .map(mapDirection);
686
-
687
- this.updateSourceSubscription(channel$, false);
688
- /* console.log('added channel ', str, channel);
689
- let subscriber = {
690
- next: this.onSubscribeToSourcesNext.bind(this),
691
- error: this.onSubscribeToSourcesError.bind(this),
692
- complete: this.onSubscribeToSourcesComplete.bind(this)
693
- };
694
- channel
695
- .do(p => console.log('p in viewstream is ', p))
696
- .subscribe(subscriber); */
697
- }
698
-
699
- /**
700
- *
701
- * Method to send data to any registered channel.
702
- **
703
- * @param {string} channelName The name of the registered Channel that was added to the Channels Controller.
704
- * @param {string} action The event type that listeners can point to.
705
- * @param {object} payload {}, The main data to send to the channel.
706
- *
707
- * @example
708
- *
709
- * let payload = {'location' : 'about'};
710
- * let action = 'PAGE_CHANGE_EVENT';
711
- * this.sendChannelPayload('ROUTE', paylaod, action);
712
- *
713
- *
714
- *
715
- * */
716
-
717
- sendChannelPayload(channelName, action = 'DEFAULT_EVENT', payload = {}) {
718
- let cid = this.props.cid;
719
- let viewName = this.props.name;
720
- let data = {cid, viewName, payload, action};
721
- let obs$ = Rx.Observable.of(data);
722
- return new ViewStreamPayload(channelName, obs$, data);
723
- }
724
-
725
- // =======================================================================================
726
- addMixins() {
727
- // ==================================
728
- // BASE CORE MIXINS
729
- // ==================================
730
- let coreMixins = BaseCoreMixins();
731
- this.createId = coreMixins.createId;
732
- this.createpropsMap = coreMixins.createpropsMap;
733
- this.convertDomStringMapToObj = convertDomStringMapToObj;
734
- this.ifNilThenUpdate = ifNilThenUpdate;
735
- // this.gc = gc.bind(this);
736
- // ==================================
737
- // BASE STREAM MIXINS
738
- // ==================================
739
- let streamMixins = BaseStreamsMixins();
740
- this.sendUIPayload = streamMixins.sendUIPayload;
741
- this.sendRoutePayload = streamMixins.sendRoutePayload;
742
- this.createLifeStreamPayload = streamMixins.createLifeStreamPayload;
743
- }
744
- }
745
- </code></pre>
746
- </article>
747
- </section>
748
-
749
-
750
-
751
-
752
- </div>
753
-
754
- <nav>
755
- <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="DomItem.html">DomItem</a></li><li><a href="ViewStream.html">ViewStream</a></li></ul>
756
- </nav>
757
-
758
- <br class="clear">
759
-
760
- <footer>
761
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Fri Dec 15 2017 22:34:55 GMT-0500 (EST)
762
- </footer>
763
-
764
- <script> prettyPrint(); </script>
765
- <script src="scripts/linenumber.js"> </script>
766
- </body>
767
- </html>