mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
allow $parent access of flow context
This commit is contained in:
parent
30aebc4ee3
commit
596fbfb517
@ -18,6 +18,7 @@ var clone = require("clone");
|
|||||||
var log = require("@node-red/util").log;
|
var log = require("@node-red/util").log;
|
||||||
var util = require("@node-red/util").util;
|
var util = require("@node-red/util").util;
|
||||||
var memory = require("./memory");
|
var memory = require("./memory");
|
||||||
|
var flows;
|
||||||
|
|
||||||
var settings;
|
var settings;
|
||||||
|
|
||||||
@ -47,6 +48,7 @@ function logUnknownStore(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init(_settings) {
|
function init(_settings) {
|
||||||
|
flows = require("../flows");
|
||||||
settings = _settings;
|
settings = _settings;
|
||||||
contexts = {};
|
contexts = {};
|
||||||
stores = {};
|
stores = {};
|
||||||
@ -198,8 +200,24 @@ function getContextStorage(storage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function followParentContext(parent, key) {
|
||||||
|
if (key === "$parent") {
|
||||||
|
return [parent, ""];
|
||||||
|
}
|
||||||
|
else if (key.startsWith("$parent.")) {
|
||||||
|
var len = "$parent.".length;
|
||||||
|
var new_key = key.substring(len);
|
||||||
|
var ctx = parent;
|
||||||
|
while (ctx && new_key.startsWith("$parent.")) {
|
||||||
|
ctx = ctx.$parent;
|
||||||
|
new_key = new_key.substring(len);
|
||||||
|
}
|
||||||
|
return [ctx, new_key];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function createContext(id,seed) {
|
function createContext(id,seed,parent) {
|
||||||
// Seed is only set for global context - sourced from functionGlobalContext
|
// Seed is only set for global context - sourced from functionGlobalContext
|
||||||
var scope = id;
|
var scope = id;
|
||||||
var obj = seed || {};
|
var obj = seed || {};
|
||||||
@ -254,6 +272,29 @@ function createContext(id,seed) {
|
|||||||
if (!storage) {
|
if (!storage) {
|
||||||
storage = keyParts.store || "_";
|
storage = keyParts.store || "_";
|
||||||
}
|
}
|
||||||
|
var result = followParentContext(parent, key);
|
||||||
|
if (result) {
|
||||||
|
var [ctx, new_key] = result;
|
||||||
|
if (ctx) {
|
||||||
|
if (new_key === "") {
|
||||||
|
if (callback) {
|
||||||
|
return callback(ctx);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctx.get(new_key, storage, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (callback) {
|
||||||
|
return callback(undefined);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!storage) {
|
if (!storage) {
|
||||||
storage = "_";
|
storage = "_";
|
||||||
@ -321,6 +362,19 @@ function createContext(id,seed) {
|
|||||||
if (!storage) {
|
if (!storage) {
|
||||||
storage = keyParts.store || "_";
|
storage = keyParts.store || "_";
|
||||||
}
|
}
|
||||||
|
var result = followParentContext(parent, key);
|
||||||
|
if (result) {
|
||||||
|
var [ctx, new_key] = result;
|
||||||
|
if (ctx) {
|
||||||
|
return ctx.set(new_key, value, storage, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (callback) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!storage) {
|
if (!storage) {
|
||||||
storage = "_";
|
storage = "_";
|
||||||
@ -361,10 +415,36 @@ function createContext(id,seed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (parent) {
|
||||||
|
Object.defineProperty(obj, "$parent", {
|
||||||
|
value: parent
|
||||||
|
});
|
||||||
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContext(localId,flowId) {
|
function createRootContext() {
|
||||||
|
var obj = {};
|
||||||
|
Object.defineProperties(obj, {
|
||||||
|
get: {
|
||||||
|
value: function(key, storage, callback) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: {
|
||||||
|
value: function(key, value, storage, callback) {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
keys: {
|
||||||
|
value: function(storage, callback) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContext(localId,flowId,parent) {
|
||||||
var contextId = localId;
|
var contextId = localId;
|
||||||
if (flowId) {
|
if (flowId) {
|
||||||
contextId = localId+":"+flowId;
|
contextId = localId+":"+flowId;
|
||||||
@ -372,10 +452,19 @@ function getContext(localId,flowId) {
|
|||||||
if (contexts.hasOwnProperty(contextId)) {
|
if (contexts.hasOwnProperty(contextId)) {
|
||||||
return contexts[contextId];
|
return contexts[contextId];
|
||||||
}
|
}
|
||||||
var newContext = createContext(contextId);
|
var newContext = createContext(contextId,undefined,parent);
|
||||||
if (flowId) {
|
if (flowId) {
|
||||||
|
var node = flows.get(flowId);
|
||||||
|
var parent = undefined;
|
||||||
|
if (node && node.type.startsWith("subflow:")) {
|
||||||
|
parent = node.context().flow;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parent = createRootContext();
|
||||||
|
}
|
||||||
|
var flowContext = getContext(flowId,undefined,parent);
|
||||||
Object.defineProperty(newContext, 'flow', {
|
Object.defineProperty(newContext, 'flow', {
|
||||||
value: getContext(flowId)
|
value: flowContext
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Object.defineProperty(newContext, 'global', {
|
Object.defineProperty(newContext, 'global', {
|
||||||
|
@ -225,6 +225,50 @@ describe('context', function() {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("$parent", function() {
|
||||||
|
it('should access $parent', function() {
|
||||||
|
var context0 = Context.get("0","flowA");
|
||||||
|
var context1 = Context.get("1","flowB", context0);
|
||||||
|
var parent = context1.get("$parent");
|
||||||
|
parent.should.equal(context0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get undefined for $parent of root', function() {
|
||||||
|
var context0 = Context.get("0","flowA");
|
||||||
|
var context1 = Context.get("1","flowB", context0);
|
||||||
|
var parent = context1.get("$parent.$parent");
|
||||||
|
should.equal(parent, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get $parent', function() {
|
||||||
|
var context0 = Context.get("0","flowA");
|
||||||
|
var context1 = Context.get("1","flowB", context0);
|
||||||
|
var parent = context1.get("$parent");
|
||||||
|
context0.set("K", "v");
|
||||||
|
var v = context1.get("$parent.K");
|
||||||
|
should.equal(v, "v");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set $parent', function() {
|
||||||
|
var context0 = Context.get("0","flowA");
|
||||||
|
var context1 = Context.get("1","flowB", context0);
|
||||||
|
var parent = context1.get("$parent");
|
||||||
|
context1.set("$parent.K", "v");
|
||||||
|
var v = context0.get("K");
|
||||||
|
should.equal(v, "v");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not contain $parent in keys', function() {
|
||||||
|
var context0 = Context.get("0","flowA");
|
||||||
|
var context1 = Context.get("1","flowB", context0);
|
||||||
|
var parent = context1.get("$parent");
|
||||||
|
context0.set("K0", "v0");
|
||||||
|
context1.set("K1", "v1");
|
||||||
|
var keys = context1.keys();
|
||||||
|
keys.should.have.length(1);
|
||||||
|
keys[0].should.equal("K1");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user