Skip to content

Commit db3efc0

Browse files
Merge remote-tracking branch 'roman/feature/optimization-dollarstring' into talentia/stable
2 parents c037594 + 1857e28 commit db3efc0

30 files changed

Lines changed: 549 additions & 421 deletions

src/Runtime/Runtime/Core/Events/INTERNAL_EventsHelper.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,11 @@ public static HtmlEventProxy AttachToDomEvents(string eventName, object domEleme
5555
static void AttachEvent(string eventName, object domElementRef, HtmlEventProxy newProxy, Action<object> originalEventHandler)
5656
{
5757
#if !BUILDINGDOCUMENTATION
58+
string sAction = INTERNAL_InteropImplementation.GetVariableStringForJS((Action<object>)newProxy.OnEvent);
5859
if (domElementRef is INTERNAL_HtmlDomElementReference)
59-
Interop.ExecuteJavaScriptAsync(@"document.addEventListenerSafe($0, $1, $2)", ((INTERNAL_HtmlDomElementReference)domElementRef).UniqueIdentifier, eventName, (Action<object>)newProxy.OnEvent);
60+
Interop.ExecuteJavaScriptFastAsync($@"document.addEventListenerSafe(""{((INTERNAL_HtmlDomElementReference)domElementRef).UniqueIdentifier}"", ""{eventName}"", {sAction})");
6061
else
61-
Interop.ExecuteJavaScriptAsync(@"document.addEventListenerSafe($0, $1, $2)", domElementRef, eventName, (Action<object>)newProxy.OnEvent);
62+
Interop.ExecuteJavaScriptFastAsync($@"document.addEventListenerSafe({INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef)}, ""{eventName}"", {sAction})");
6263

6364
/*
6465
DOMEventType eventType;
@@ -87,7 +88,11 @@ static void AttachEvent(string eventName, object domElementRef, HtmlEventProxy n
8788
internal static void DetachEvent(string eventName, object domElementRef, HtmlEventProxy proxy, Action<object> originalEventHandler)
8889
{
8990
#if !BUILDINGDOCUMENTATION
90-
Interop.ExecuteJavaScriptAsync(@"document.removeEventListenerSafe($0, $1, $2)", domElementRef, eventName, (Action<object>)proxy.OnEvent);
91+
string sAction = INTERNAL_InteropImplementation.GetVariableStringForJS((Action<object>)proxy.OnEvent);
92+
if (domElementRef is INTERNAL_HtmlDomElementReference)
93+
Interop.ExecuteJavaScriptFastAsync($@"document.removeEventListenerSafe(""{((INTERNAL_HtmlDomElementReference)domElementRef).UniqueIdentifier}"", ""{eventName}"", {sAction})");
94+
else
95+
Interop.ExecuteJavaScriptFastAsync($@"document.removeEventListenerSafe({INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef)}, ""{eventName}"", {sAction})");
9196

9297
/*
9398
DOMEventType eventType;

src/Runtime/Runtime/Core/Main/INTERNAL_SimulatorExecuteJavaScript.cs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,22 @@ internal static void ExecuteJavaScriptAsync(string javaScriptToExecute, string c
154154
#if OPTIMIZATION_LOG
155155
Console.WriteLine("[OPTIMIZATION] Calling setTimeout. _isDispatcherPending: " + _isDispatcherPending.ToString());
156156
#endif
157-
CSHTML5.INTERNAL_InteropImplementation.ExecuteJavaScript_SimulatorImplementation(
158-
javascript: "setTimeout($0, 1)",
159-
runAsynchronously: false,
160-
noImpactOnPendingJSCode: true,
161-
variables: new object[]
157+
string action = CSHTML5.INTERNAL_InteropImplementation.GetVariableStringForJS(
158+
(Action)(() =>
162159
{
163-
(Action)(() =>
164-
{
165160
#if OPTIMIZATION_LOG
166161
Console.WriteLine("[OPTIMIZATION] Executing setTimeout. _isDispatcherPending: " + _isDispatcherPending.ToString());
167162
#endif
168-
if (_isDispatcherPending) // We check again, because in the meantime the dispatcher can be cancelled in case of a forced execution of the pending JS code, for example when making a JavaScript execution that "returns a value".
169-
{
170-
ExecutePendingJavaScriptCode("SETTIMEOUT COMPLETED");
171-
}
172-
})
173-
}
163+
if (_isDispatcherPending) // We check again, because in the meantime the dispatcher can be cancelled in case of a forced execution of the pending JS code, for example when making a JavaScript execution that "returns a value".
164+
{
165+
ExecutePendingJavaScriptCode("SETTIMEOUT COMPLETED");
166+
}
167+
})
168+
);
169+
CSHTML5.INTERNAL_InteropImplementation.ExecuteJavaScript_SimulatorImplementation(
170+
javascript: $"setTimeout({action}, 1)",
171+
runAsynchronously: false,
172+
noImpactOnPendingJSCode: true
174173
);
175174
}
176175
}

src/Runtime/Runtime/Core/Rendering/INTERNAL_HtmlDomManager.cs

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,14 @@ public static dynamic GetFirstChildDomElement(dynamic domElementRef)
179179
#endif
180180
public static INTERNAL_HtmlDomElementReference GetChildDomElementAt(INTERNAL_HtmlDomElementReference domElementRef, int index)
181181
{
182-
int length = Convert.ToInt32(Interop.ExecuteJavaScript("$0.childNodes.length", domElementRef));
182+
string sDomElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef);
183+
int length = Convert.ToInt32(Interop.ExecuteJavaScript($"{sDomElement}.childNodes.length"));
183184
if (index < 0 || length <= index)
184185
{
185186
throw new IndexOutOfRangeException();
186187
}
187188

188-
string childNodeId = Interop.ExecuteJavaScript(@"var child = $0.childNodes[$1]; child.id;", domElementRef, index).ToString();
189+
string childNodeId = Interop.ExecuteJavaScript($@"var child = {sDomElement}.childNodes[{index.ToInvariantString()}]; child.id;").ToString();
189190
return new INTERNAL_HtmlDomElementReference(childNodeId, domElementRef);
190191
}
191192

@@ -233,7 +234,8 @@ public static void SetFocus(UIElement element)
233234
if (IsRunningInJavaScript())
234235
#endif
235236
{
236-
CSHTML5.Interop.ExecuteJavaScriptAsync("setTimeout(function() { $0.focus(); }, 1)", domElementRefConcernedByFocus);
237+
string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRefConcernedByFocus);
238+
CSHTML5.Interop.ExecuteJavaScriptAsync($@"setTimeout(function() {{ {sElement}.focus(); }}, 1)");
237239
}
238240
else
239241
{
@@ -390,10 +392,11 @@ public static string GetTextBoxText(object domElementRef)
390392
{
391393
#endif
392394
string uniqueIdentifier = ((INTERNAL_HtmlDomElementReference)domElementRef).UniqueIdentifier;
393-
object domElement = Interop.ExecuteJavaScriptAsync(@"document.getElementByIdSafe($0)", uniqueIdentifier);
395+
object domElement = Interop.ExecuteJavaScriptAsync($@"document.getElementByIdSafe(""{uniqueIdentifier}"")");
394396
//todo-perfs: replace the code above with a call to the faster "ExecuteJavaScript" method instead of "ExecuteJavaScriptWithResult". To do so, see other methods in this class, or see the class "INTERNAL_HtmlDomStyleReference.cs".
395397

396-
return Interop.ExecuteJavaScript("getTextAreaInnerText($0)", domElement).ToString();
398+
string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElement);
399+
return Interop.ExecuteJavaScript($"getTextAreaInnerText({sElement})").ToString();
397400
#if !CSHTML5NETSTANDARD
398401
}
399402
#endif
@@ -424,14 +427,14 @@ public static object AddOptionToNativeComboBox(
424427
string elementToAdd,
425428
int index)
426429
{
427-
var optionDomElement = CSHTML5.Interop.ExecuteJavaScriptAsync(@"
428-
(function(){
430+
string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(nativeComboBoxDomElement);
431+
var optionDomElement = CSHTML5.Interop.ExecuteJavaScriptAsync($@"
432+
(function(){{
429433
var option = document.createElement(""option"");
430-
option.text = $1;
431-
$0.add(option, $2);
434+
option.text = ""{EscapeStringForUseInJavaScript(elementToAdd)}"";
435+
{sElement}.add(option, {index.ToInvariantString()});
432436
return option;
433-
}())
434-
", nativeComboBoxDomElement, elementToAdd, index);
437+
}}())");
435438

436439
return optionDomElement;
437440
}
@@ -449,14 +452,14 @@ public static object AddOptionToNativeComboBox(object nativeComboBoxDomElement,
449452
}()
450453
", domNode, elementToAdd);
451454
*/
452-
var optionDomElement = CSHTML5.Interop.ExecuteJavaScriptAsync(@"
453-
(function(){
455+
string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(nativeComboBoxDomElement);
456+
var optionDomElement = CSHTML5.Interop.ExecuteJavaScriptAsync($@"
457+
(function(){{
454458
var option = document.createElement(""option"");
455-
option.text = $1;
456-
$0.add(option);
459+
option.text = ""{EscapeStringForUseInJavaScript(elementToAdd)}"";
460+
{sElement}.add(option);
457461
return option;
458-
}())
459-
", nativeComboBoxDomElement, elementToAdd);
462+
}}())");
460463
return optionDomElement;
461464
/*
462465
if (IsRunningInJavaScript())
@@ -499,12 +502,15 @@ public static object AddOptionToNativeComboBox(object nativeComboBoxDomElement,
499502

500503
public static void RemoveOptionFromNativeComboBox(object optionToRemove, object nativeComboBoxDomElement)
501504
{
502-
CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0.removeChild($1)", nativeComboBoxDomElement, optionToRemove);
505+
string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(nativeComboBoxDomElement);
506+
string sToRemove = INTERNAL_InteropImplementation.GetVariableStringForJS(optionToRemove);
507+
CSHTML5.Interop.ExecuteJavaScriptFastAsync($"{sElement}.removeChild({sToRemove})");
503508
}
504509

505510
public static void RemoveOptionFromNativeComboBox(object nativeComboBoxDomElement, int index)
506511
{
507-
CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0.remove($1)", nativeComboBoxDomElement, index);
512+
string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(nativeComboBoxDomElement);
513+
CSHTML5.Interop.ExecuteJavaScriptFastAsync($"{sElement}.remove({index.ToInvariantString()})");
508514
}
509515

510516
//public static void AppendChild(dynamic parentDomElement, dynamic childDomElement)
@@ -679,12 +685,14 @@ internal static void SetDomElementStylePropertyUsingVelocity(object domElement,
679685
{
680686
//INTERNAL_HtmlDomManager.SetDomElementStyleProperty(cssEquivalent.DomElement, cssEquivalent.Name, cssValue);
681687
object newObj = CSHTML5.Interop.ExecuteJavaScriptAsync(@"new Object()");
682-
688+
string sNewobj = INTERNAL_InteropImplementation.GetVariableStringForJS(newObj);
689+
string sCssValue = INTERNAL_InteropImplementation.GetVariableStringForJS(cssValue);
683690
foreach (string csspropertyName in cssPropertyNames)
684691
{
685-
CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0[$1] = $2;", newObj, csspropertyName, cssValue);
692+
CSHTML5.Interop.ExecuteJavaScriptFastAsync($@"{sNewobj}[""{csspropertyName}""] = {sCssValue};");
686693
}
687-
CSHTML5.Interop.ExecuteJavaScriptAsync(@"Velocity($0, $1, {duration:1, queue:false});", domElement, newObj);
694+
string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElement); ;
695+
CSHTML5.Interop.ExecuteJavaScriptFastAsync($"Velocity({sElement}, {sNewobj}, {{duration:1, queue:false}});");
688696
}
689697

690698
}
@@ -717,7 +725,8 @@ public static void RemoveDomElementAttribute(object domElementRef, string attrib
717725

718726
public static object GetDomElementAttribute(object domElementRef, string attributeName)
719727
{
720-
return Interop.ExecuteJavaScript("$0[$1]", domElementRef, attributeName);
728+
string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef);
729+
return Interop.ExecuteJavaScript($@"{sElement}[""{attributeName}""]");
721730

722731
// if (IsRunningInJavaScript())
723732
// {
@@ -917,11 +926,13 @@ static object CreateDomElementAndAppendIt_ForUseByTheSimulator(string domElement
917926
if (parentRef is INTERNAL_HtmlDomElementReference)
918927
{
919928
parent = (INTERNAL_HtmlDomElementReference)parentRef;
920-
Interop.ExecuteJavaScriptAsync(@"document.createElementSafe($0, $1, $2, $3)", domElementTag, uniqueIdentifier, parent.UniqueIdentifier, index);
929+
string javaScriptToExecute = $@"document.createElementSafe(""{domElementTag}"", ""{uniqueIdentifier}"", ""{parent.UniqueIdentifier}"", {index.ToInvariantString()})";
930+
Interop.ExecuteJavaScriptFastAsync(javaScriptToExecute);
921931
}
922932
else
923933
{
924-
Interop.ExecuteJavaScriptAsync(@"document.createElementSafe($0, $1, $2, $3)", domElementTag, uniqueIdentifier, parentRef, index);
934+
string sParentRef = INTERNAL_InteropImplementation.GetVariableStringForJS(parentRef);
935+
Interop.ExecuteJavaScriptFastAsync($@"document.createElementSafe(""{domElementTag}"", ""{uniqueIdentifier}"", {sParentRef}, {index.ToInvariantString()})");
925936
}
926937

927938
INTERNAL_idsToUIElements.Add(uniqueIdentifier, associatedUIElement);
@@ -1188,19 +1199,18 @@ public static object ExecuteJavaScriptWithResult(string javaScriptToExecute, str
11881199
/// in the visual tree composition at the specified point.</returns>
11891200
public static UIElement FindElementInHostCoordinates_UsedBySimulatorToo(double x, double y) // IMPORTANT: If you rename this method or change its signature, make sure to rename its dynamic call in the Simulator.
11901201
{
1191-
object domElementAtCoordinates = Interop.ExecuteJavaScript(@"
1192-
(function(){
1193-
var domElementAtCoordinates = document.elementFromPoint($0, $1);
1202+
object domElementAtCoordinates = Interop.ExecuteJavaScript($@"
1203+
(function(){{
1204+
var domElementAtCoordinates = document.elementFromPoint({x.ToInvariantString()}, {y.ToInvariantString()});
11941205
if (!domElementAtCoordinates || domElementAtCoordinates === document.documentElement)
1195-
{
1206+
{{
11961207
return null;
1197-
}
1208+
}}
11981209
else
1199-
{
1210+
{{
12001211
return domElementAtCoordinates;
1201-
}
1202-
}())
1203-
", x, y);
1212+
}}
1213+
}}())");
12041214

12051215
UIElement result = GetUIElementFromDomElement(domElementAtCoordinates);
12061216

@@ -1213,6 +1223,7 @@ public static UIElement GetUIElementFromDomElement(object domElementRef)
12131223

12141224
while (!IsNullOrUndefined(domElementRef))
12151225
{
1226+
string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef);
12161227
// Walk up the DOM tree until we find a DOM element that has a corresponding CSharp object:
12171228

12181229
// Check if element exists in the DOM Tree; strangely, sometimes it doesn't
@@ -1227,7 +1238,7 @@ public static UIElement GetUIElementFromDomElement(object domElementRef)
12271238
{
12281239
// In the Simulator, we get the CSharp object associated to a DOM element by searching for the DOM element ID in the "INTERNAL_idsToUIElements" dictionary.
12291240

1230-
object jsId = Interop.ExecuteJavaScript("$0.id", domElementRef);
1241+
object jsId = Interop.ExecuteJavaScript($"{sElement}.id");
12311242
if (!IsNullOrUndefined(jsId))
12321243
{
12331244
string id = Convert.ToString(jsId);
@@ -1242,7 +1253,7 @@ public static UIElement GetUIElementFromDomElement(object domElementRef)
12421253
{
12431254
// In JavaScript, we get the CSharp object associated to a DOM element by reading the "associatedUIElement" property:
12441255

1245-
object associatedUIElement = Interop.ExecuteJavaScript("$0.associatedUIElement", domElementRef);
1256+
object associatedUIElement = Interop.ExecuteJavaScript($"{sElement}.associatedUIElement");
12461257
if (!IsNullOrUndefined(associatedUIElement))
12471258
{
12481259
result = (UIElement)associatedUIElement;
@@ -1251,7 +1262,7 @@ public static UIElement GetUIElementFromDomElement(object domElementRef)
12511262
}
12521263

12531264
// Move to the parent:
1254-
domElementRef = Interop.ExecuteJavaScript("$0.parentNode", domElementRef);
1265+
domElementRef = Interop.ExecuteJavaScript($"{sElement}.parentNode");
12551266
}
12561267

12571268
return result;

src/Runtime/Runtime/Core/Rendering/INTERNAL_PopupsManager.cs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,18 +112,17 @@ public static PopupRoot CreateAndAppendNewPopupRoot(Window parentWindow)
112112
// Create a DIV for the PopupRoot in the DOM tree:
113113
//--------------------------------------
114114

115-
CSHTML5.Interop.ExecuteJavaScriptAsync(
116-
@"
115+
CSHTML5.Interop.ExecuteJavaScriptFastAsync(
116+
$@"
117117
var popupRoot = document.createElement('div');
118-
popupRoot.setAttribute('id', $0);
118+
popupRoot.setAttribute('id', ""{uniquePopupRootIdentifier}"");
119119
popupRoot.style.position = 'absolute';
120120
popupRoot.style.width = '100%';
121121
popupRoot.style.height = '100%';
122122
popupRoot.style.overflowX = 'hidden';
123123
popupRoot.style.overflowY = 'hidden';
124124
popupRoot.style.pointerEvents = 'none';
125-
$1.appendChild(popupRoot);
126-
", uniquePopupRootIdentifier, parentWindow.INTERNAL_RootDomElement);
125+
{INTERNAL_InteropImplementation.GetVariableStringForJS(parentWindow.INTERNAL_RootDomElement)}.appendChild(popupRoot);");
127126

128127
//--------------------------------------
129128
// Get the PopupRoot DIV:
@@ -138,7 +137,7 @@ public static PopupRoot CreateAndAppendNewPopupRoot(Window parentWindow)
138137
#endif
139138
popupRootDiv = new INTERNAL_HtmlDomElementReference(uniquePopupRootIdentifier, null);
140139
else
141-
popupRootDiv = Interop.ExecuteJavaScriptAsync("document.getElementByIdSafe($0)", uniquePopupRootIdentifier);
140+
popupRootDiv = Interop.ExecuteJavaScriptAsync($@"document.getElementByIdSafe(""{uniquePopupRootIdentifier}"")");
142141

143142
//--------------------------------------
144143
// Create the C# class that points to the PopupRoot DIV:
@@ -189,11 +188,10 @@ public static void RemovePopupRoot(PopupRoot popupRoot)
189188
// Remove from the DOM:
190189
//--------------------------------------
191190

192-
CSHTML5.Interop.ExecuteJavaScriptAsync(
193-
@"
194-
var popupRoot = document.getElementByIdSafe($0);
195-
$1.removeChild(popupRoot);
196-
", uniquePopupRootIdentifier, parentWindow.INTERNAL_RootDomElement);
191+
CSHTML5.Interop.ExecuteJavaScriptFastAsync(
192+
$@"
193+
var popupRoot = document.getElementByIdSafe(""{uniquePopupRootIdentifier}"");
194+
{INTERNAL_InteropImplementation.GetVariableStringForJS(parentWindow.INTERNAL_RootDomElement)}.removeChild(popupRoot);");
197195

198196
//--------------------------------------
199197
// Remove from the list of popups:

0 commit comments

Comments
 (0)