three js object traverse does not update child - three.js

I traverse child nodes of an object and want to set them visible. But the child is not updated (still visible=false)
mymesh.traverse((child) => {
if (child?.userData?.type === "windowhelper") {
child.visible = true;
console.log('child ', child); // prints: child.visible = false !!! why?
}
});

Related

react-redux: flat tree seems to continue to force updates

I've been using react-redux for a while now. Despite this, I can't figure out what might be causing the re-renders given the following.
I have a tree structure that I serialize/deserialize with each update to a node (tree or subtree). The updates are driven by events generated by the UI.
Here is the sequence following an event generated by the UI:
// middleware
// instantiate the Tree instance to compute changes
const tree = Tree.fromFlatNodes(getFlatTreeFromStore());
try {
const updatedTree = Tree.moveNode(tree, {
event,
DEBUG,
});
next([
setTree(Tree.toFlatNodes(updatedTree.root)),
setNotification({
message: `updated flat tree`,
feature: DRAFTING,
}),
]);
} catch (e) {
if (e instanceof InvalidTreeStateError) {
next(setNotification({ message: e.message, feature: DRAFTING }));
} else {
throw e;
}
}
The reducer that handles the SET_TREE event type:
// reducer
// dispatched by middleware
[SET_TREE]: (state, { payload }) => {
return {
...state,
tree: payload,
};
},
The selector for the node state only requires the node id:
/**
* Return values that remain constant despite updates to the tree.
*/
export const selectNodeSeed = (stateFragment, id) => {
const { data, height, childIds } = stateFragment.tree?.[id];
return {
id,
height,
childIds,
dataType: data?.type ?? null,
};
};
Retrieving the node state:
const { height, childIds = [], etlUnitType } = useSelector(
(state) => selectNodeSeed(state, id),
shallowEqual,
);
Base on what I'm showing here, does anyone see why an update to anywhere in the tree, causes all of the node components to re-render?

Add/Create new child node in d3js tree

Im using the below code to create a node. But while adding a new node the whole tree is refreshing. I need to refresh the node which is added newly.
if (parentNode._children != null) {
parentNode.children = parentNode._children;
parentNode._children = null;
}
if (parentNode.children == null) { parentNode.children = []; }
parentNode.data.children.push({ 'name': 'title', 'children': [], '_children': null });
scope.root = d3.hierarchy(scope.data, function (datachild: any) {
return datachild.children;
});
scope.root.x0 = parentNode.x0;
scope.root.y0 = parentNode.y0;
update(scope.root);
I managed to update depth of the each if it has a parent.
if (parentNode._children != null) {
parentNode.children = parentNode._children;
parentNode._children = null;
}
if (parentNode.children == null) {
parentNode.children = [];
}
const nodeData = {
'name': 'title',
'children': [],
'_children': null,
'depth': 0
};
const newNode = d3.hierarchy(nodeData);
newNode.parent = parentNode;
parentNode.children.push(newNode);
parentNode.data.children.push(nodeData);
scope.inEditMode = true;
update(parentNode, true);
function update(source, addNewNode) {
// Assigns the x and y position for the nodes
const treeData = scope.tree(scope.root);
// Compute the new tree layout.
const nodes = treeData.descendants(),
links = treeData.descendants().slice(1);
// Normalize for fixed-depth.
nodes.forEach(function (d: any, i: any) {
if (addNewNode && d.parent) {
// Here you can update.
d.depth = d.parent.depth + 1;
}
d.y = d.depth * 280;
});
}

Resolving promises in Protactor

I actually have issue with following code :
var promise = element(by.id("closeNotification")).isPresent(); // point A
console.log(promise);
promise.then((message) => {
element(by.id("closeNotification")).click();
browser.sleep(3000);
}, (errorMessage) => { // Point B
browser.refresh();
});
Here at point A, if element is present, program runs smoothly. But if element is not present, an error is thrown. At point B i have tried to handle the promise if it is rejected. Please help me with the condition if element is not present.
Thanks in advance.
move the click into if block, only when element is present, then execute click
var promise = element(by.id("closeNotification")).isPresent(); // point A
promise.then((present) => {
if(present) { // only click when present == true
element(by.id("closeNotification")).click();
}
browser.sleep(3000);
}, (errorMessage) => { // Point B
browser.refresh();
});

How to force CKEditor inline widgets to preserve trailing spaces

