spyne 0.18.3 → 0.19.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.
@@ -12,6 +12,7 @@ import {
12
12
  is
13
13
  } from 'ramda';
14
14
  import {SpyneAppProperties} from '../utils/spyne-app-properties';
15
+ import {safeClone} from '../utils/safe-clone';
15
16
 
16
17
  export class ChannelPayload {
17
18
  /**
@@ -76,15 +77,15 @@ export class ChannelPayload {
76
77
 
77
78
 
78
79
 
79
- channelPayloadItemObj.clone = () => clone(mergeAll([
80
- {payload:ChannelPayload.deepClone(channelPayloadItemObj.payload)},
80
+ channelPayloadItemObj.clone = () => mergeAll([
81
+ {payload:safeClone(channelPayloadItemObj.payload)},
81
82
  channelPayloadItemObj.payload,
82
- { channel },
83
- { event: event },
83
+ { channel: clone(channel) },
84
+ { event: clone(event) },
84
85
  {srcElement: srcElement},
85
- channelPayloadItemObj.srcElement, {
86
- action: channelPayloadItemObj.action }
87
- ]));
86
+ clone(channelPayloadItemObj.srcElement), {
87
+ action: clone(channelPayloadItemObj.action) }
88
+ ]);
88
89
 
89
90
 
90
91
 
@@ -84,7 +84,7 @@ export class Channel {
84
84
  this.checkForPersistentDataMode = Channel.checkForPersistentDataMode.bind(this);
85
85
  this.observer$ = this.props['observer'] = observer$;
86
86
  let dispatcherStream$ = this.streamsController.getStream('DISPATCHER');
87
- const payloadPredByChannelName = propEq('name', props.name)
87
+ const payloadPredByChannelName = propEq(props.name, 'name')
88
88
  dispatcherStream$.pipe(filter(payloadPredByChannelName)).subscribe((val) => this.onReceivedObservable(val));
89
89
  }
90
90
 
@@ -295,7 +295,7 @@ export class Channel {
295
295
  //console.log("INCOMING ",{action, payload, srcElement}, {obj});
296
296
  const mergeProps = (d) => mergeAll([d, { action: prop('action', d) }, prop('payload', d), prop('srcElement', d)]);
297
297
  let dataObj = obsVal => ({
298
- props: () => mergeProps(obj.data),
298
+ clone: () => mergeProps(obj.data),
299
299
  action, payload, srcElement,
300
300
  event: obsVal
301
301
  });
@@ -401,6 +401,13 @@ export class Channel {
401
401
  }
402
402
 
403
403
 
404
+ static checkForNotTrackFlag(props={}){
405
+ if (props.doNotTrack === true){
406
+ SpyneAppProperties.doNotTrackChannel(props.channelName);
407
+ }
408
+
409
+
410
+ }
404
411
 
405
412
 
406
413
 
@@ -45,8 +45,8 @@ export class ChannelsMap {
45
45
 
46
46
  static listRegisteredChannels(showOnlyProxies = false) {
47
47
  let proxyMap = this.getChannelsList();
48
- let rejectProxyFn = reject(propEq('val', 'ChannelProxy'));
49
- let filterProxyFn = filter(propEq('val', 'ChannelProxy'));
48
+ let rejectProxyFn = reject(propEq('ChannelProxy', 'val'));
49
+ let filterProxyFn = filter(propEq('ChannelProxy', 'val' ));
50
50
  let fn = showOnlyProxies === true ? filterProxyFn : rejectProxyFn;
51
51
  let removedProxyArr = fn(proxyMap);
52
52
  return pluck(['key'], removedProxyArr);
@@ -57,7 +57,7 @@ export class ChannelsMap {
57
57
 
58
58
  checkForMissingChannels() {
59
59
  let proxyMap = this.getChannelsList();
60
- let filterProxyFn = filter(propEq('val', 'ChannelProxy'));
60
+ let filterProxyFn = filter(propEq('ChannelProxy', 'val'));
61
61
  let filterProxyArr = filterProxyFn(proxyMap);
62
62
 
63
63
  if (filterProxyArr.length >= 1) {
@@ -295,9 +295,18 @@ export class SpyneChannelWindow extends Channel {
295
295
  'CHANNEL_WINDOW_FOCUS_EVENT',
296
296
  'CHANNEL_WINDOW_FULLSCREENCHANGE_EVENT',
297
297
  'CHANNEL_WINDOW_FULLSCREENERROR_EVENT',
298
+ 'CHANNEL_WINDOW_KEYUP_EVENT',
299
+ 'CHANNEL_WINDOW_KEYDOWN_EVENT',
298
300
  'CHANNEL_WINDOW_LOAD_EVENT',
299
301
  'CHANNEL_WINDOW_MEDIA_QUERY_EVENT',
300
302
  'CHANNEL_WINDOW_MESSAGE_EVENT',
303
+ 'CHANNEL_WINDOW_MOUSEDOWN_EVENT',
304
+ 'CHANNEL_WINDOW_MOUSEENTER_EVENT',
305
+ 'CHANNEL_WINDOW_MOUSELEAVE_EVENT',
306
+ 'CHANNEL_WINDOW_MOUSEMOVE_EVENT',
307
+ 'CHANNEL_WINDOW_MOUSEOUT_EVENT',
308
+ 'CHANNEL_WINDOW_MOUSEOVER_EVENT',
309
+ 'CHANNEL_WINDOW_MOUSEUP_EVENT',
301
310
  'CHANNEL_WINDOW_MOUSEWHEEL_EVENT',
302
311
  'CHANNEL_WINDOW_OFFLINE_EVENT',
303
312
  'CHANNEL_WINDOW_ONLINE_EVENT',
@@ -3,7 +3,7 @@ import {ViewStream} from './views/view-stream';
3
3
  import {SpyneAppProperties} from './utils/spyne-app-properties';
4
4
  import {deepMerge} from './utils/deep-merge';
5
5
  const _channels = new ChannelsMap();
6
- const version = '0.18.3';
6
+ const version = '0.19.0';
7
7
 
8
8
  class SpyneApplication {
9
9
  /**
@@ -41,7 +41,7 @@ class SpyneApplication {
41
41
  init(config = {}, testMode=false) {
42
42
  //this.channels = new ChannelsMap();
43
43
  /*!
44
- * Spyne 0.18.3
44
+ * Spyne 0.19.0
45
45
  * https://spynejs.org
46
46
  *
47
47
  * @license Copyright 2017-2021, Frank Batista, Relevant Context, LLC. All rights reserved.
@@ -14,6 +14,7 @@ import { ChannelPayload } from './channels/channel-payload-class';
14
14
  import {ChannelPayloadFilter} from './utils/channel-payload-filter';
15
15
  import {SpynePlugin} from './spyne-plugins';
16
16
  import { deepMerge } from './utils/deep-merge';
17
+ import {safeClone} from './utils/safe-clone';
17
18
  import {SpyneAppProperties} from './utils/spyne-app-properties';
18
19
  import {SpyneApp} from './spyne-app';
19
20
 
@@ -35,5 +36,6 @@ export {
35
36
  SpyneApp,
36
37
  SpyneAppProperties,
37
38
  SpynePlugin,
38
- deepMerge
39
+ deepMerge,
40
+ safeClone
39
41
  };
@@ -47,7 +47,7 @@ export class ChannelFetchUtil {
47
47
  */
48
48
 
49
49
 
50
- constructor(options, subscriber, testMode) {
50
+ constructor(options, subscriber, testMode, CHANNEL_NAME) {
51
51
 
52
52
  const testSubscriber = (p) => console.log('FETCH RETURNED ', p);
53
53
 
@@ -57,6 +57,7 @@ export class ChannelFetchUtil {
57
57
  this._serverOptions = ChannelFetchUtil.setServerOptions(options);
58
58
  this._subscriber = subscriber !== undefined ? subscriber : testSubscriber;
59
59
  this.debug = options.debug !== undefined ? options.debug : false;
60
+ this.channelName = CHANNEL_NAME;
60
61
 
61
62
  let fetchProps = {
62
63
  mapFn: this.mapFn,
@@ -66,18 +67,27 @@ export class ChannelFetchUtil {
66
67
  debug: this.debug
67
68
  };
68
69
  if (testMode !== true) {
69
- ChannelFetchUtil.startWindowFetch(fetchProps, this._subscriber);
70
+ ChannelFetchUtil.startWindowFetch(fetchProps, this._subscriber, this.channelName);
70
71
  }
71
72
  }
72
73
 
73
- static startWindowFetch(props, subscriber) {
74
+ static startWindowFetch(props, subscriber, channelName) {
74
75
  let { mapFn, url, serverOptions, responseType, debug } = props;
75
- const tapLogDebug = p => console.log('DEBUG FETCH :', p);
76
+ const tapLogDebug = p => console.log('DEBUG FETCH :', p, {url, serverOptions, responseType, channelName});
76
77
  const tapLog = debug === true ? tapLogDebug : () => {};
77
78
 
79
+ const mapWrapper = (mapMethod)=>{
80
+ const metadata = {channelName, url, responseType, serverOptions}
81
+
82
+ return (data)=>{
83
+ return mapMethod(data, metadata);
84
+ }
85
+
86
+ }
87
+
78
88
  let response$ = from(window.fetch(url, serverOptions))
79
89
  .pipe(tap(tapLog), flatMap(r => from(r[responseType]())),
80
- map(mapFn),
90
+ map(mapWrapper(mapFn)),
81
91
  publish());
82
92
 
83
93
  response$.connect();
@@ -126,7 +136,7 @@ export class ChannelFetchUtil {
126
136
 
127
137
  static updateMethodWhenBodyExists(opts) {
128
138
  const hasBody = has('body');
129
- const methodIsGet = propEq('method', 'GET');
139
+ const methodIsGet = propEq('GET', 'method');
130
140
  const pred = allPass([hasBody, methodIsGet]);
131
141
  return when(pred, assoc('method', 'POST'))(opts);
132
142
  }
@@ -0,0 +1,85 @@
1
+ import {clone, compose, fromPairs, is, path, toPairs} from 'ramda';
2
+ import {SpyneAppProperties} from './spyne-app-properties';
3
+
4
+
5
+
6
+
7
+ const getPropType = (prp) => {
8
+ let type = typeof prp;
9
+ if (['number', 'boolean', 'string'].includes(type)){
10
+ type = 'primitive';
11
+ } else if (type==='object'){
12
+ if (Array.isArray(prp)){
13
+ type = 'array'
14
+ } else if (prp===null){
15
+ type = 'undefined';
16
+ }
17
+ }
18
+ return type;
19
+ }
20
+
21
+
22
+ const cmsDataReviveNestedProxyObj = (proxyObj, proxyReviverMethod) => {
23
+
24
+
25
+ const {__proxy__proxyName} = proxyObj;
26
+
27
+ if (__proxy__proxyName === undefined){
28
+ console.error('object is not proxy object ',proxyObj);
29
+ }
30
+
31
+ const cloneNestedProxyObj = (target, pathArr)=>{
32
+ const nestedProxyObj = path(pathArr, proxyObj);
33
+ const {__proxy__isProxy, __proxy__props} = nestedProxyObj;
34
+ return __proxy__isProxy ? proxyReviverMethod(target, __proxy__props) : target;
35
+ }
36
+
37
+
38
+ const rootObj = cloneNestedProxyObj(clone(proxyObj), []);
39
+
40
+
41
+ const proxyIterable = (iterObj, iterPath) => {
42
+ let dataPath = iterPath || [];
43
+ const loopObj = ([key, prop]) => {
44
+ const type = getPropType(prop);
45
+ const clonedPath = [...dataPath]
46
+ clonedPath.push(key);
47
+ if (type === 'object' || type==='array') {
48
+ iterObj[key] = cloneNestedProxyObj(prop, clonedPath);
49
+ proxyIterable(prop, clonedPath)
50
+ }
51
+ }
52
+ Object.entries(iterObj).forEach(loopObj);
53
+ }
54
+
55
+ proxyIterable(rootObj);
56
+ // console.timeEnd('proxify2');
57
+
58
+
59
+ return rootObj;
60
+
61
+
62
+ }
63
+
64
+
65
+
66
+
67
+ export const safeClone = function(o){
68
+ const {__proxy__proxyName} = o;
69
+ if (__proxy__proxyName!==undefined){
70
+ const proxyReviverMethod = SpyneAppProperties.getProxyReviver(__proxy__proxyName);
71
+ if (typeof proxyReviverMethod === 'function'){
72
+ return cmsDataReviveNestedProxyObj(o, proxyReviverMethod);
73
+ }
74
+ }
75
+
76
+ const isArr = is(Array);
77
+ const isObj = is(Object);
78
+ const isIter = ob => isArr(ob)===false && isObj(ob)===true;
79
+ const isIterable = isIter(o);
80
+ return isIterable ? compose(fromPairs, toPairs, clone)(o) : clone(o);
81
+
82
+
83
+
84
+
85
+ }
@@ -5,9 +5,11 @@ import {path} from 'ramda';
5
5
 
6
6
  let _config;
7
7
  let _channels;
8
- let _channelsMap
8
+ let _channelsMap;
9
9
  let _initialized = false;
10
10
  let _debug = true;
11
+ const _doNotTrackChannelsArr = [];
12
+ const _proxiesMap = new Map();;
11
13
 
12
14
  const _spynePluginMethods = new SpynePluginsMethods();
13
15
 
@@ -162,6 +164,27 @@ class SpyneAppPropertiesClass{
162
164
 
163
165
  }
164
166
 
167
+
168
+
169
+ doNotTrackChannel(channelName){
170
+ _doNotTrackChannelsArr.push(channelName);
171
+ }
172
+
173
+ getUntrackedChannelsList(){
174
+ return _doNotTrackChannelsArr;
175
+ }
176
+
177
+
178
+ registerProxyReviver(name, method){
179
+ _proxiesMap.set(name, method);
180
+ //console.log("REGISTERD PROXY REVIVER",_proxiesMap, _proxiesMap.get(name));
181
+
182
+ }
183
+
184
+ getProxyReviver(proxyName){
185
+ return _proxiesMap.get(proxyName);
186
+ }
187
+
165
188
  getPluginConfigByPluginName(pluginName){
166
189
  return _config.plugins[pluginName];
167
190
  }
@@ -188,7 +188,7 @@ export class SpyneUtilsChannelRouteUrl {
188
188
  };
189
189
 
190
190
  const checkForEitherStrOrReMatch = either(
191
- propEq('str', mainStr), compose(test(__, mainStr), prop('re'))
191
+ propEq(mainStr, 'str'), compose(test(__, mainStr), prop('re'))
192
192
  );
193
193
 
194
194
  const findMatchIndex = compose(findLastIndex(equals(true)), map(checkForEitherStrOrReMatch), map(createStrRegexTest), map(checkForEmpty));
@@ -55,13 +55,12 @@ export class SpyneUtilsChannelRoute {
55
55
  return obj;
56
56
  };
57
57
 
58
- const createPred = p => compose(keys, filter(propEq(p, true)));
58
+ const createPred = p => compose(keys, filter(propEq(true, p)));
59
59
 
60
60
  const getPropsState = compose(map(compareProps), uniq, chain(keys))([obj1, obj2]);
61
61
  let pathsChanged = chain(createPred('changed'), getPropsState);
62
62
  let pathsAdded = chain(createPred('added'), getPropsState);
63
63
  let pathsRemoved = chain(createPred('removed'), getPropsState);
64
- // console.log("GET KEYS ", pathsChanged);
65
64
  obj1 = obj2;
66
65
  return { pathsAdded, pathsRemoved, pathsChanged };
67
66
  },
@@ -1,5 +1,6 @@
1
1
  import {includes, __, ifElse, path, prop, reject, is, isNil, isEmpty} from 'ramda';
2
2
 
3
+
3
4
  /**
4
5
  * @module DomElTemplate
5
6
  * @type util
@@ -133,8 +134,11 @@ import {includes, __, ifElse, path, prop, reject, is, isNil, isEmpty} from 'ramd
133
134
  */
134
135
 
135
136
  export class DomElementTemplate {
136
- constructor(template, data) {
137
+ constructor(template, data={}) {
137
138
  this.template = this.formatTemplate(template);
139
+ this.isProxyData = data.__cms__isProxy === true;
140
+
141
+
138
142
 
139
143
  const checkForArrayData = ()=>{
140
144
  if (is(Array, data) === true) {
@@ -149,40 +153,60 @@ export class DomElementTemplate {
149
153
 
150
154
  this.templateData = data;
151
155
 
152
-
153
156
  let strArr = DomElementTemplate.getStringArray(this.template);
154
157
 
155
-
156
158
  let strMatches = this.template.match(DomElementTemplate.findTmplLoopsRE());
157
159
  strMatches = strMatches === null ? [] : strMatches;
158
160
 
159
161
  const parseTmplLoopsRE = DomElementTemplate.parseTmplLoopsRE();
162
+
160
163
  const parseTmplLoopFn = this.parseTheTmplLoop.bind(this);
161
- const mapTmplLoop = (str, data) => str.replace(parseTmplLoopsRE, parseTmplLoopFn);
162
- const findTmplLoopsPred = includes(__, strMatches);
163
164
 
165
+ const mapTmplLoop = (str, data) => {
166
+ return str.replace(parseTmplLoopsRE, parseTmplLoopFn);
167
+ }
168
+
169
+ const findTmplLoopsPred = includes(__, strMatches);
164
170
  const checkForMatches = ifElse(
165
- findTmplLoopsPred,
166
- mapTmplLoop,
167
- this.addParams.bind(this));
171
+ findTmplLoopsPred,
172
+ mapTmplLoop,
173
+ this.addParams.bind(this));
168
174
 
169
175
  this.finalArr = strArr.map(checkForMatches);
170
176
 
171
177
  }
172
178
 
179
+ static isPrimitiveTag(str){
180
+ return /({{\.\*?}})/.test(str);;
181
+ }
182
+
183
+ // FIND CORRECT NESTED DATA
184
+ static getNestedDataReducer(data={}, param=""){
185
+ const dataReducer = (nestedData, str) =>{
186
+ if (nestedData[str]){
187
+ return nestedData[str];
188
+ }
189
+ return nestedData;
190
+ }
191
+ return /(\.)/gm.test(String(param)) ? String(param).split('.').reduce(dataReducer,data) : data[param];
192
+ }
193
+
173
194
  static getStringArray(template) {
174
195
  let strArr = template.split(DomElementTemplate.findTmplLoopsRE());
175
196
  const emptyRE = /^([\\n\s\W]+)$/;
176
197
  const filterOutEmptyStrings = s => s.match(emptyRE);
177
- return reject(filterOutEmptyStrings, strArr);
198
+ const finalStr = reject(filterOutEmptyStrings, strArr);
199
+
200
+ return finalStr;
201
+
178
202
  }
179
203
 
180
204
  static findTmplLoopsRE() {
181
- return /({{#\w+}}[\w\n\s\W]+?{{\/\w+}})/gm;
205
+ return /({{#[\w.]+}}[\w\n\s\W]+?{{\/[\w.]+}})/gm;
182
206
  }
183
207
 
184
208
  static parseTmplLoopsRE() {
185
- return /({{#(\w+)}})([\w\n\s\W]+?)({{\/\2}})/gm;
209
+ return /({{#([\w.]+)}})([\w\n\s\W]+?)({{\/\2}})/gm;
186
210
  }
187
211
 
188
212
  static swapParamsForTagsRE() {
@@ -196,10 +220,10 @@ export class DomElementTemplate {
196
220
  }
197
221
 
198
222
 
199
- /**
200
- *
201
- * @desc Returns a document fragment generated from the template and any added data.
202
- */
223
+ /**
224
+ *
225
+ * @desc Returns a document fragment generated from the template and any added data.
226
+ */
203
227
 
204
228
 
205
229
  renderDocFrag() {
@@ -207,7 +231,7 @@ export class DomElementTemplate {
207
231
  const isTableSubTag = /^([^>]*?)(<){1}(\b)(thead|col|colgroup|tbody|td|tfoot|tr|th)(\b)([^\0]*)$/.test(html);
208
232
  const el = isTableSubTag ? html : document.createRange().createContextualFragment(html);
209
233
 
210
- window.setTimeout(this.removeThis(), 2);
234
+ window.setTimeout(this.removeThis(), 2);
211
235
  return el;
212
236
 
213
237
  }
@@ -233,52 +257,97 @@ export class DomElementTemplate {
233
257
  }
234
258
 
235
259
  addParams(str) {
236
- //console.time(this.tempL+'9')
237
260
  const re = /(\.)/gm;
238
-
239
261
  const replaceTags = (str, p1, p2, p3) => {
240
- if (re.test(p2) === false && this.templateData[p2] !==undefined){
241
- return this.templateData[p2];
242
- }
243
- return this.getDataValFromPathStr(p2, this.templateData);
262
+ return DomElementTemplate.getNestedDataReducer(this.templateData, p2);
244
263
  };
245
-
246
- return str.replace(DomElementTemplate.swapParamsForTagsRE(), replaceTags);
264
+ return str.replace(DomElementTemplate.swapParamsForTagsRE(), replaceTags);
247
265
 
248
266
  }
249
267
 
250
- parseTheTmplLoop(str, p1, p2, p3) {
251
268
 
252
- //console.time(this.tempL+'5b')
269
+
270
+
271
+ parseTheTmplLoop(str, p1, p2, p3) {
272
+ const dotConverter = str=>`${str.replace(/(\.)/g, "][")}`
253
273
  const reDot = /(\.)/gm;
254
274
  const subStr = p3;
255
- let elData = this.templateData[p2];
256
- const parseString = (item, str) => {
275
+
276
+ const dataReducer = (acc, str) =>{
277
+ acc = acc[str];
278
+ return acc;
279
+ }
280
+
281
+
282
+ let elData = DomElementTemplate.getNestedDataReducer(this.templateData, p2);
283
+
284
+ const arrayStringToObjAdapter = (d,str, i)=>{
285
+
286
+ // IF {{.}} RUN parseString
287
+ if (DomElementTemplate.isPrimitiveTag(str)){
288
+ return parseString(d, str, i);
289
+ }
290
+
291
+ // CREATE DATA OBJ -- CHECK TO ADD PROXY VALUES
292
+ const createDataObj = ()=>{
293
+ const spyneLoopKey = d;
294
+ const loopIndex = i;
295
+ const loopNum = i+1;
296
+
297
+ if (this.isProxyData) {
298
+ const __cms__dataId = elData.__cms__dataId;
299
+ const keyIdStr = `__cms__keyFor_${d}`
300
+ const origKey = elData[keyIdStr];
301
+ return {spyneLoopKey, __cms__dataId, origKey, loopIndex, loopNum, d}
302
+
303
+ }
304
+ return {spyneLoopKey, loopIndex, loopNum};
305
+ }
306
+
307
+ return parseObject(createDataObj(), str, i);
308
+ }
309
+
310
+ const parseString = (item, str, index, origIndex) => {
257
311
  return str.replace(DomElementTemplate.swapParamsForTagsRE(), item);
258
312
  };
259
- const parseObject = (obj, str) => {
313
+
314
+
315
+ // PARSING ARRAYS AND OBJECTS
316
+ const parseObject = (obj, str, i) => {
317
+ /// LOOP NUMBER VALUES AUTO ADDED
318
+
319
+ //const loopIndex = i;
320
+ //const loopNum = i+1;
321
+
260
322
  const loopObj = (str, p1, p2) => {
261
323
  // DOT SYNTAX CHECK
324
+ const hash = {
325
+ loopIndex: i,
326
+ loopNum: i+1
327
+ }
328
+
329
+ // IF {{.}}
262
330
  if (reDot.test(p2) === false && obj[p2] !==undefined) {
263
- return obj[p2]
331
+ return hash[p2] !== undefined ? hash[p2] : obj[p2]
264
332
  }
265
333
 
266
- return this.getDataValFromPathStr(p2, obj);
334
+ const dataReducedVal = this.getDataValFromPathStr(p2, obj);
335
+ return hash[p2] !== undefined ? hash[p2] : dataReducedVal
267
336
  };
268
337
  return str.replace(DomElementTemplate.swapParamsForTagsRE(), loopObj);
269
338
  };
270
- const mapStringData = (d) => typeof(d) === 'string' ? parseString(d, subStr) : parseObject(d, subStr);
271
339
 
340
+ const mapStringData = (d, i) => typeof(d) === 'string' ? arrayStringToObjAdapter(d, subStr, i) : parseObject(d, subStr, i);
272
341
 
273
342
  if (isNil(elData) === true || isEmpty(elData)) {
274
343
  return '';
275
344
  }
276
345
 
277
346
  if (elData.length===undefined) {
278
- elData = [elData];
279
- }
347
+ elData = [elData];
348
+ }
280
349
 
281
- return elData.map(mapStringData).join('');
350
+ return elData.map(mapStringData).join('');
282
351
 
283
352
 
284
353
  }
@@ -155,9 +155,17 @@ export class ViewStreamElement {
155
155
  let container = isNil(d.query) ? d.node : d.query;
156
156
  let prepend = (node, item) => node.insertBefore(item, node.firstChild);
157
157
  let append = (node, item) => node.appendChild(item);
158
+ let after = (node, item) => node.after(item);
159
+
160
+ const defaultFn = prepend;
161
+ const attachTypeHash = {
162
+ 'appendChild' : append,
163
+ 'after' : after
164
+ }
158
165
  // DETERMINE WHETHER TO USE APPEND OR PREPEND
159
166
  // ON CONNECTING DOM ITEMS TO EACH OTHER
160
- let attachFunc = d.attachType === 'appendChild' ? append : prepend;
167
+ //let attachFunc = d.attachType === 'appendChild' ? append : prepend;
168
+ const attachFunc = attachTypeHash[d.attachType] || defaultFn;
161
169
  attachFunc(container, this.domItem.render());
162
170
  this.setAnimateIn(d);
163
171
  }
@@ -1,4 +1,5 @@
1
1
  import {SpyneAppProperties} from '../utils/spyne-app-properties';
2
+ import {safeClone} from '../utils/safe-clone';
2
3
  import { gc } from '../utils/gc';
3
4
  import {
4
5
  compose,
@@ -36,7 +37,8 @@ export class ViewStreamPayload {
36
37
 
37
38
  sendToDirectorStream(payload) {
38
39
  let directorStream$ = SpyneAppProperties.channelsMap.getStream('DISPATCHER');
39
- const frozenPayload = ViewStreamPayload.deepClone(payload);
40
+ const frozenPayload = safeClone(payload);
41
+ //console.log("VS PAYLOAD ",frozenPayload);
40
42
  directorStream$.next(frozenPayload);
41
43
  payload = undefined;
42
44
 
@@ -33,7 +33,7 @@ function testSelectors(cxt, str, verboseBool) {
33
33
  const elIsDomElement = compose(lte(0), defaultTo(-1),
34
34
  prop('nodeType'));
35
35
 
36
- if (elIsDomElement(el) === false) {
36
+ if (el !== null && elIsDomElement(el) === false) {
37
37
  console.warn(`Spyne Warning: the el object is not a valid single element, ${el}`);
38
38
  return;
39
39
  }
@@ -52,18 +52,37 @@ function testSelectors(cxt, str, verboseBool) {
52
52
 
53
53
  function getNodeListArray(cxt, str, verboseBool=false) {
54
54
  let selector = str !== undefined ? `${cxt} ${str}` : cxt;
55
+ let isParent = false;
55
56
 
56
57
 
57
58
  const returnSelectorIfValid = (selector) => {
58
- try { document.querySelectorAll(selector) } catch (e) { return [] }
59
- return document.querySelectorAll(selector);
59
+ let arr = [];
60
+ try {
61
+ arr = document.querySelectorAll(selector)
62
+ } catch (e) { arr = [] }
63
+ try {
64
+ isParent = document.querySelector(str) === document.querySelector(cxt);
65
+ if (isParent === true){
66
+ arr = [document.querySelector(str)];
67
+ }
68
+ } catch(e){
69
+ //return [];
70
+ }
71
+ return arr;// document.querySelectorAll(selector);
60
72
  };
61
73
 
62
74
 
75
+ const elArr = returnSelectorIfValid(selector);
76
+
63
77
  if (verboseBool===true) {
64
- testSelectors(cxt, str, verboseBool);
78
+ const mainSel = isParent === true ? 'body' : cxt;
79
+ testSelectors(mainSel, str, verboseBool);
65
80
  }
66
- return returnSelectorIfValid(selector)
81
+
82
+ return elArr;
83
+
84
+
85
+
67
86
  }
68
87
 
69
88
  function setInlineCss(val, cxt, str) {