Skip to content

Commit

Permalink
Support range replace upadtes part of issue #105
Browse files Browse the repository at this point in the history
  • Loading branch information
David-Desmaisons committed Feb 16, 2019
1 parent aa5eb18 commit 6714c58
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 23 deletions.
40 changes: 32 additions & 8 deletions Neutronium.Core/Binding/GlueObject/JSArray.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using MoreCollection.Extensions;
using Neutronium.Core.Binding.Builder;
using Neutronium.Core.Binding.CollectionChanges;
using Neutronium.Core.Binding.Listeners;
using Neutronium.Core.JavascriptFramework;
using Neutronium.Core.WebBrowserEngine.JavascriptObject;
using MoreCollection.Extensions;
using Neutronium.Core.Binding.Builder;
using Neutronium.Core.Binding.Listeners;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;

Expand All @@ -26,7 +26,7 @@ internal class JsArray : GlueBase, IJsCsCachableGlue

public JsArray(IEnumerable collection, Type individual)
{
CValue = collection;
CValue = collection;
_IndividualType = individual;
}

Expand All @@ -46,7 +46,7 @@ public void VisitDescendants(Func<IJsCsGlue, bool> visit)
}
}

public void VisitChildren(Action<IJsCsGlue> visit)
public void VisitChildren(Action<IJsCsGlue> visit)
{
foreach (var item in Items)
visit(item);
Expand Down Expand Up @@ -131,6 +131,16 @@ private static BridgeUpdater CheckForRemove(BridgeUpdater updater, IJsCsGlue glu
return updater;
}

private static BridgeUpdater CheckForRemove(BridgeUpdater updater, List<IJsCsGlue> glues)
{
glues.ForEach(glue =>
{
if (glue.Release())
updater.Remove(glue);
});
return updater;
}

public BridgeUpdater GetReplaceUpdater(IJsCsGlue glue, int index)
{
var bridgeUpdater = new BridgeUpdater(viewModelUpdater => Splice(viewModelUpdater, index, 1, glue));
Expand All @@ -139,6 +149,20 @@ public BridgeUpdater GetReplaceUpdater(IJsCsGlue glue, int index)
return CheckForRemove(bridgeUpdater, old);
}

public BridgeUpdater GetReplaceUpdater(List<IJsCsGlue> glues, int index)
{
var bridgeUpdater = new BridgeUpdater(viewModelUpdater => Splice(viewModelUpdater, index, glues.Count, glues));

var oldChildren = new List<IJsCsGlue>();
glues.ForEach(glue =>
{
var old = Items[index];
Items[index] = glue.AddRef();
oldChildren.Add(old);
});
return CheckForRemove(bridgeUpdater, oldChildren);
}

public BridgeUpdater GetMoveUpdater(int oldIndex, int newIndex)
{
var item = Items[oldIndex];
Expand Down
28 changes: 17 additions & 11 deletions Neutronium.Core/Binding/Updaters/CollectionJavascriptUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@ private BridgeUpdater GetBridgeUpdater(JsArray array)
return GetAddUpdater(array);

case NotifyCollectionChangedAction.Replace:
var newValue = _JsUpdateHelper.Map(_Change.NewItems[0]);
if (newValue == null)
return null;
NewJsValues.Add(newValue);
return array.GetReplaceUpdater(newValue, _Change.NewStartingIndex);
return GetReplaceUpdater(array);

case NotifyCollectionChangedAction.Remove:
return array.GetRemoveUpdater(_Change.OldStartingIndex, _Change.OldItems.Count);
Expand All @@ -64,18 +60,28 @@ private BridgeUpdater GetBridgeUpdater(JsArray array)

private BridgeUpdater GetAddUpdater(JsArray array)
{
InitValuesFromNewItems();
if (_Change.NewItems.Count == 1)
{
var newValue = _JsUpdateHelper.Map(_Change.NewItems[0]);
if (newValue == null)
return null;
NewJsValues.Add(newValue);
return array.GetAddUpdater(newValue, _Change.NewStartingIndex);
return array.GetAddUpdater(_NewJsValues[0], _Change.NewStartingIndex);
}
return array.GetAddUpdater(_NewJsValues, _Change.NewStartingIndex);
}

private BridgeUpdater GetReplaceUpdater(JsArray array)
{
InitValuesFromNewItems();
if (_Change.NewItems.Count == 1)
{
return array.GetReplaceUpdater(_NewJsValues[0], _Change.NewStartingIndex);
}
return array.GetReplaceUpdater(_NewJsValues, _Change.NewStartingIndex);
}

private void InitValuesFromNewItems()
{
_NewJsValues = _Change.NewItems.Cast<object>().Select(item => _JsUpdateHelper.Map(item))
.ToList();
return array.GetAddUpdater(_NewJsValues, _Change.NewStartingIndex);
}

public void OnJsContext()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,33 @@ public async Task TwoWay_Collection_Updates_After_RemoveRange_Changes()
await RunAsync(test);
}

[Fact]
public async Task TwoWay_Collection_Updates_After_ReplaceRange_Changes()
{
var dataContext = new VmWithRangeCollection();
dataContext.List.AddRange(new[] { 1, 20, 30, 40, 5 });
var test = new TestInContextAsync()
{
Bind = (win) => HtmlBinding.Bind(win, dataContext, JavascriptBindingMode.TwoWay),
Test = async (mb) =>
{
var js = mb.JsRootObject;

DoSafeUI(() =>
{
dataContext.List.ReplaceRange(1, 3, new[] { 2, 3, 4 });
});

await Task.Delay(500);
var col = GetCollectionAttribute(js, "List");
col.Should().NotBeNull();
CheckIntCollection(col, new[] { 1, 2, 3, 4, 5 });
}
};

await RunAsync(test);
}

[Fact]
public async Task TwoWay_Collection_Updates_CSharp_From_JS_Update()
{
Expand Down
8 changes: 4 additions & 4 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1067,18 +1067,18 @@
"incrementalPhase": "build"
},
"processors": {
"TocDocumentProcessor": {
"ResourceDocumentProcessor": {
"can_incremental": false,
"details": "Processor TocDocumentProcessor cannot support incremental build because the processor doesn't implement ISupportIncrementalDocumentProcessor interface.",
"details": "Processor ResourceDocumentProcessor cannot support incremental build because the processor doesn't implement ISupportIncrementalDocumentProcessor interface.",
"incrementalPhase": "build"
},
"ConceptualDocumentProcessor": {
"can_incremental": false,
"incrementalPhase": "build"
},
"ResourceDocumentProcessor": {
"TocDocumentProcessor": {
"can_incremental": false,
"details": "Processor ResourceDocumentProcessor cannot support incremental build because the processor doesn't implement ISupportIncrementalDocumentProcessor interface.",
"details": "Processor TocDocumentProcessor cannot support incremental build because the processor doesn't implement ISupportIncrementalDocumentProcessor interface.",
"incrementalPhase": "build"
}
}
Expand Down

0 comments on commit 6714c58

Please sign in to comment.