As I reported at in this CKEditor this ticket, inline widgets in CKEditor (4.7.0) do not preserve trailing spaces, causing display issues.
Take the following simple widget:
CKEDITOR.plugins.add('spanwidget', {
requires: 'widget',
init: function (editor) {
editor.widgets.add('spanwidget', {
editables: {
content: {
selector: 'span'
}
},
upcast: function (element) {
return element.name == 'span';
}
});
}
});
When you load the following data <span>lorem </span>ipsum, you see this text in output: loremipsum (notice the missing space).
This can be seen in this JSFiddle.
How can I work around the problem (I do not control which data is loaded inside CKEditor)?
I found a workaround to force the last trailing space to be preserved. The idea is to replace the last space with a when upcasting the widget element, then remove it before downcasting it:
CKEDITOR.replace('ck', {
allowedContent: true,
extraPlugins: 'spanwidget'
});
CKEDITOR.plugins.add('spanwidget', {
requires: 'widget',
init: function (editor) {
editor.widgets.add('spanwidget', {
editables: {
content: { selector: 'span' }
},
upcast: function (element) {
// Matches?
if (element.name == 'span') {
// Ends with text?
var children = element.children,
childCount = children.length,
lastChild = childCount && children[childCount - 1];
if (lastChild instanceof CKEDITOR.htmlParser.text) {
// Replace the last space with a non breaking space
// (see https://github.com/ckeditor/ckeditor-dev/issues/605)
lastChild.value = lastChild.value.replace(/ $/, ' ');
}
// Match!
return true;
}
// No match
return false;
},
downcast: function (element) {
// Span with class "targetinfo"?
if (element.name == 'span') {
// Ends with text?
var children = element.children,
childCount = children.length,
lastChild = childCount && children[childCount - 1];
if (lastChild instanceof CKEDITOR.htmlParser.text) {
// Ends with a non breaking space?
var match = lastChild.value.match(/ $/i);
if (match) {
// Replace the non breaking space with a normal one
lastChild.value = lastChild.value.replace(/ $/i, ' ');
// Clone the element
var clone = element.clone();
// Reinsert all the children into that element
for (var i = 0; i < childCount; i++) {
clone.add(children[i]);
}
// Return the clone
return clone;
}
}
}
}
});
}
});
See updated JSFiddle here.

How to query connections/endpoints contained in a parent div

Is there a way to query jsPlumb in order to retrieve all connections whose "source" and "target" properties have the same parent div? Currently, I am manually setting the "scope" property of each connection (based on the parent div's id), and this works. However, feels hacky. I feel as if there should be some way to query jsPlumb like
jsPlumb.select('#parentDiv').each(function(connection) {
/*do stuff here*/
});
At the time of connection creation itself you can check and store those connections separately instead of checking for it later. Code:
jsPlumb.bind("jsPlumbConnection", function(ci) {
var s=ci.sourceId,c=ci.targetId;
var f=$('#'+s).parent().attr("id");
var g=$('#'+c).parent().attr("id");
if( f===g ){
// store ci.connection
console.log("Connection:"+ ci.connection +" has same parent div");
}
});
This is how you can confined it to a specific parent div & use 'instance' for each jsPlumb operation :
jsPlumb.ready(function () {
instance = jsPlumb.getInstance({
DragOptions: { cursor: 'pointer', zIndex: 2000 },
ConnectionOverlays: [
["Arrow", { width: 12, length: 15, location: -3 }],
],
Container: "parent" //put parent div id here
});
});
function containsCycle() {
var return_content = false;
$('.item:visible').each(function() {
$(this).addClass("white");
});
$('.item:visible').each(function() {
$vertex = $(this);
if ($vertex.hasClass("white")) {
if (visit($vertex)) {
return_content = true;
return false;
}
}
});
return return_content;
}
function visit(vertex) {
vertex.removeClass("white")
.addClass("grey");
var vertex_connections = jsPlumb
.getConnections({
source: vertex
});
for (var i = 0; i < vertex_connections.length; i++) {
if ($('#' + vertex_connections[i].targetId)
.hasClass("grey")) {
return true;
} else if ($('#' + vertex_connections[i].targetId)
.hasClass("white")) {
if (visit($('#' + vertex_connections[i].targetId))) {
return true;
}
}
}
vertex.removeClass("grey")
.addClass("black");
return false;
}
Use this code to find the cycle connection

Resources