diff --git a/src/Runtime/Runtime/Core/Events/INTERNAL_EventsHelper.cs b/src/Runtime/Runtime/Core/Events/INTERNAL_EventsHelper.cs index 29785c4a8..f9149142e 100644 --- a/src/Runtime/Runtime/Core/Events/INTERNAL_EventsHelper.cs +++ b/src/Runtime/Runtime/Core/Events/INTERNAL_EventsHelper.cs @@ -55,10 +55,11 @@ public static HtmlEventProxy AttachToDomEvents(string eventName, object domEleme static void AttachEvent(string eventName, object domElementRef, HtmlEventProxy newProxy, Action originalEventHandler) { #if !BUILDINGDOCUMENTATION + string sAction = INTERNAL_InteropImplementation.GetVariableStringForJS((Action)newProxy.OnEvent); if (domElementRef is INTERNAL_HtmlDomElementReference) - Interop.ExecuteJavaScriptAsync(@"document.addEventListenerSafe($0, $1, $2)", ((INTERNAL_HtmlDomElementReference)domElementRef).UniqueIdentifier, eventName, (Action)newProxy.OnEvent); + Interop.ExecuteJavaScriptFastAsync($@"document.addEventListenerSafe(""{((INTERNAL_HtmlDomElementReference)domElementRef).UniqueIdentifier}"", ""{eventName}"", {sAction})"); else - Interop.ExecuteJavaScriptAsync(@"document.addEventListenerSafe($0, $1, $2)", domElementRef, eventName, (Action)newProxy.OnEvent); + Interop.ExecuteJavaScriptFastAsync($@"document.addEventListenerSafe({INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef)}, ""{eventName}"", {sAction})"); /* DOMEventType eventType; @@ -87,7 +88,11 @@ static void AttachEvent(string eventName, object domElementRef, HtmlEventProxy n internal static void DetachEvent(string eventName, object domElementRef, HtmlEventProxy proxy, Action originalEventHandler) { #if !BUILDINGDOCUMENTATION - Interop.ExecuteJavaScriptAsync(@"document.removeEventListenerSafe($0, $1, $2)", domElementRef, eventName, (Action)proxy.OnEvent); + string sAction = INTERNAL_InteropImplementation.GetVariableStringForJS((Action)proxy.OnEvent); + if (domElementRef is INTERNAL_HtmlDomElementReference) + Interop.ExecuteJavaScriptFastAsync($@"document.removeEventListenerSafe(""{((INTERNAL_HtmlDomElementReference)domElementRef).UniqueIdentifier}"", ""{eventName}"", {sAction})"); + else + Interop.ExecuteJavaScriptFastAsync($@"document.removeEventListenerSafe({INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef)}, ""{eventName}"", {sAction})"); /* DOMEventType eventType; diff --git a/src/Runtime/Runtime/Core/Main/INTERNAL_SimulatorExecuteJavaScript.cs b/src/Runtime/Runtime/Core/Main/INTERNAL_SimulatorExecuteJavaScript.cs index fc74f6e5b..1d1bfbe9e 100644 --- a/src/Runtime/Runtime/Core/Main/INTERNAL_SimulatorExecuteJavaScript.cs +++ b/src/Runtime/Runtime/Core/Main/INTERNAL_SimulatorExecuteJavaScript.cs @@ -154,23 +154,22 @@ internal static void ExecuteJavaScriptAsync(string javaScriptToExecute, string c #if OPTIMIZATION_LOG Console.WriteLine("[OPTIMIZATION] Calling setTimeout. _isDispatcherPending: " + _isDispatcherPending.ToString()); #endif - CSHTML5.INTERNAL_InteropImplementation.ExecuteJavaScript_SimulatorImplementation( - javascript: "setTimeout($0, 1)", - runAsynchronously: false, - noImpactOnPendingJSCode: true, - variables: new object[] + string action = CSHTML5.INTERNAL_InteropImplementation.GetVariableStringForJS( + (Action)(() => { - (Action)(() => - { #if OPTIMIZATION_LOG Console.WriteLine("[OPTIMIZATION] Executing setTimeout. _isDispatcherPending: " + _isDispatcherPending.ToString()); #endif - 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". - { - ExecutePendingJavaScriptCode("SETTIMEOUT COMPLETED"); - } - }) - } + 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". + { + ExecutePendingJavaScriptCode("SETTIMEOUT COMPLETED"); + } + }) + ); + CSHTML5.INTERNAL_InteropImplementation.ExecuteJavaScript_SimulatorImplementation( + javascript: $"setTimeout({action}, 1)", + runAsynchronously: false, + noImpactOnPendingJSCode: true ); } } diff --git a/src/Runtime/Runtime/Core/Rendering/INTERNAL_HtmlDomManager.cs b/src/Runtime/Runtime/Core/Rendering/INTERNAL_HtmlDomManager.cs index d9235c832..efb91b587 100644 --- a/src/Runtime/Runtime/Core/Rendering/INTERNAL_HtmlDomManager.cs +++ b/src/Runtime/Runtime/Core/Rendering/INTERNAL_HtmlDomManager.cs @@ -179,13 +179,14 @@ public static dynamic GetFirstChildDomElement(dynamic domElementRef) #endif public static INTERNAL_HtmlDomElementReference GetChildDomElementAt(INTERNAL_HtmlDomElementReference domElementRef, int index) { - int length = Convert.ToInt32(Interop.ExecuteJavaScript("$0.childNodes.length", domElementRef)); + string sDomElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef); + int length = Convert.ToInt32(Interop.ExecuteJavaScript($"{sDomElement}.childNodes.length")); if (index < 0 || length <= index) { throw new IndexOutOfRangeException(); } - string childNodeId = Interop.ExecuteJavaScript(@"var child = $0.childNodes[$1]; child.id;", domElementRef, index).ToString(); + string childNodeId = Interop.ExecuteJavaScript($@"var child = {sDomElement}.childNodes[{index.ToInvariantString()}]; child.id;").ToString(); return new INTERNAL_HtmlDomElementReference(childNodeId, domElementRef); } @@ -233,7 +234,8 @@ public static void SetFocus(UIElement element) if (IsRunningInJavaScript()) #endif { - CSHTML5.Interop.ExecuteJavaScriptAsync("setTimeout(function() { $0.focus(); }, 1)", domElementRefConcernedByFocus); + string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRefConcernedByFocus); + CSHTML5.Interop.ExecuteJavaScriptAsync($@"setTimeout(function() {{ {sElement}.focus(); }}, 1)"); } else { @@ -390,10 +392,11 @@ public static string GetTextBoxText(object domElementRef) { #endif string uniqueIdentifier = ((INTERNAL_HtmlDomElementReference)domElementRef).UniqueIdentifier; - object domElement = Interop.ExecuteJavaScriptAsync(@"document.getElementByIdSafe($0)", uniqueIdentifier); + object domElement = Interop.ExecuteJavaScriptAsync($@"document.getElementByIdSafe(""{uniqueIdentifier}"")"); //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". - return Interop.ExecuteJavaScript("getTextAreaInnerText($0)", domElement).ToString(); + string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElement); + return Interop.ExecuteJavaScript($"getTextAreaInnerText({sElement})").ToString(); #if !CSHTML5NETSTANDARD } #endif @@ -424,14 +427,14 @@ public static object AddOptionToNativeComboBox( string elementToAdd, int index) { - var optionDomElement = CSHTML5.Interop.ExecuteJavaScriptAsync(@" -(function(){ + string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(nativeComboBoxDomElement); + var optionDomElement = CSHTML5.Interop.ExecuteJavaScriptAsync($@" +(function(){{ var option = document.createElement(""option""); - option.text = $1; - $0.add(option, $2); + option.text = ""{EscapeStringForUseInJavaScript(elementToAdd)}""; + {sElement}.add(option, {index.ToInvariantString()}); return option; -}()) -", nativeComboBoxDomElement, elementToAdd, index); +}}())"); return optionDomElement; } @@ -449,14 +452,14 @@ public static object AddOptionToNativeComboBox(object nativeComboBoxDomElement, }() ", domNode, elementToAdd); */ - var optionDomElement = CSHTML5.Interop.ExecuteJavaScriptAsync(@" -(function(){ + string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(nativeComboBoxDomElement); + var optionDomElement = CSHTML5.Interop.ExecuteJavaScriptAsync($@" +(function(){{ var option = document.createElement(""option""); - option.text = $1; - $0.add(option); + option.text = ""{EscapeStringForUseInJavaScript(elementToAdd)}""; + {sElement}.add(option); return option; -}()) -", nativeComboBoxDomElement, elementToAdd); +}}())"); return optionDomElement; /* if (IsRunningInJavaScript()) @@ -499,12 +502,15 @@ public static object AddOptionToNativeComboBox(object nativeComboBoxDomElement, public static void RemoveOptionFromNativeComboBox(object optionToRemove, object nativeComboBoxDomElement) { - CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0.removeChild($1)", nativeComboBoxDomElement, optionToRemove); + string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(nativeComboBoxDomElement); + string sToRemove = INTERNAL_InteropImplementation.GetVariableStringForJS(optionToRemove); + CSHTML5.Interop.ExecuteJavaScriptFastAsync($"{sElement}.removeChild({sToRemove})"); } public static void RemoveOptionFromNativeComboBox(object nativeComboBoxDomElement, int index) { - CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0.remove($1)", nativeComboBoxDomElement, index); + string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(nativeComboBoxDomElement); + CSHTML5.Interop.ExecuteJavaScriptFastAsync($"{sElement}.remove({index.ToInvariantString()})"); } //public static void AppendChild(dynamic parentDomElement, dynamic childDomElement) @@ -679,12 +685,14 @@ internal static void SetDomElementStylePropertyUsingVelocity(object domElement, { //INTERNAL_HtmlDomManager.SetDomElementStyleProperty(cssEquivalent.DomElement, cssEquivalent.Name, cssValue); object newObj = CSHTML5.Interop.ExecuteJavaScriptAsync(@"new Object()"); - + string sNewobj = INTERNAL_InteropImplementation.GetVariableStringForJS(newObj); + string sCssValue = INTERNAL_InteropImplementation.GetVariableStringForJS(cssValue); foreach (string csspropertyName in cssPropertyNames) { - CSHTML5.Interop.ExecuteJavaScriptAsync(@"$0[$1] = $2;", newObj, csspropertyName, cssValue); + CSHTML5.Interop.ExecuteJavaScriptFastAsync($@"{sNewobj}[""{csspropertyName}""] = {sCssValue};"); } - CSHTML5.Interop.ExecuteJavaScriptAsync(@"Velocity($0, $1, {duration:1, queue:false});", domElement, newObj); + string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElement); ; + CSHTML5.Interop.ExecuteJavaScriptFastAsync($"Velocity({sElement}, {sNewobj}, {{duration:1, queue:false}});"); } } @@ -717,7 +725,8 @@ public static void RemoveDomElementAttribute(object domElementRef, string attrib public static object GetDomElementAttribute(object domElementRef, string attributeName) { - return Interop.ExecuteJavaScript("$0[$1]", domElementRef, attributeName); + string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef); + return Interop.ExecuteJavaScript($@"{sElement}[""{attributeName}""]"); // if (IsRunningInJavaScript()) // { @@ -917,11 +926,13 @@ static object CreateDomElementAndAppendIt_ForUseByTheSimulator(string domElement if (parentRef is INTERNAL_HtmlDomElementReference) { parent = (INTERNAL_HtmlDomElementReference)parentRef; - Interop.ExecuteJavaScriptAsync(@"document.createElementSafe($0, $1, $2, $3)", domElementTag, uniqueIdentifier, parent.UniqueIdentifier, index); + string javaScriptToExecute = $@"document.createElementSafe(""{domElementTag}"", ""{uniqueIdentifier}"", ""{parent.UniqueIdentifier}"", {index.ToInvariantString()})"; + Interop.ExecuteJavaScriptFastAsync(javaScriptToExecute); } else { - Interop.ExecuteJavaScriptAsync(@"document.createElementSafe($0, $1, $2, $3)", domElementTag, uniqueIdentifier, parentRef, index); + string sParentRef = INTERNAL_InteropImplementation.GetVariableStringForJS(parentRef); + Interop.ExecuteJavaScriptFastAsync($@"document.createElementSafe(""{domElementTag}"", ""{uniqueIdentifier}"", {sParentRef}, {index.ToInvariantString()})"); } INTERNAL_idsToUIElements.Add(uniqueIdentifier, associatedUIElement); @@ -1188,19 +1199,18 @@ public static object ExecuteJavaScriptWithResult(string javaScriptToExecute, str /// in the visual tree composition at the specified point. 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. { - object domElementAtCoordinates = Interop.ExecuteJavaScript(@" -(function(){ - var domElementAtCoordinates = document.elementFromPoint($0, $1); + object domElementAtCoordinates = Interop.ExecuteJavaScript($@" +(function(){{ + var domElementAtCoordinates = document.elementFromPoint({x.ToInvariantString()}, {y.ToInvariantString()}); if (!domElementAtCoordinates || domElementAtCoordinates === document.documentElement) - { + {{ return null; - } + }} else - { + {{ return domElementAtCoordinates; - } -}()) -", x, y); + }} +}}())"); UIElement result = GetUIElementFromDomElement(domElementAtCoordinates); @@ -1213,6 +1223,7 @@ public static UIElement GetUIElementFromDomElement(object domElementRef) while (!IsNullOrUndefined(domElementRef)) { + string sElement = INTERNAL_InteropImplementation.GetVariableStringForJS(domElementRef); // Walk up the DOM tree until we find a DOM element that has a corresponding CSharp object: #if OPENSILVER if (true) @@ -1222,7 +1233,7 @@ public static UIElement GetUIElementFromDomElement(object domElementRef) { // 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. - object jsId = Interop.ExecuteJavaScript("$0.id", domElementRef); + object jsId = Interop.ExecuteJavaScript($"{sElement}.id"); if (!IsNullOrUndefined(jsId)) { string id = Convert.ToString(jsId); @@ -1237,7 +1248,7 @@ public static UIElement GetUIElementFromDomElement(object domElementRef) { // In JavaScript, we get the CSharp object associated to a DOM element by reading the "associatedUIElement" property: - object associatedUIElement = Interop.ExecuteJavaScript("$0.associatedUIElement", domElementRef); + object associatedUIElement = Interop.ExecuteJavaScript($"{sElement}.associatedUIElement"); if (!IsNullOrUndefined(associatedUIElement)) { result = (UIElement)associatedUIElement; @@ -1246,7 +1257,7 @@ public static UIElement GetUIElementFromDomElement(object domElementRef) } // Move to the parent: - domElementRef = Interop.ExecuteJavaScript("$0.parentNode", domElementRef); + domElementRef = Interop.ExecuteJavaScript($"{sElement}.parentNode"); } return result; diff --git a/src/Runtime/Runtime/Core/Rendering/INTERNAL_PopupsManager.cs b/src/Runtime/Runtime/Core/Rendering/INTERNAL_PopupsManager.cs index c14032421..77b861b9d 100644 --- a/src/Runtime/Runtime/Core/Rendering/INTERNAL_PopupsManager.cs +++ b/src/Runtime/Runtime/Core/Rendering/INTERNAL_PopupsManager.cs @@ -112,18 +112,17 @@ public static PopupRoot CreateAndAppendNewPopupRoot(Window parentWindow) // Create a DIV for the PopupRoot in the DOM tree: //-------------------------------------- - CSHTML5.Interop.ExecuteJavaScriptAsync( -@" + CSHTML5.Interop.ExecuteJavaScriptFastAsync( +$@" var popupRoot = document.createElement('div'); -popupRoot.setAttribute('id', $0); +popupRoot.setAttribute('id', ""{uniquePopupRootIdentifier}""); popupRoot.style.position = 'absolute'; popupRoot.style.width = '100%'; popupRoot.style.height = '100%'; popupRoot.style.overflowX = 'hidden'; popupRoot.style.overflowY = 'hidden'; popupRoot.style.pointerEvents = 'none'; -$1.appendChild(popupRoot); -", uniquePopupRootIdentifier, parentWindow.INTERNAL_RootDomElement); +{INTERNAL_InteropImplementation.GetVariableStringForJS(parentWindow.INTERNAL_RootDomElement)}.appendChild(popupRoot);"); //-------------------------------------- // Get the PopupRoot DIV: @@ -138,7 +137,7 @@ public static PopupRoot CreateAndAppendNewPopupRoot(Window parentWindow) #endif popupRootDiv = new INTERNAL_HtmlDomElementReference(uniquePopupRootIdentifier, null); else - popupRootDiv = Interop.ExecuteJavaScriptAsync("document.getElementByIdSafe($0)", uniquePopupRootIdentifier); + popupRootDiv = Interop.ExecuteJavaScriptAsync($@"document.getElementByIdSafe(""{uniquePopupRootIdentifier}"")"); //-------------------------------------- // Create the C# class that points to the PopupRoot DIV: @@ -189,11 +188,10 @@ public static void RemovePopupRoot(PopupRoot popupRoot) // Remove from the DOM: //-------------------------------------- - CSHTML5.Interop.ExecuteJavaScriptAsync( -@" -var popupRoot = document.getElementByIdSafe($0); -$1.removeChild(popupRoot); -", uniquePopupRootIdentifier, parentWindow.INTERNAL_RootDomElement); + CSHTML5.Interop.ExecuteJavaScriptFastAsync( +$@" +var popupRoot = document.getElementByIdSafe(""{uniquePopupRootIdentifier}""); +{INTERNAL_InteropImplementation.GetVariableStringForJS(parentWindow.INTERNAL_RootDomElement)}.removeChild(popupRoot);"); //-------------------------------------- // Remove from the list of popups: diff --git a/src/Runtime/Runtime/DefaultStyles/INTERNAL_DefaultListBoxStyle.xaml b/src/Runtime/Runtime/DefaultStyles/INTERNAL_DefaultListBoxStyle.xaml index fa5446b8e..1d6c4fde3 100644 --- a/src/Runtime/Runtime/DefaultStyles/INTERNAL_DefaultListBoxStyle.xaml +++ b/src/Runtime/Runtime/DefaultStyles/INTERNAL_DefaultListBoxStyle.xaml @@ -142,6 +142,70 @@ + +