public static ScriptCoreLib.JavaScript.Runtime.Cookie BindTo(this ScriptCoreLib.JavaScript.Runtime.Cookie c, IHTMLTextArea a) { a.onchange += delegate { c.Value = a.value; }; a.value = c.Value; return c; }
internal static IHTMLTextArea InternalConstructor(string value) { IHTMLTextArea n = new IHTMLTextArea(); n.value = value; return n; }
internal static IHTMLTextArea InternalConstructor(string value) { IHTMLTextArea n = new IHTMLTextArea(); n.value = value; return(n); }
// Z:\jsc.svn\examples\javascript\crypto\WebServiceAuthorityExperiment\ /// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IApp page) { new { }.With( async delegate { var x = await base.GetData(); var o = x.value; var t = new IHTMLTextArea { value = x, readOnly = true }.AttachToDocument(); t.style.whiteSpace = IStyle.WhiteSpaceEnum.nowrap; t.style.width = "80em"; //t.style.right = "1em"; t.style.height = "20em"; var status = new IHTMLPre { new { verify = await base.Verify(x) } }.AttachToDocument(); t.style.paddingLeft = "1em"; t.style.borderLeft = "1em solid green"; t.readOnly = false; //while (await t.async.onchange) while (await t.async.onkeyup) { t.style.borderLeft = "1em solid yellow"; // Z:\jsc.svn\core\ScriptCoreLib.Windows.Forms\ScriptCoreLib.Windows.Forms\JavaScript\BCLImplementation\System\Windows\Forms\TextBox.cs x.value = t.value.Replace(Environment.NewLine, "\n").Replace("\n", Environment.NewLine); var verify = await base.Verify(x); status.innerText = new { isoriginal = o == x.value, o = o.Length, t = x.value.Length, verify }.ToString(); if (verify) t.style.borderLeft = "1em solid green"; else t.style.borderLeft = "1em solid red"; } } ); }
void InternalSetAcceptsReturn(bool value) { if (value) if (InternalTextField != null) if (InternalTextField_MultiLine == null) { // known situation this.InternalTextField_MultiLine = new IHTMLTextArea(this.InternalTextField.value) { readOnly = this.InternalTextField.readOnly, wrap = "off" }; this.InternalTextField_MultiLine.style.margin = "0"; this.InternalTextField_MultiLine.style.paddingTop = "0"; this.InternalTextField_MultiLine.style.paddingBottom = "0"; this.InternalTextField_MultiLine.style.position = IStyle.PositionEnum.absolute; this.InternalTextField_MultiLine.style.SetLocation(0, 0); this.InternalTextField_MultiLine.style.overflow = IStyle.OverflowEnum.hidden; this.InternalTextField_MultiLine.style.resize = "none"; // is it tested with the shadow dom? var p = this.InternalTextField.parentNode; // we should actually just notify our collection about this change // but instead we do the exchange here at the moment if (p != null) { p.insertBefore(this.InternalTextField_MultiLine, this.InternalTextField); p.removeChild(this.InternalTextField); //Console.WriteLine("InternalSetAcceptsReturn!!"); } // lets apply current font - probably is the default font... this.FontFamily = this.InternalFontFamily; this.FontSize = this.InternalFontSize; Action InternalAutoSizeUpdate = delegate { if (this.InternalTextField_Shadow == null) return; this.InternalAutoSizeToText(this.InternalTextField_MultiLine.value); }; this.InternalTextField_MultiLine.onchange += delegate { InternalAutoSizeUpdate(); }; this.InternalTextField_MultiLine.onkeyup += delegate { InternalAutoSizeUpdate(); }; InternalUpdateBackground(); InternalUpdateBorderThickness(); InternalUpdateForeground(); return; } throw new NotImplementedException(); }
private void AddEvents(IHTMLElement htext) { var content = new IHTMLDiv().AttachTo(DocumentBody); content.Hide(); var IsCamelCaseNames = "Use CamelCase on event names ".ToCheckBox().AttachToWithLabel(content); IHTMLInput NamePrefix = new IHTMLInput(ScriptCoreLib.Shared.HTMLInputTypeEnum.text); new IHTMLDiv( new IHTMLLabel("Event name prefix: ", NamePrefix), NamePrefix ).AttachTo(content); var update = default(Action); // var a = new IHTMLTextArea().AttachTo(content); IHTMLButton.Create( "Example code", delegate { a.value = @"added Dispatched when a display object is added to the display list. addedToStage Dispatched when a display object is added to the on stage display list, either directly or through the addition of a sub tree in which the display object is contained. enterFrame Dispatched when the playhead is entering a new frame. removed Dispatched when a display object is about to be removed from the display list. removedFromStage Dispatched when a display object is about to be removed from the display list, either directly or through the removal of a sub tree in which the display object is contained. render Dispatched when the display list is about to be updated and rendered."; update(); } ).AttachTo(content); // too big // var cookie = new Cookie("ExampleEvents").BindTo(a); var z = new IHTMLTable().AttachTo(content); var zb = z.AddBody(); var b = new IHTMLTextArea().AttachTo(content); htext.onclick += delegate { content.ToggleVisible(); }; a.style.display = ScriptCoreLib.JavaScript.DOM.IStyle.DisplayEnum.block; a.style.width = "100%"; a.style.height = "20em"; b.style.display = ScriptCoreLib.JavaScript.DOM.IStyle.DisplayEnum.block; b.style.width = "100%"; b.style.height = "20em"; b.readOnly = true; var dict = new { EventType = new Dictionary<string, string>(), EventCodeName = new Dictionary<string, string>(), }; Action<Action<string>> update_output = handler => { var w = new StringBuilder(); var w2 = new StringBuilder(); var lines = a.Lines.ToArray(); w.AppendLine("#region Events"); w2.AppendLine("#region Implementation for methods marked with [Script(NotImplementedHere = true)]"); var DeclaringTypeName = DeclaringType.value; for (int i = 0; i < lines.Length; i += 2) { if ((i + 1) < lines.Length) { var Summary = lines[i + 1].Trim(); var EventName = lines[i].Trim(); if (EventName.IndexOf(":") > -1) EventName = EventName.Substring(0, EventName.IndexOf(":")).Trim(); if (EventName.ContainsAny("(", "#")) throw new Exception("Invalid Event Name"); if (!EventName.Contains("AIR-only")) { //var ReadOnly = "[read-only]"; w.AppendLine("/// <summary>"); w.AppendLine("/// " + Summary); w.AppendLine("/// </summary>"); if (handler != null) handler(EventName); var EventType = dict.EventType[EventName]; var EventCodeName = dict.EventCodeName[EventName]; var FriendlyEventName = EventName; if (IsCamelCaseNames.@checked) FriendlyEventName = FriendlyEventName.ToCamelCase(); if (!string.IsNullOrEmpty(NamePrefix.value)) FriendlyEventName = NamePrefix.value + FriendlyEventName; if (FriendlyEventName == "") throw new Exception("Friendly name is empty."); w.AppendLine("[method: Script(NotImplementedHere = true)]"); w.AppendLine("public event Action<" + EventType + "> " + FriendlyEventName + ";"); w.AppendLine(); w2.AppendLine("#region " + FriendlyEventName); w2.AppendLine("public static void add_" + FriendlyEventName + "(" + DeclaringTypeName + " that, Action<" + EventType + "> value)"); w2.AppendLine("{"); w2.AppendLine(" CommonExtensions.CombineDelegate(that, value, " + EventType + "." + EventCodeName + ");"); w2.AppendLine("}"); w2.AppendLine(); w2.AppendLine("public static void remove_" + FriendlyEventName + "(" + DeclaringTypeName + " that, Action<" + EventType + "> value)"); w2.AppendLine("{"); w2.AppendLine(" CommonExtensions.RemoveDelegate(that, value, " + EventType + "." + EventCodeName + ");"); w2.AppendLine("}"); w2.AppendLine("#endregion"); w2.AppendLine(); } } } w.AppendLine("#endregion"); w2.AppendLine("#endregion"); w.AppendLine(); w.Append(w2.ToString()); b.value = w.ToString(); }; update = delegate { try { zb.removeChildren(); // propagate new values to next buttons var PChange = new List<Func<string, string, string, bool>>(); update_output( EventName => { var row = zb.AddRow(); row.AddColumn(EventName); var EventType = new IHTMLInput(ScriptCoreLib.Shared.HTMLInputTypeEnum.text); if (!dict.EventType.ContainsKey(EventName)) dict.EventType[EventName] = "Event"; var EventTypeOld = dict.EventType[EventName]; EventType.value = dict.EventType[EventName]; var CPChangeOffset = PChange.Count; Action<string, string, string> CPChange = (_EventName, _Old, _New) => { for (int i = CPChangeOffset + 1; i < PChange.Count; i++) { if (!PChange[i](_EventName, _Old, _New)) break; } }; PChange.Add( (_Event, _Old, _New) => { // Console.WriteLine(EventName + " detected a change from " + _Event); if (EventType.value == _Old) { EventType.value = _New; dict.EventType[EventName] = EventType.value; return true; } return false; } ); EventType.onchange += delegate { if (CPChange != null) CPChange(EventName, dict.EventType[EventName], EventType.value); dict.EventType[EventName] = EventType.value; update_output(null); }; row.AddColumn(EventType); var EventCodeName = new IHTMLInput(ScriptCoreLib.Shared.HTMLInputTypeEnum.text); if (!dict.EventCodeName.ContainsKey(EventName)) dict.EventCodeName[EventName] = EventName.ToCamelCaseUpper(); EventCodeName.value = dict.EventCodeName[EventName]; EventCodeName.onchange += delegate { dict.EventCodeName[EventName] = EventCodeName.value; update_output(null); }; row.AddColumn(EventCodeName); } ); htext.style.color = Color.Blue; } catch (Exception ex) { htext.style.color = Color.Red; b.value = "error: " + ex.Message; } }; DeclaringType.onchange += delegate { update_output(null); }; NamePrefix.onchange += delegate { update(); }; IsCamelCaseNames.onchange += delegate { update(); }; a.onchange += delegate { update(); }; }
private void AddMethods(IHTMLElement htext) { var content = new IHTMLDiv().AttachTo(DocumentBody); content.Hide(); var IsInterface = new IHTMLInput(ScriptCoreLib.Shared.HTMLInputTypeEnum.checkbox); new IHTMLDiv( new IHTMLLabel("is an interface: ", IsInterface), IsInterface ).AttachTo(content); var DelegatesParams = new IHTMLInput(ScriptCoreLib.Shared.HTMLInputTypeEnum.checkbox); new IHTMLDiv( new IHTMLLabel("delegates parameters to base constructor: ", DelegatesParams), DelegatesParams ).AttachTo(content); var update = default(Action); // var a = new IHTMLTextArea().AttachTo(content); IHTMLButton.Create( "Example code", delegate { a.value = @"addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void Registers an event listener object with an EventDispatcher object so that the listener receives notification of an event. "; update(); } ).AttachTo(content); var b = new IHTMLTextArea().AttachTo(content); htext.onclick += delegate { content.ToggleVisible(); }; a.style.display = ScriptCoreLib.JavaScript.DOM.IStyle.DisplayEnum.block; a.style.width = "100%"; a.style.height = "20em"; b.style.display = ScriptCoreLib.JavaScript.DOM.IStyle.DisplayEnum.block; b.style.width = "100%"; b.style.height = "20em"; b.readOnly = true; Action update_output = delegate { var w = new StringBuilder(); var w2 = new StringBuilder(); var lines = a.Lines.ToArray(); w.AppendLine("#region Methods"); w2.AppendLine("#region Constructors"); for (int i = 0; i < lines.Length; i += 3) { if ((i + 1) < lines.Length) { var StaticKeyword = "[static]"; var Summary = lines[i + 1].Trim(); var MethodSig = lines[i].Trim(); if (!MethodSig.Contains("AIR-only")) { var q0 = MethodSig.Split(')'); var q1 = q0[0].Split('('); var MethodName = FixVariableName(q1[0].Trim()); var MethodParameters = new MethodParametersInfo(q1[1].Trim()); var MethodReturnType = ""; if (q0[1].StartsWith(":")) MethodReturnType = FixTypeName(q0[1].Substring(1).Trim()); var IsConstructor = string.IsNullOrEmpty(MethodReturnType); foreach (var v in MethodParameters.Variations) { if (IsConstructor) { w2.AppendLine("/// <summary>"); w2.AppendLine("/// " + Summary); w2.AppendLine("/// </summary>"); if (DelegatesParams.@checked) w2.AppendLine("public " + MethodName + "(" + v + ") : base(" + v.NamesToString() + ")"); else w2.AppendLine("public " + MethodName + "(" + v + ")"); w2.AppendLine("{"); w2.AppendLine("}"); w2.AppendLine(); } else { if (v.Parameters.Length == 0 && MethodName == "toString") { } else { w.AppendLine("/// <summary>"); w.AppendLine("/// " + Summary); w.AppendLine("/// </summary>"); var StaticModifier = Summary.Contains(StaticKeyword) ? "static " : ""; if (IsInterface.@checked) { w.AppendLine(MethodReturnType + " " + MethodName + "(" + v + ");"); } else { w.AppendLine("public " + StaticModifier + MethodReturnType + " " + MethodName + "(" + v + ")"); w.AppendLine("{"); if (MethodReturnType != "void") w.AppendLine(" return default(" + MethodReturnType + ");"); w.AppendLine("}"); } w.AppendLine(); } } } } } } w.AppendLine("#endregion"); w2.AppendLine("#endregion"); if (!IsInterface.@checked) { w.AppendLine(); w.Append(w2.ToString()); } b.value = w.ToString(); }; update = delegate { try { update_output(); htext.style.color = Color.Blue; } catch (Exception ex) { htext.style.color = Color.Red; b.value = "error: " + ex.Message; } }; IsInterface.onchange += delegate { update(); }; DelegatesParams.onchange += delegate { update(); }; a.onchange += delegate { update(); }; }
public ConvertASToCS() { Native.Document.title = "ConvertASToCS"; Native.Document.body.style.padding = "0"; Native.Document.body.style.margin = "0"; var cookie = new Cookie("DeclaringType").BindTo(DeclaringType); #region Title var MyTitleText = new IHTMLDiv("This tool allows you to copy various parts of flash doc html file in and generate C# headers."); MyTitleText.style.paddingTop = "12px"; MyTitleText.style.paddingLeft = "15px"; MyTitleText.style.fontFamily = IStyle.FontFamilyEnum.Tahoma; MyTitleText.style.fontSize = "13px"; var MyTitle = new IHTMLDiv(MyTitleText); MyTitle.style.background = "url(" + Assets.Path + "titleTableTop.jpg) repeat-x"; MyTitle.style.height = "44px"; MyTitle.AttachToDocument(); var MyTitleMiddleTextFloat = new IHTMLDiv(); MyTitleMiddleTextFloat.style.paddingTop = "3px"; MyTitleMiddleTextFloat.style.Float = IStyle.FloatEnum.right; var MyTitleMiddleText = new IHTMLDiv(new IHTMLLabel("DeclaringType: ", DeclaringType), DeclaringType); MyTitleMiddleText.style.paddingTop = "3px"; MyTitleMiddleText.style.paddingLeft = "15px"; MyTitleMiddleText.style.fontFamily = IStyle.FontFamilyEnum.Tahoma; MyTitleMiddleText.style.fontSize = "20px"; var MyTitleMiddle = new IHTMLDiv(MyTitleMiddleTextFloat, MyTitleMiddleText); MyTitleMiddle.style.background = "url(" + Assets.Path + "titleTableMiddle.jpg) repeat-x"; MyTitleMiddle.style.height = "31px"; MyTitleMiddle.AttachToDocument(); var MyTitleShadow = new IHTMLDiv(""); MyTitleShadow.style.background = "url(" + Assets.Path + "titleTableBottom.jpg) repeat-x"; MyTitleShadow.style.height = "5px"; MyTitleShadow.AttachToDocument(); #endregion DocumentBody = new IHTMLDiv().AttachToDocument(); DocumentBody.style.padding = "1em"; DocumentBody.style.backgroundImage = "url(assets/ConvertASToCS/flash_logo.png)"; DocumentBody.style.backgroundPosition = "right top"; DocumentBody.style.backgroundRepeat = "no-repeat"; a = new IHTMLTextArea().AttachTo(DocumentBody); a.style.backgroundColor = Color.Transparent; a.style.border = "1px solid gray"; Func<IHTMLImage, string, IHTMLAnchor> CreateButton = (img, text) => { img.style.border = "0px"; var htext = new IHTMLAnchor("#", img, new IHTMLSpan(text)).AttachTo(MyTitleMiddleTextFloat); htext.onclick += e => e.PreventDefault(); htext.style.margin = "1em"; return htext; }; AddEvents(CreateButton((Assets.Path + "ak590dyt.pubevent(en-US,VS.80).gif"), "Events")); AddConstants(CreateButton((Assets.Path + "ak590dyt.pubproperty(en-US,VS.80).gif"), "Constants")); AddProperties(CreateButton((Assets.Path + "ak590dyt.pubproperty(en-US,VS.80).gif"), "Properties")); AddMethods(CreateButton((Assets.Path + "deshae98.pubmethod(en-us,VS.90).gif"), "Methods")); AddAny(CreateButton((Assets.Path + "deshae98.pubmethod(en-us,VS.90).gif"), "Any")); AddProxy(CreateButton((Assets.Path + "deshae98.pubmethod(en-us,VS.90).gif"), "Proxy")); }
private void AddProperties(IHTMLElement htext) { // todo: interface properties var content = new IHTMLDiv().AttachTo(DocumentBody); content.Hide(); var IsField = new IHTMLInput(ScriptCoreLib.Shared.HTMLInputTypeEnum.checkbox); new IHTMLDiv( new IHTMLLabel("as fields instead of properties: ", IsField), IsField ).AttachTo(content); // var a = new IHTMLTextArea().AttachTo(content); var b = new IHTMLTextArea().AttachTo(content); htext.onclick += delegate { content.ToggleVisible(); }; a.style.display = ScriptCoreLib.JavaScript.DOM.IStyle.DisplayEnum.block; a.style.width = "100%"; a.style.height = "20em"; b.style.display = ScriptCoreLib.JavaScript.DOM.IStyle.DisplayEnum.block; b.style.width = "100%"; b.style.height = "20em"; b.readOnly = true; Action update = delegate { try { //c.removeChildren(); var w = new StringBuilder(); var lines = a.Lines.ToArray(); if (IsField.@checked) w.AppendLine("#region Fields"); else w.AppendLine("#region Properties"); for (int i = 0; i < lines.Length; i += 2) { if ((i + 1) < lines.Length) { var Summary = lines[i + 1].Trim(); if (!lines[i].Contains("AIR-only")) { var ReadOnly = "[read-only]"; w.AppendLine("/// <summary>"); w.AppendLine("/// " + Summary); w.AppendLine("/// </summary>"); var x0 = lines[i].Split(':'); var x1 = x0[1].Trim().Split('='); var DefaultValue = ""; if (x1.Length == 2) DefaultValue = x1[1].Trim(); var TypeName = FixTypeName(x1[0].Trim()); var FieldName = x0[0].Trim(); /* var Image = (IHTMLImage)img.cloneNode(false); Image.style.verticalAlign = "middle"; new IHTMLDiv( Image, new IHTMLCode(TypeName + " " + FieldName) ).AttachTo(c); */ var StaticModifier = Summary.Contains("[static]") ? "static " : ""; if (IsField.@checked) { var ReadonlyModifier = Summary.Contains(ReadOnly) ? "readonly " : ""; var DefaultValueExpression = string.IsNullOrEmpty(DefaultValue) ? "" : " = " + DefaultValue; w.AppendLine("public " + StaticModifier + ReadonlyModifier + TypeName + " " + FieldName + DefaultValueExpression + ";"); } else { if (Summary.Contains(ReadOnly)) w.AppendLine("public " + StaticModifier + TypeName + " " + FieldName + " { get; private set; }"); else w.AppendLine("public " + StaticModifier + TypeName + " " + FieldName + " { get; set; }"); } w.AppendLine(); } } } w.AppendLine("#endregion"); b.value = w.ToString(); htext.style.color = Color.Blue; } catch (Exception ex) { htext.style.color = Color.Red; b.value = "error: " + ex.Message; } }; a.onchange += delegate { update(); }; IsField.onchange += delegate { update(); }; }
public Application(IApp page) { // X:\jsc.svn\examples\javascript\chrome\extensions\ChromeTabsExperiment\ChromeTabsExperiment\Application.cs dynamic self = Native.self; dynamic self_chrome = self.chrome; object self_chrome_tabs = self_chrome.tabs; #region self_chrome_tabs if (self_chrome_tabs != null) { Console.WriteLine("extension is now running..."); #region isYTMissing new { }.With( async delegate { var vid = "TXExg6Xj3aA"; var thumbnail = $"https://img.youtube.com/vi/{vid}/0.jpg"; var thumbnailImage = new IHTMLImage { src = thumbnail }; // wont get those events for 404? //Native.window.onerror += err => //{ // Console.WriteLine( // "window onerror " + // new // { // thumbnail, // err, // thumbnailImage.complete, // thumbnailImage.width, // thumbnailImage.naturalWidth, // thumbnailImage.naturalHeight // } // ); //}; //thumbnailImage.onerror += err => //{ // Console.WriteLine( // "thumbnailImage onerror " + // new // { // thumbnail, // err, // thumbnailImage.complete, // thumbnailImage.width, // thumbnailImage.naturalWidth, // thumbnailImage.naturalHeight // } // ); //}; await thumbnailImage.async.oncomplete; Console.WriteLine( new { thumbnail, thumbnailImage.complete, thumbnailImage.width, thumbnailImage.naturalWidth, thumbnailImage.naturalHeight } ); var thumbnailBytes = await thumbnailImage.async.bytes; Console.WriteLine( new { thumbnailBytes.Length } ); // crc? var sw = Stopwatch.StartNew(); var crc = CRCExample.ActionScript.Crc32Helper.GetCrc32(thumbnailBytes); // 247ms {{ crc = 9e47636d, ElapsedMilliseconds = 7 }} var isYTMissing = 0x9e47636d == crc; Console.WriteLine( new { crc = crc.ToString("x8"), sw.ElapsedMilliseconds, isYTMissing } ); } ); #endregion var oncePerTab = new Dictionary<TabIdInteger, object>(); chrome.tabs.Updated += async (i, x, tab) => { // chrome://newtab/ // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201504/20150423 #region tab if (tab == null) { Console.WriteLine("bugcheck :198 iframe? called with the wrong state?"); return; } Console.WriteLine("enter async chrome.tabs.Updated " + new { tab.url, tab.status }); if (tab.url.StartsWith("chrome-devtools://")) { return; } if (tab.url.StartsWith("chrome://")) return; // while running tabs.insertCSS: The extensions gallery cannot be scripted. if (tab.url.StartsWith("https://chrome.google.com/webstore/")) return; if (tab.status != "complete") { Console.WriteLine("exit async chrome.tabs.Updated, not complete?"); return; } #endregion if (oncePerTab.ContainsKey(tab.id)) return; oncePerTab[tab.id] = new object(); // where is the hop to iframe? // X:\jsc.svn\examples\javascript\Test\TestSwitchToIFrame\TestSwitchToIFrame\Application.cs // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201504/20150403 //await (HopToChromeTab)tab.id; Console.WriteLine("chrome.tabs.Updated will delay, to increment state"); // why do we need this fake await? // cannot resume state otherwise? await Task.Delay(1); // // X:\jsc.svn\market\synergy\javascript\chrome\chrome\chrome.idl var tabIdString = Convert.ToString((object)tab.id); // 13032ms chrome.tabs.Updated will HopToChromeTab {{ tabIdString = 608 }} Console.WriteLine("chrome.tabs.Updated will HopToChromeTab " + new { tabIdString }); // state1: await (HopToChromeTab)tab; // TypeError: Cannot set property 'ztabIdString' of null ztabIdString = tabIdString; //await tab.id; // are we now on the tab? // can we jump back? // 531ms yt found {{ Length = 108 }} // X:\jsc.svn\examples\javascript\test\TestShadowForIFrame\TestShadowForIFrame\Application.cs //var yt1 = Native.document.querySelectorAll(" [class='youtube-player']"); // <iframe width="420" height="315" src="https://www.youtube.com/embed/sJIh70IZua8" frameborder="0" allowfullscreen=""></iframe> // 503ms create iframe... {{ ztabIdString = null }} // what about jumping with files/uploads? Console.WriteLine("create iframe... " + new { ztabIdString }); iframe = new IHTMLIFrame { //src = "about:blank" //new XElement("button", "did extension send us our code? " ) new XElement("script", new XAttribute("src", url), " ") }.AttachTo( Native.document.documentElement ); var yt1 = Native.document.querySelectorAll("iframe"); Console.WriteLine("yt found " + new { yt1.Length }); yt1.WithEach( async e => { //if (e == null) // return; var xiframe = (IHTMLIFrame)e; //13ms yt found { { Length = 9 } } //VM1190: 51533 515ms enter catch //{ // mname = < 01ed > ldloca.s.try } ClauseCatchLocal: // VM1190: 51533 515ms TypeError: Cannot read property 'src' of null if (!xiframe.src.StartsWith("https://www.youtube.com/")) { return; } // can we interact, swap the videos? var size = new { xiframe.clientWidth, xiframe.clientHeight }; var swap = new IHTMLDiv { //new IHTMLPre { xiframe.src }, //new IHTMLContent { } }; new IStyle(swap) { backgroundColor = "yellow", width = size.clientWidth + "px", height = size.clientHeight + "px", overflow = IStyle.OverflowEnum.hidden }; // https://code.google.com/p/dart/issues/detail?id=19561 // 27ms HierarchyRequestError: Failed to execute 'createShadowRoot' on 'Element': Author-created shadow roots are disabled for this element. //swap.AttachTo(xiframe.shadow); xiframe.ReplaceWith(swap); var sh = new IHTMLDiv { }.AttachTo(swap.shadow); var vid = xiframe.src.TakeUntilIfAny("?").SkipUntilOrEmpty("/embed/"); // Remote Address:[2a00: 1450:400f:802::100e]:443 //Request URL: https://img.youtube.com/vi/TXExg6Xj3aA/0.jpg //Request Method: GET //Status Code: 404 OK var thumbnail404 = $"https://img.youtube.com/vi/{vid}/0.jpg"; // lets look at the image. is the video removed? // https://img.youtube.com/vi/TXExg6Xj3aA/0.jpg // http://stackoverflow.com/questions/22097747/getimagedata-error-the-canvas-has-been-tainted-by-cross-origin-data //.AttachToHead(); new IStyle(sh) { width = size.clientWidth + "px", height = size.clientHeight + "px", overflow = IStyle.OverflowEnum.hidden, position = IStyle.PositionEnum.relative, backgroundImage = $"url('{thumbnail404}')", }; //var info = new IHTMLPre { xiframe.src }; var info = new IHTMLPre { new { vid } }; // so we can later find it again... lookup_info[thumbnail404] = info; // assume its not missing until we know more lookup_info_YTmissing[thumbnail404] = false; info.AttachTo(sh); new IStyle(info) { backgroundColor = "rgba(0,0,255, 0.5)", color = "rgba(255,255,0, 0.9)", left = "0px", bottom = "0px", right = "0px", //height = size.clientHeight + "px", position = IStyle.PositionEnum.absolute }; // at this point we need to consult the extension as it can download the bytes new { }.With( async delegate { var xtabIdString = ztabIdString; var xthumbnail404 = thumbnail404; // 517ms about to jump to extension to inspect the damn image... {{ xthumbnail404 = https://img.youtube.com/vi/TXExg6Xj3aA/0.jpg, xtabIdString = 608 }} Console.WriteLine("about to jump to extension to inspect the damn image... " + new { xthumbnail404, xtabIdString }); // fixup? await Task.Delay(1); await default(HopToExtension); Console.WriteLine("about to jump to extension to inspect the damn image... done " + new { xthumbnail404, xtabIdString }); // 43228ms about to jump to extension to inspect the damn image... done {{ xthumbnail404 = https://img.youtube.com/vi/TXExg6Xj3aA/0.jpg, xtabIdString = 608 }} // can we jump back once we know what it was? var thumbnailImage = new IHTMLImage { src = xthumbnail404 }; await thumbnailImage.async.oncomplete; var thumbnailBytes = await thumbnailImage.async.bytes; var sw = Stopwatch.StartNew(); var crc = CRCExample.ActionScript.Crc32Helper.GetCrc32(thumbnailBytes); // we only do strings at this point, not integers, we could do booleans tho... var isYTMissing = Convert.ToString(0x9e47636d == crc); var xtab = await chrome.tabs.get(tabId: Convert.ToInt32(xtabIdString)); //xthumbnail404 = https://img.youtube.com/vi/BZIeqnQ1rY0/0.jpg, isYTMissing = false, xtabIdString = 608, url = https://zproxy.wordpress.com/2015/04/05/thought-form-magicians/ }} // xthumbnail404 = https://img.youtube.com/vi/TXExg6Xj3aA/0.jpg, isYTMissing = true, xtabIdString = 608, url = https://zproxy.wordpress.com/2015/04/05/thought-form-magicians/ }} Console.WriteLine(">> " + new { xthumbnail404, isYTMissing, xtabIdString, xtab.url }); // can we jump back to the tab to color it red if missing? // 43340ms >> {{ xthumbnail404 = https://img.youtube.com/vi/TXExg6Xj3aA/0.jpg, isYTMissing = true, xtabIdString = 608 }} //(HopToChromeTab) // ok now we now what tab we are in but even if we jump back. we wont have a ref to the infobar? await (HopToChromeTab)xtab; Console.WriteLine(">> " + new { xthumbnail404, isYTMissing, xtabIdString } + " back in the tab?"); // would the old variables be reconnected for us? // jumps should be able to resume an old startemachine. lookup_info_YTmissing[xthumbnail404] = Convert.ToBoolean(isYTMissing); var xinfo = lookup_info[xthumbnail404]; //xthumbnail404 = https://img.youtube.com/vi/BZIeqnQ1rY0/0.jpg, isYTMissing = false, xtabIdString = 744 }} back in the tab? if (Convert.ToBoolean(isYTMissing)) { // yikes. video pulled! new IStyle(xinfo) { backgroundColor = "rgba(255,0,0, 0.7)", }; new IHTMLSpan { " do we have a local copy?" }.AttachTo(xinfo); // we should send udp to the archive server? // if it has how can we load it up? return; } new IStyle(xinfo) { backgroundColor = "rgba(255,255,0, 0.5)", }; } ); // https://www.youtube.com/embed/jQLNMljadyo?vers // https://www.youtube.com/embed/M4RBW85J4Cg // http://img.youtube.com/vi/<insert-youtube-video-id-here>/0.jpg await sh.async.onmouseover; // no reason to load it. its missing! if (lookup_info_YTmissing[thumbnail404]) return; xiframe.AttachTo(sh); info.AttachTo(sh); var copyToToolbar = new IHTMLButton { "+" }.AttachTo(info); await copyToToolbar.async.onclick; copyToToolbar.Orphanize(); //width = "128px", //xiframe.style.transform = "scale(0.2)"; new IStyle(xiframe) { width = (128) + "px", height = (96) + "px", }; // This video contains content from WMG. It is restricted from playback on certain sites. xiframe.AttachTo( //iframe.contentWindow.document.documentElement iframe.contentWindow.document.body ); } ); Console.WriteLine("create iframe... done"); //iframe.allowTransparency = true; // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201504/20150423 // __8__1 is null. why? a struct? // b.__this.__8__1.scope = new ctor$vQEABrCB_bTmuL0jGQp_bnVw(b.__this._iframe_5__2); // oh crap. the container is initialized before await (HopToChromeTab)tab; thus lost due to context switch. var scope = new { iframe }; //Console.WriteLine("iframe visible? " + new { scope }); new IStyle(iframe) { borderWidth = "0", // wont animate? transition = "left 300ms linear", // dont want the white box while it loads.. backgroundColor = "rgba(0, 0, 255, 0)", position = IStyle.PositionEnum.@fixed, //left = "1px", top = "32px", width = "128px", // animateIFrame // pre hide it left = "-120px", //height = "100px", // wont work on slashdot? //bottom = "3em" // can we be topmost? //zIndex = 30000 zIndex = 1999999999 }; fixHeight(iframe); animateIFrame(iframe); //var __iframe = iframe; await iframe.async.onload; //new IStyle(iframe) //{ // backgroundColor = "rgba(0, 0, 255, 0.7)", //}; Console.WriteLine("lets hop from tab context to iframe context... "); await (HopToIFrame)iframe; Console.WriteLine("lets hop from tab context to iframe context... done!"); new IStyle(Native.document.body) { margin = "0px", //marginRight = "1em", padding = "0px", paddingRight = "1em", transition = "background-color 300ms linear", backgroundColor = "rgba(0, 0, 255, 0.1)", //border = "1px solid red" }; var button4 = new IHTMLButton { "hop to parent, extension, app" }.AttachToDocument(); new IStyle(button4) { display = IStyle.DisplayEnum.block }; // not yet. need a new example button4.disabled = true; //Native.body.backgroundColor = "rgba(0, 0, 255, 0.7)"; //var text3 = new IHTMLTextArea { value = "hey" }.AttachToDocument(); // need to use static, as scope variables are being encapsulated, and due to context jumps we dont support it yet text3 = new IHTMLTextArea { value = "hey" }.AttachToDocument(); text3.style.width = "100%"; var button3 = new IHTMLButton { "hop to parent, extension" }.AttachToDocument(); new IStyle(button3) { display = IStyle.DisplayEnum.block }; button3.onclick += async delegate { // can we hop back? var data3 = text3.value; Console.WriteLine("enter button3 " + new { data3 }); // 2602ms enter button3 {{ data3 = hey }} // why do we need this fake await? // cannot resume state otherwise? await Task.Delay(1); await default(HopToParent); var tab_title = Native.document.title; // 3105ms are strings being synchronized to iframe? {{ tab_title = IANA — IANA-managed Reserved Domains, data3 = null }} Console.WriteLine("are strings being synchronized from iframe? " + new { tab_title, data3 }); /// 2926ms will hop back to extension!? can we resume later? await default(HopToExtension); //Native.window.alert("hi! i am back home! do we even know which tab we were in? did i get some data yet? " + new { tab_title }); Console.WriteLine("hi! i am back home! do we even know which tab we were in? did i get some data yet? " + new { tab_title, data3 }); // 13844ms hi! i am back home! do we even know which tab we were in? did i get some data yet? {{ tab_title = IANA — IANA-managed Reserved Domains }} // lets guess which tab we clicked on? var tt = await chrome.tabs.getCurrent(); // https://developer.chrome.com/extensions/tabs // https://developer.chrome.com/extensions/windows // https://developer.chrome.com/extensions/processes //chrome.runtime. new chrome.Notification( title: new { data3, tt }.ToString() ); //chrome.tabs.rel // can we do appwindow here or we need to jump out of extension? }; var button2 = new IHTMLButton { "hop to parent" }.AttachToDocument(); new IStyle(button2) { display = IStyle.DisplayEnum.block }; button2.onclick += async delegate { // can we hop back? Console.WriteLine("enter button2"); // why do we need this fake await? // cannot resume state otherwise? await Task.Delay(1); await default(HopToParent); var tab_title = Native.document.title; Console.WriteLine("are strings being synchronized to iframe? " + new { tab_title }); // we are jumping back, yet into a new state machine. //Native.window.alert("hi! in a tab, in an extension! " + new //{ // Native.document.title // , // iframe //}); // can we jump back? is the iframe awaiting for multiple jumps? await (HopToIFrame)iframe; Native.window.alert("hi! iframe, in a tab, in an extension! " + new { Native.document.title, tab_title }); // ok. we now know how to // jump from extension to tab to iframe to tab to iframe // what about workers, and jumping back to extension? // but likely we did not jump to the same data? }; var button1 = new IHTMLButton { "click me" }.AttachToDocument(); new IStyle(button1) { display = IStyle.DisplayEnum.block }; //new { }.With( // async delegate // { // // stack variables not visible, why? // while (await button1.async.onmouseover) // { // new IStyle(Native.document.body) // { // backgroundColor = "rgba(0, 0, 255, 0.8)", // }; // await button1.async.onmouseout; // new IStyle(Native.document.body) // { // backgroundColor = "rgba(0, 0, 255, 0.2)", // }; // } // } //); //oldschool as a workaround button1.onclick += delegate { Native.window.alert("hi! iframe, in a tab, in an extension! " + new { Native.document.title }); }; button1.onmouseover += e => { new IStyle(Native.document.body) { backgroundColor = "rgba(255, 0, 0, 0.9)", }; e.stopPropagation(); }; button1.onmouseout += delegate { new IStyle(Native.document.body) { backgroundColor = "rgba(0, 0, 255, 0.1)", }; }; // we are in iframe! Native.document.onmouseover += delegate { new IStyle(Native.document.body) { backgroundColor = "rgba(0, 0, 255, 0.3)", }; }; Native.document.onmouseout += delegate { new IStyle(Native.document.body) { backgroundColor = "rgba(0, 0, 255, 0.1)", }; }; //var f = new IHTMLButton { "in the frame! click to notify parent" }.AttachToDocument(); //await default(HopToParent); // why need this stackfix? //var stackfix_iframe = iframe; // new { }.With( // async delegate // { // while (await Native.window.async.onresize) // { // stackfix_iframe.style.height = (Native.window.Height - 64) + "px"; // } // } //); // X:\jsc.svn\examples\javascript\Test\TestHopFromIFrame\TestHopFromIFrame\Application.cs // can we jump? // <div class="player-video-title">Ariana Grande - One Last Time (Official)</div> //Native.document.title = "(" + Native.document.title + ")"; // X:\jsc.svn\examples\javascript\xml\FindByClassAndObserve\FindByClassAndObserve\Application.cs // luckyly its only hidden... no need to await the element and find it later // <span id="eow-title" class="watch-title " dir="ltr" title="THORnews Weird Weather Watch! Wind Dragon inbound to USA Pacific Coast!"> //var yt0 = Native.document.querySelectorAll(" [class='player-video-title']"); //var yt1 = Native.document.querySelectorAll(" [class='watch-title ']"); //yt0.Concat(yt1).WithEach( // async e => // { // do // { // Native.document.title = e.innerText; // // X:\jsc.svn\examples\javascript\chrome\extensions\ChromeExtensionHopToTabThenIFrame\ChromeExtensionHopToTabThenIFrame\Application.cs // // we would need to jump back here to do extension notification // // the jump back would be to another state machine tho // // we would need other ports opened? // Native.document.documentElement.style.borderLeft = "1em solid yellow"; // for (int xi = 0; xi < 5; xi++) // { // Native.body.style.borderLeft = "1em solid yellow"; // await Task.Delay(100); // Native.body.style.borderLeft = "1em solid black"; // await Task.Delay(100); // } // Native.document.documentElement.style.borderLeft = "1em solid red"; // // or actually instead of jumping back we need to send back progress? // } // while (await e.async.onmutation); // } // ); // lets start monitoring }; return; } #endregion // 420ms TypeError: Cannot read property 'url' of null Console.WriteLine("nop"); #if true #region inside iframe if (Native.window.parent != Native.window) { // X:\jsc.svn\examples\javascript\chrome\extensions\ChromeExtensionHopToTabThenIFrame\ChromeExtensionHopToTabThenIFrame\Application.cs // inside iframe new { }.With( async delegate { // start the handshake // we gain intellisense, but the type is partal, likely not respawned, acivated, initialized //var m = await Native.window.parent.postMessageAsync<TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine>(); // new IHTMLPre { // "inside iframe awaiting onmessage" //}.AttachToDocument(); // first null jump //Native.window.parent.postMessage(r.shadowstate); var m = await Native.window.parent.postMessageAsync(default(TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine)); Console.WriteLine("iframe got the first state..."); // we can now send one hop back? InternalInvoke(m.data); } ); return; } #endregion #endif Console.WriteLine("nop"); // we made the jump? //Native.body.style.borderLeft = "0em solid red"; // yes we did. can we talk to the chrome extension? // lets do some SETI // The runtime.onMessage event is fired in each content script running in the specified tab for the current extension. // Severity Code Description Project File Line //Error 'runtime.onMessage' is inaccessible due to its protection level ChromeExtensionHopToTabThenIFrame X:\jsc.svn\examples\javascript\chrome\extensions\ChromeExtensionHopToTabThenIFrame\ChromeExtensionHopToTabThenIFrame\Application.cs 272 // public static event System.Action<object, object, object> Message Action<object> PostToExtension = null; #region Connect chrome.runtime.Connect += port => { Console.WriteLine("chrome.runtime.Connect " + new { port.name, port.sender }); // 8295ms will invoke sendResponse... done?? {{ message = jump! }} //port.postMessage("jump! " + new { port.name, port.sender }); PostToExtension = xdata => { // PostToExtension {{ xdata = [object Object] }} Console.WriteLine("PostToExtension " + new { xdata }); //Console.WriteLine("PostToExtension " + new { xdata = JSON.stringify(xdata) }); port.postMessage(xdata); }; }; #endregion #region chrome.runtime.Message chrome.runtime.Message += (object message, chrome.MessageSender sender, IFunction sendResponse) => { var s = (TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine)message; if (url != null) { Console.WriteLine("jumping back to tab for more? done"); InternalInvoke(s); return; } Console.WriteLine("chrome.runtime.Message " + new { s.state, sender.id, code = s.code.Length }); // at this point we can initialize hop to iframe since we have the code we can actually use? // 276ms xonmessage {{ state = 1, id = fkgibadjpabiongmgoeomdbcefhabmah, code = 3296612 }} #region url var aFileParts = new[] { s.code }; var oMyBlob = new Blob(aFileParts, new { type = "text/javascript" }); //var url = oMyBlob.ToObjectURL(); url = URL.createObjectURL(oMyBlob); #endregion Console.WriteLine("will we want to jump back to extension?"); HopToExtension.VirtualOnCompleted += (that, continuation) => { Console.WriteLine("will hop back to extension!? can we resume later?"); var r = TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine.ResumeableFromContinuation(continuation); // can we only send once? //Console.WriteLine("will invoke sendResponse... " + new { sendResponse }); Console.WriteLine("will invoke sendResponse... "); //sendResponse.apply(null, r); //will invoke sendResponse... //(program):51533 1664ms enter catch //{ // mname = < 0154 > ldarg.0.try } ClauseCatchLocal: // (program):51533 1664ms TypeError: Converting circular structure to JSON // planB PostToExtension(r.shadowstate); }; InternalInvoke(s); //Task.Delay(1000).ContinueWith( // delegate // { // sendResponse.apply(null, "response"); // } //); }; #endregion // Native.window.onmessage += e => //{ //}; }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IDefault page) { @"Hello world".ToDocumentTitle(); var output = new IHTMLTextArea().AttachToDocument(); var gexf = new XElement("gexf"); gexf.Add( new XElement("meta", new XElement("creator", "jsc"), new XElement("description", "NASDAQSNA") ) ); var graph = new XElement("graph", new XAttribute("mode", "static"), new XAttribute("defaultedgetype", "directed") ); gexf.Add(graph); var nodes = new XElement("nodes"); graph.Add(nodes); var edges = new XElement("edges"); graph.Add(edges); output.value = gexf.ToString(); output.onfocus += delegate { output.value = gexf.ToString(); }; output.onmouseover += delegate { output.value = gexf.ToString(); }; var NumericNodeIdLookup = new List<string>(); Func<string, int> GetNumericNodeId = k => { if (!NumericNodeIdLookup.Contains(k)) NumericNodeIdLookup.Add(k); return NumericNodeIdLookup.IndexOf(k); }; #region AddRelatedCompanies Func<IHTMLDiv, string, Action, Task> AddRelatedCompanies = null; AddRelatedCompanies = (c, qid, done) => { var nqid = GetNumericNodeId(qid).ToString(); var cc = new IHTMLDiv(); cc.style.marginLeft = "2em"; var service = new ApplicationWebService { qid = qid, yield = (id, CompanyName, Price) => { var nid = GetNumericNodeId(id).ToString(); if (nodes.Elements().Any(k => k.Attribute("id").Name.LocalName == nid)) { } else { nodes.Add( new XElement("node", new XAttribute("id", nid), new XAttribute("label", CompanyName) ) ); } var btn = new IHTMLButton { innerText = id + " " + CompanyName + " " + Price }; btn.style.display = IStyle.DisplayEnum.block; if (qid == id) { btn.disabled = true; if (c == null) { btn.AttachToDocument(); cc.AttachToDocument(); } else { //btn.AttachTo(c); cc.AttachTo(c); } if (done != null) done(); } else { edges.Add( new XElement("edge", new XAttribute("source", nqid), new XAttribute("target", nid) ) ); btn.AttachTo(cc); var ccc = new IHTMLDiv(); ccc.AttachTo(cc); int cx = 0; ccc.ToggleVisible(); btn.WhenClicked( async delegate { if (cx == 0) { btn.style.color = JSColor.Red; await AddRelatedCompanies(ccc, id, delegate { btn.style.color = JSColor.Blue; } ); } cx++; ccc.ToggleVisible(); } ); } } }; return service.GetRelatedCompanies(); }; #endregion AddRelatedCompanies(null, "NASDAQ:FB", null); AddRelatedCompanies(null, "NASDAQ:GOOG", null); }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IApp page) { new { }.With( async delegate { new IHTMLPre { new { Native.document.currentScript } }.AttachToDocument(); var x = await base.GetData(); new IHTMLPre { new { Native.document.currentScript } }.AttachToDocument(); // IPublicKey . VerifyAsync() var verificationKey = await Native.crypto.subtle.importRSAPublicKeyForVerificationAsync( this.PublicKeyModulus, this.PublicKeyExponent ); new IHTMLPre { new { verificationKey } }.AttachToDocument(); //new System.Security.Cryptography.RSACryptoServiceProvider().e var verified = await Native.crypto.subtle.verifyAsync(verificationKey, x.signature, Encoding.UTF8.GetBytes(x.value)); // at any point we can now verify the data from webservice is signed and valid. new IHTMLPre { new { verified } }.AttachToDocument(); // http://caniuse.com/#feat=cryptography //#region keyData //var m64padding = Convert.ToBase64String(base.PublicKeyModulus); //var m64 = m64padding; //while (m64.EndsWith("==")) // m64 = m64.Substring(0, m64.Length - 2); //// make URL friendly: ////str = str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''); //// http://stackoverflow.com/questions/4492426/remove-trailing-when-base64-encoding //m64 = m64.Replace("+", "-").Replace("/", "_").Replace("=+", ""); //var keyData = new //{ // //alg = "RS256", // alg = "RS1", // //alg = "RSA-OAEP", // e = Convert.ToBase64String(base.PublicKeyExponent), // ext = false, // kty = "RSA", // n = m64 //}; //#endregion //// { keyData = { alg = RSA-OAEP, e = AQAB, ext = false, kty = RSA, n = s8uxpsmasavYjVmctC_FSnC98T-qHs8zBsuQF44015gF_jSkM8apog3SZquKXf_SyT8v-HMUSoyBuu1ztbAovQ } } //// http://blog.engelke.com/2014/10/21/web-crypto-and-x-509-certificates/ //// "1.2.840.113549.1.1.5" //// onError { z = DataError: The JWK "alg" member was inconsistent with that specified by the Web Crypto call } //// https://github.com/diafygi/webcrypto-examples //var algorithm = new //{ // name = "RSASSA-PKCS1-v1_5", // //name = "RSA-OAEP", // //hash = new { name = "SHA-256" }, // hash = new { name = "SHA-1" } // //modulusLength = 2048, // //publicExponent, //}; //var sw = Stopwatch.StartNew(); // //Native.crypto.subtle.importKey //var p = Native.crypto.subtle.importKey( // format: "jwk", // keyData: keyData, // algorithm: algorithm, // extractable: false, // keyUsages: new[] { // "encrypt", // // onError { z = SyntaxError: Cannot create a key using the specified key usages. } // "verify" // } //); //p.then( // onSuccess: publicKey => // { // // onSuccess {{ z = [object CryptoKey], ElapsedMilliseconds = 9278 }} // new IHTMLPre { "onSuccess " + new { publicKey, sw.ElapsedMilliseconds } }.AttachToDocument(); // //new IHTMLButton { "encrypt for server" }.AttachToDocument().onclick += // //async delegate // //{ // // // Man in the middle? // // // layered security // // var data = Encoding.UTF8.GetBytes("hello from client"); // // var esw = Stopwatch.StartNew(); // // var ebytes = await Native.crypto.subtle.encryptAsync(algorithm, z, data); // // new IHTMLPre { "encryptAsync " + new { esw.ElapsedMilliseconds } }.AttachToDocument(); // // await UploadEncryptedString( // // ebytes // // ); // //}; // // onSuccess { z = [object CryptoKey], ElapsedMilliseconds = 0 } // Native.crypto.subtle.verify( // new // { // name = "RSASSA-PKCS1-v1_5", // }, // publicKey, //from generateKey or importKey above // x.signature, //ArrayBuffer of the signature // Encoding.UTF8.GetBytes(x.value) //ArrayBuffer of the data // ).then( // onSuccess: verified => // { // new IHTMLPre { // "verify " + // new { // verified} // }.AttachToDocument(); // } // ); // }, // onError: z => // { // // onError { z = DataError: The JWK member "n" could not be base64url decoded or contained padding } // new IHTMLPre { // "onError " + // new { // z} // }.AttachToDocument(); // } //); // onError { z = SyntaxError: Cannot create a key using the specified key usages. } var o = x.value; var t = new IHTMLTextArea { value = x, readOnly = true }.AttachToDocument(); t.style.whiteSpace = IStyle.WhiteSpaceEnum.nowrap; t.style.width = "80em"; //t.style.right = "1em"; t.style.height = "20em"; var status = new IHTMLPre { }.AttachToDocument(); t.style.paddingLeft = "1em"; //t.style.borderLeft = "1em solid green"; t.readOnly = false; ////while (await t.async.onchange) do { t.style.borderLeft = "1em solid yellow"; // Z:\jsc.svn\core\ScriptCoreLib.Windows.Forms\ScriptCoreLib.Windows.Forms\JavaScript\BCLImplementation\System\Windows\Forms\TextBox.cs x.value = t.value.Replace(Environment.NewLine, "\n").Replace("\n", Environment.NewLine); verified = await Native.crypto.subtle.verifyAsync(verificationKey, x.signature, Encoding.UTF8.GetBytes(x.value)); //var verify = await base.Verify(x); status.innerText = new { isoriginal = o == x.value, o = o.Length, t = x.value.Length, verified }.ToString(); if (verified) t.style.borderLeft = "1em solid green"; else t.style.borderLeft = "1em solid red"; } while (await t.async.onkeyup); } ); }
//override void InternalSetAcceptsReturn(bool value) { if (value) if (InternalTextField != null) if (InternalTextField_MultiLine == null) { // known situation this.InternalTextField_MultiLine = new IHTMLTextArea(this.InternalTextField.value) { readOnly = this.InternalTextField.readOnly, wrap = "off" }; // X:\jsc.svn\examples\javascript\forms\SQLiteConsoleExperiment\SQLiteConsoleExperiment\ApplicationControl.cs //refresh this.InternalTextField_MultiLine.style.margin = "0"; this.InternalTextField_MultiLine.style.paddingTop = "0"; this.InternalTextField_MultiLine.style.paddingBottom = "0"; this.InternalTextField_MultiLine.style.position = IStyle.PositionEnum.absolute; this.InternalTextField_MultiLine.style.SetLocation(0, 0); this.InternalTextField_MultiLine.style.overflow = IStyle.OverflowEnum.hidden; this.InternalTextField_MultiLine.style.resize = "none"; this.InternalTextField_MultiLine.style.outline = "none"; // http://www.electrictoolbox.com/disable-textarea-resizing-safari-chrome/ this.BackColor = this.BackColor; this.ForeColor = this.ForeColor; this.BorderStyle = this.BorderStyle; if (InternalUpdateScrollBars != null) InternalUpdateScrollBars(); var p = this.InternalTextField.parentNode; // we should actually just notify our collection about this change // but instead we do the exchange here at the moment if (p != null) { p.insertBefore(this.InternalTextField_MultiLine, this.InternalTextField); p.removeChild(this.InternalTextField); //Console.WriteLine("InternalSetAcceptsReturn!!"); } this.InternalTextField_MultiLine.style.width = "100%"; this.InternalTextField_MultiLine.style.height = "100%"; // lets apply current font - probably is the default font... //this.FontFamily = this.InternalFontFamily; //this.FontSize = this.InternalFontSize; this.InternalSetFont(this.Font); Action InternalAutoSizeUpdate = delegate { if (this.InternalTextField_Shadow == null) return; //this.InternalAutoSizeToText(this.InternalTextField_MultiLine.value); }; this.InternalTextField_MultiLine.onchange += delegate { InternalAutoSizeUpdate(); this.InternalRaiseTextChanged(); }; this.InternalTextField_MultiLine.onkeyup += delegate { InternalAutoSizeUpdate(); this.InternalRaiseTextChanged(); }; //InternalUpdateBackground(); //InternalUpdateBorderThickness(); //InternalUpdateForeground(); return; } throw new NotImplementedException(); }
public Application(IHTMLElement e) { Native.Document.title = "IntelliSense1"; var c = new IHTMLDiv { }.AttachToDocument(); c.onmouseover += delegate { c.style.backgroundColor = "#efefff"; }; c.onmouseout += delegate { c.style.backgroundColor = ""; }; c.style.margin = "2em"; c.style.padding = "2em"; c.style.border = "1px solid #777777"; c.style.borderLeft = "2em solid #777777"; new IHTMLDiv { new IHTMLAnchor { innerText = "Write javascript, flash and java applets within a C# project.", href = "http://www.jsc-solutions.net" } }.AttachTo(c); { var btn = new IHTMLButton { innerText = "UltraWebService" }.AttachTo(c); btn.onclick += delegate { new UltraWebService().GetTime("time: ", result => { new IHTMLDiv { innerText = result }.AttachTo(c); } ); }; } var Editor = new IHTMLDiv().AttachToDocument(); Editor.style.position = IStyle.PositionEnum.relative; Editor.style.backgroundColor = "#efefef"; Editor.style.SetSize(400, 200); //Editor.style.overflow = IStyle.OverflowEnum.auto; var CodeShadowContainer = new IHTMLDiv().AttachTo(Editor); var CodeShadowSize = new IHTMLSpan().AttachTo(CodeShadowContainer); var CodeShadow = new IHTMLSpan().AttachTo(CodeShadowContainer); var CodeShadowLine = new IHTMLSpan().AttachTo(CodeShadowContainer); var CodeShadowMenu = new IHTMLDiv().AttachTo(CodeShadowContainer); CodeShadowMenu.style.backgroundColor = "red"; var Code = new IHTMLTextArea().AttachTo(Editor); Code.style.SetLocation(0, 0, 400, 200); CodeShadowSize.style.position = IStyle.PositionEnum.absolute; CodeShadowSize.style.SetLocation(0, 0); CodeShadow.style.position = IStyle.PositionEnum.absolute; CodeShadow.style.SetLocation(0, 0); CodeShadowLine.style.position = IStyle.PositionEnum.absolute; CodeShadowLine.style.SetLocation(0, 0); CodeShadowContainer.style.SetLocation(0, 0, 400, 200); Action Update = delegate { CodeShadowSize.innerText = Code.value; var n = Code.value.Substring(0, Code.SelectionStart).Replace("\r", ""); CodeShadow.innerText = n; CodeShadowLine.innerText = n.SkipUntilLastIfAny("\n"); //var w = CodeShadowSize.offsetWidth; //if (w < 400) // w = 400; //var h = CodeShadowSize.offsetHeight; //if (h < 200) // h = 200; //Code.style.SetSize(w, h); if (n.EndsWith(".")) { CodeShadowMenu.style.SetLocation( CodeShadowLine.offsetWidth, CodeShadow.offsetHeight, 64, 32 ); } else { CodeShadowMenu.style.SetLocation( CodeShadowLine.offsetWidth, CodeShadow.offsetHeight, 12, 12 ); } }; Code.onkeyup += delegate { Update(); }; Code.onchange += delegate { Update(); }; Code.onmouseup += delegate { Update(); }; Action<IStyle> SetStyle = style => { style.padding = "0"; style.margin = "0"; style.display = IStyle.DisplayEnum.inline; style.fontFamily = ScriptCoreLib.JavaScript.DOM.IStyle.FontFamilyEnum.Verdana; style.fontSize = "1em"; // http://www.tagindex.net/css/form/line_height.html // http://www.eskimo.com/~bloo/indexdot/css/properties/dimension/lineheight.htm style.lineHeight = "200%"; // http://www.w3schools.com/CSS/pr_text_white-space.asp style.whiteSpace = IStyle.WhiteSpaceEnum.pre; //style.textWrap = }; Code.style.border = "0"; // http://www.idocs.com/tags/forms/_TEXTAREA_WRAP.html Code.wrap = "off"; Code.style.overflow = IStyle.OverflowEnum.hidden; Code.style.backgroundColor = JSColor.Transparent; //if (IsMicrosoftInternetExplorer) //{ // CodeShadow.style.lineHeight = "125%"; //} CodeShadow.style.color = "gray"; CodeShadow.style.backgroundColor = "yellow"; CodeShadowLine.style.color = "gray"; CodeShadowLine.style.backgroundColor = "cyan"; SetStyle(Code); SetStyle(CodeShadowSize); SetStyle(CodeShadow); SetStyle(CodeShadowLine); Code.value = "hello1\nhello2\nhello3 WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\n..."; Update(); }
// https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160108/udp // Z:\jsc.svn\examples\c\android\Test\TestNDKUDP\TestNDKUDP\xNativeActivity.cs // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20151212/androidudpclipboard // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160101/ovrwindwheelndk // from red to asus // net use // subst a: s:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPClipboard\bin\Debug\staging\ChromeUDPClipboard.Application\web /// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IApp page) { #region += Launched chrome.app.window dynamic self = Native.self; dynamic self_chrome = self.chrome; object self_chrome_socket = self_chrome.socket; if (self_chrome_socket != null) { if (!(Native.window.opener == null && Native.window.parent == Native.window.self)) { Console.WriteLine("chrome.app.window.create, is that you?"); // pass thru } else { // should jsc send a copresence udp message? //chrome.runtime.UpdateAvailable += delegate //{ // new chrome.Notification(title: "UpdateAvailable"); //}; // nuget chrome chrome.app.runtime.Launched += async delegate { // 0:12094ms chrome.app.window.create {{ href = chrome-extension://aemlnmcokphbneegoefdckonejmknohh/_generated_background_page.html }} Console.WriteLine("chrome.app.window.create " + new { Native.document.location.href }); new chrome.Notification(title: "ChromeUDPClipboard"); // https://developer.chrome.com/apps/app_window#type-CreateWindowOptions var xappwindow = await chrome.app.window.create( Native.document.location.pathname, options: new { alwaysOnTop = true, visibleOnAllWorkspaces = true } ); //xappwindow.setAlwaysOnTop xappwindow.show(); await xappwindow.contentWindow.async.onload; Console.WriteLine("chrome.app.window loaded!"); }; return; } } #endregion Native.document.body.style.backgroundColor = "darkcyan"; (Native.body.style as dynamic).webkitUserSelect = "text"; new IHTMLButton { "update pending... update available. click to reload.." }.AttachToDocument().onclick += delegate { // can we get an udp signal from the compiler when the app is out of date, when the update is pending? chrome.runtime.reload(); }; new IHTMLHorizontalRule { }.AttachToDocument(); var i = new IHTMLTextArea { }.AttachToDocument(); new IHTMLHorizontalRule { }.AttachToDocument(); #region UDPClipboardSend // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160103/x360videoui // Z:\jsc.svn\examples\javascript\chrome\apps\WebGL\ChromeEquirectangularPanorama\ChromeEquirectangularPanorama\Application.cs Action<string> UDPClipboardSend = async message => { var n = await chrome.socket.getNetworkList(); new IHTMLPre { new { n.Length } }.AttachToDocument(); // LINQ and async wont mix for 2012? //foreach (var item in n.Where(x => x.prefixLength == 24)) foreach (var item in n) if (item.prefixLength == 24) { new IHTMLPre { new { item.prefixLength, item.name, item.address } }.AttachToDocument(); //{ prefixLength = 64, name = {AE3B881D-488F-4C3A-93F8-7DA0D65B9300}, address = fe80::fc45:cae9:46ca:7b0f } //about to bind... { port = 29129 } //about to send... { Length = 0 } //sent: -2 //{ prefixLength = 24, name = {AE3B881D-488F-4C3A-93F8-7DA0D65B9300}, address = 192.168.1.12 } //about to bind... { port = 25162 } //about to send... { Length = 0 } //sent: 0 // X:\jsc.svn\examples\merge\TestDetectOpenFiles\TestDetectOpenFiles\Program.cs // X:\jsc.svn\examples\javascript\chrome\apps\MulticastListenExperiment\MulticastListenExperiment\Application.cs // https://code.google.com/p/chromium/issues/detail?id=455352 // X:\jsc.svn\examples\merge\TestDetectOpenFiles\TestDetectOpenFiles\Program.cs // bind? var data = Encoding.UTF8.GetBytes(message); //creates a variable b of type byte // http://stackoverflow.com/questions/13691119/chrome-packaged-app-udp-sockets-not-working // http://www.chinabtp.com/how-to-do-udp-broadcast-using-chrome-sockets-udp-api/ // chrome likes 0 too. var port = new Random().Next(16000, 40000); //var port = 0; // //new IHTMLPre { "about to bind... " + new { port } }.AttachToDocument(); // where is bind async? var socket = new UdpClient(); socket.Client.Bind( //new IPEndPoint(IPAddress.Any, port: 40000) new IPEndPoint(IPAddress.Parse(item.address), port) ); //new IHTMLPre { "about to send... " + new { data.Length } }.AttachToDocument(); // X:\jsc.svn\examples\javascript\chrome\apps\ChromeUDPNotification\ChromeUDPNotification\Application.cs var s = await socket.SendAsync( data, data.Length, hostname: "239.1.2.3", port: 49814 ); //new IHTMLPre { "sent: " + s }.AttachToDocument(); //socket.ReceiveAsync //socket.Close(); //new IHTMLPre { $"sent: {s}" }.AttachToDocument(); // android cannot see it. why? because it needs to know which NIC to use. } }; #endregion // Z:\jsc.svn\examples\c\android\Test\TestNDKUDP\TestNDKUDP\xNativeActivity.cs new { }.With( async delegate { do { var v = await Native.document.documentElement.async.ondroptext; i.value = v; UDPClipboardSend(v); } while (true); } ); new IHTMLButton { () => "send to '" + i.value + "' android" }.AttachToDocument().onclick += async delegate { UDPClipboardSend(i.value); }; }
private void AddConstants(IHTMLElement htext) { var content = new IHTMLDiv().AttachTo(DocumentBody); content.Hide(); var IsEnum = "Declare constants as enums ".ToCheckBox().AttachToWithLabel(content); var update = default(Action); // var a = new IHTMLTextArea().AttachTo(content); IHTMLButton.Create( "Example code", delegate { a.value = @"ACTIVATE : String = ""activate"" [static] The Event.ACTIVATE constant defines the value of the type property of an activate event object. ADDED : String = ""added"" [static] The Event.ADDED constant defines the value of the type property of an added event object. ADDED_TO_STAGE : String = ""addedToStage"" [static] The Event.ADDED_TO_STAGE constant defines the value of the type property of an addedToStage event object. CANCEL : String = ""cancel"" [static] The Event.CANCEL constant defines the value of the type property of a cancel event object. CHANGE : String = ""change"" [static] The Event.CHANGE constant defines the value of the type property of a change event object. CLOSE : String = ""close"" [static] The Event.CLOSE constant defines the value of the type property of a close event object. AIR-only CLOSING : String = ""closing"" [static] The Event.CLOSING constant defines the value of the type property of a closing event object. COMPLETE : String = ""complete"" [static] The Event.COMPLETE constant defines the value of the type property of a complete event object. CONNECT : String = ""connect"" [static] The Event.CONNECT constant defines the value of the type property of a connect event object. DEACTIVATE : String = ""deactivate"" [static] The Event.DEACTIVATE constant defines the value of the type property of a deactivate event object. AIR-only DISPLAYING : String = ""displaying"" [static] Defines the value of the type property of a displaying event object. ENTER_FRAME : String = ""enterFrame"" [static] The Event.ENTER_FRAME constant defines the value of the type property of an enterFrame event object. AIR-only EXITING : String = ""exiting"" [static] The Event.EXITING constant defines the value of the type property of an exiting event object. FULLSCREEN : String = ""fullScreen"" [static] The Event.FULL_SCREEN constant defines the value of the type property of a fullScreen event object. AIR-only HTML_BOUNDS_CHANGE : String = ""htmlBoundsChange"" [static] The Event.HTML_BOUNDS_CHANGE constant defines the value of the type property of an htmlBoundsChange event object. AIR-only HTML_DOM_INITIALIZE : String = ""htmlDOMInitialize"" [static] The Event.HTML_DOM_INITIALIZE constant defines the value of the type property of an htmlDOMInitialize event object. AIR-only HTML_RENDER : String = ""htmlRender"" [static] The Event.HTML_RENDER constant defines the value of the type property of an htmlRender event object. ID3 : String = ""id3"" [static] The Event.ID3 constant defines the value of the type property of an id3 event object. INIT : String = ""init"" [static] The Event.INIT constant defines the value of the type property of an init event object. AIR-only LOCATION_CHANGE : String = ""locationChange"" [static] The Event.LOCATION_CHANGE constant defines the value of the type property of a locationChange event object. MOUSE_LEAVE : String = ""mouseLeave"" [static] The Event.MOUSE_LEAVE constant defines the value of the type property of a mouseLeave event object. AIR-only NETWORK_CHANGE : String = ""networkChange"" [static] The Event.NETWORK_CHANGE constant defines the value of the type property of a networkChange event object. OPEN : String = ""open"" [static] The Event.OPEN constant defines the value of the type property of an open event object. REMOVED : String = ""removed"" [static] The Event.REMOVED constant defines the value of the type property of a removed event object. REMOVED_FROM_STAGE : String = ""removedFromStage"" [static] The Event.REMOVED_FROM_STAGE constant defines the value of the type property of a removedFromStage event object. RENDER : String = ""render"" [static] The Event.RENDER constant defines the value of the type property of a render event object. RESIZE : String = ""resize"" [static] The Event.RESIZE constant defines the value of the type property of a resize event object. SCROLL : String = ""scroll"" [static] The Event.SCROLL constant defines the value of the type property of a scroll event object. SELECT : String = ""select"" [static] The Event.SELECT constant defines the value of the type property of a select event object. SOUND_COMPLETE : String = ""soundComplete"" [static] The Event.SOUND_COMPLETE constant defines the value of the type property of a soundComplete event object. TAB_CHILDREN_CHANGE : String = ""tabChildrenChange"" [static] The Event.TAB_CHILDREN_CHANGE constant defines the value of the type property of a tabChildrenChange event object. TAB_ENABLED_CHANGE : String = ""tabEnabledChange"" [static] The Event.TAB_ENABLED_CHANGE constant defines the value of the type property of a tabEnabledChange event object. TAB_INDEX_CHANGE : String = ""tabIndexChange"" [static] The Event.TAB_INDEX_CHANGE constant defines the value of the type property of a tabIndexChange event object. UNLOAD : String = ""unload"" [static] The Event.UNLOAD constant defines the value of the type property of an unload event object. AIR-only USER_IDLE : String = ""userIdle"" [static] The Event.USER_IDLE constant defines the value of the type property of a userIdle event object. AIR-only USER_PRESENT : String = ""userPresent"" [static] The Event.USER_PRESENT constant defines the value of the type property of a userPresent event object. "; update(); } ).AttachTo(content); var z = new IHTMLTable().AttachTo(content); var zb = z.AddBody(); var b = new IHTMLTextArea().AttachTo(content); htext.onclick += delegate { content.ToggleVisible(); }; a.style.display = ScriptCoreLib.JavaScript.DOM.IStyle.DisplayEnum.block; a.style.width = "100%"; a.style.height = "20em"; b.style.display = ScriptCoreLib.JavaScript.DOM.IStyle.DisplayEnum.block; b.style.width = "100%"; b.style.height = "20em"; b.readOnly = true; Action<Action<string>> update_output = handler => { var w = new StringBuilder(); var w2 = new StringBuilder(); var lines = a.Lines.ToArray(); if (IsEnum.@checked) { w.AppendLine("public enum " + DeclaringType.value); w.AppendLine("{"); } else w.AppendLine("#region Constants"); for (int i = 0; i < lines.Length; i += 2) { if ((i + 1) < lines.Length) { var Summary = lines[i + 1].Trim(); var x = lines[i].Split(':'); var ConstantName = x[0].Trim(); if (ConstantName.Contains("(")) throw new Exception("Invalid Constant Name"); var y = x[1].Trim().Split('='); var ConstantType = FixTypeName(y[0].Trim()); var ConstantValue = y[1].Trim(); if (!ConstantName.Contains("AIR-only")) { w.AppendLine("/// <summary>"); w.AppendLine("/// " + Summary); w.AppendLine("/// </summary>"); if (handler != null) handler(ConstantName); if (IsEnum.@checked) { var Prefix = DeclaringType.value.ToLower() + "_"; if (ConstantName.ToLower().StartsWith(Prefix)) ConstantName = ConstantName.Substring(Prefix.Length).ToLower().ToCamelCase(); if (string.IsNullOrEmpty(ConstantValue)) w.AppendLine(ConstantName + ","); else w.AppendLine(ConstantName + " = " + ConstantValue + ","); } else { if (string.IsNullOrEmpty(ConstantValue)) w.AppendLine("public static readonly " + ConstantType + " " + ConstantName + ";"); else w.AppendLine("public static readonly " + ConstantType + " " + ConstantName + " = " + ConstantValue + ";"); } w.AppendLine(); } } } if (IsEnum.@checked) { w.AppendLine("}"); } else w.AppendLine("#endregion"); b.value = w.ToString(); }; update = delegate { try { zb.removeChildren(); update_output( null ); htext.style.color = Color.Blue; } catch (Exception ex) { htext.style.color = Color.Red; b.value = "error: " + ex.Message; } }; DeclaringType.onchange += delegate { update(); }; IsEnum.onchange += delegate { update(); }; a.onchange += delegate { update(); }; }
/// <summary> /// This is a javascript application. /// </summary> /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param> public Application(IApp page) { // how can we connect VR headset webview and chrome app mouse lock? // X:\jsc.svn\examples\javascript\p2p\RTCPeerIPAddress\RTCPeerIPAddress\Application.cs // http://www.html5rocks.com/en/tutorials/webrtc/basics/ // http://simpl.info/rtcdatachannel/ // http://www.webrtc.org/ // http://www.html5rocks.com/en/tutorials/webrtc/basics/#toc-rtcdatachannel // https://bloggeek.me/webrtc-data-channel-uses/ // http://www.slideshare.net/victorpascual/webrtc-datachannels-demystified // http://simpl.info/rtcdatachannel/js/main.js // http://stackoverflow.com/questions/20396160/how-to-transfer-file-between-two-browsers-with-webrtc // http://blog.printf.net/articles/2013/05/17/webrtc-without-a-signaling-server/ // https://www.webrtc-experiment.com/docs/how-file-broadcast-works.html // http://lists.w3.org/Archives/Public/public-webrtc/2012Jul/0008.html // https://code.google.com/p/webrtc/issues/detail?id=1430 // http://blog.printf.net/articles/2014/07/01/serverless-webrtc-continued/ // https://github.com/muaz-khan/WebRTC-Experiment/tree/master/DataChannel // https://www.webrtc-experiment.com/docs/how-to-use-rtcdatachannel-and-rtcpeerconnectionjs.html // http://omshiv.github.io/impressions/jsfoo/webrtc-talk/#/6 // https://groups.google.com/forum/#!topic/discuss-webrtc/CNWplOqtV_w // https://groups.google.com/forum/#!topic/discuss-webrtc/9zs21EBciNM Native.body.Clear(); new { }.With( async delegate { var yellow = new IHTMLDiv { }.AttachToDocument(); yellow.style.position = IStyle.PositionEnum.absolute; yellow.style.right = "0px"; yellow.style.top = "0px"; yellow.style.backgroundColor = "cyan"; #region remotePeerConnection var remotePeerConnection = new RTCPeerConnection(null, null //new { optional = new[] { new { RtpDataChannels = true } } } ); #region onicecandidate // onICE: It returns locally generated ICE candidates; so you can share them with other peer(s). remotePeerConnection.onicecandidate = new Action<RTCPeerConnectionIceEvent>( (RTCPeerConnectionIceEvent e) => { if (e.candidate == null) return; // onicecandidate: {{ sdpMLineIndex = 0, candidate = candidate:630834096 1 tcp 1518214911 192.168.43.252 0 typ host tcptype active generation 0 }} new IHTMLPre { "remotePeerConnection.onicecandidate: " + new { e.candidate.sdpMLineIndex, e.candidate.sdpMid } }.AttachTo(yellow); new IHTMLTextArea { value = e.candidate.candidate, title = "for local addIceCandidate" }.AttachTo(yellow); } ); #endregion #region ondatachannel remotePeerConnection.ondatachannel = new Action<RTCDataChannelEvent>( (RTCDataChannelEvent e) => { new IHTMLPre { "enter remotePeerConnection.ondatachannel " }.AttachTo(yellow); var data = default(object); var counter = 0; new IHTMLPre { () => "onmessage: " + new { data, counter } }.AttachTo(yellow); //Native.document.title e.channel.onmessage += m => { counter++; data = m.data; }; } ); #endregion #endregion #if RRTCIceCandidate //remotePeerConnection.addIceCandidate(event.candidate); var xcandidate = new IHTMLTextArea { }.AttachToDocument(); await new IHTMLButton { "addIceCandidate" }.AttachToDocument().async.onclick; var candidate = new RTCIceCandidate(new { candidate = xcandidate.value, sdpMLineIndex = 0, sdpMid = "data" }); #region remotePeerConnection.addIceCandidate // http://stackoverflow.com/questions/23325510/not-able-to-add-remote-ice-candidate-in-webrtc // ??? wtf new IHTMLPre { "before remotePeerConnection.addIceCandidate" }.AttachToDocument(); // TypeError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Valid arities are: [1, 3], but 2 arguments provided. remotePeerConnection.addIceCandidate( candidate, new Action( delegate { new IHTMLPre { "at remotePeerConnection.addIceCandidate" }.AttachToDocument(); } ), new Action<object>( err => { // All callback-based methods have been moved to a legacy section, and replaced by same-named overloads using Promises instead // err remotePeerConnection.addIceCandidate {{ err = Error processing ICE candidate }} new IHTMLPre { "err remotePeerConnection.addIceCandidate " + new { err } }.AttachToDocument(); } ) ); new IHTMLPre { "after remotePeerConnection.addIceCandidate" }.AttachToDocument(); #endregion #endif var x = new IHTMLTextArea { }.AttachTo(yellow); await new IHTMLButton { "setRemoteDescription" }.AttachTo(yellow).async.onclick; //await x.async.onch var desc = new RTCSessionDescription(new { sdp = x.value, type = "offer" }); new IHTMLPre { "before remotePeerConnection.setRemoteDescription" }.AttachTo(yellow); remotePeerConnection.setRemoteDescription(desc, new Action( delegate { new IHTMLPre { "at remotePeerConnection.setRemoteDescription" }.AttachTo(yellow); // the second parameter to setRemoteDescription is a completion callback. Call createAnswer from within the callback to avoid a race condition new IHTMLPre { "before remotePeerConnection.createAnswer" }.AttachTo(yellow); remotePeerConnection.createAnswer( e => { new IHTMLPre { "at remotePeerConnection.createAnswer" }.AttachTo(yellow); remotePeerConnection.setLocalDescription(e, new Action( delegate { } ) ); new IHTMLTextArea { readOnly = true, value = e.sdp, title = "for localPeerConnection.setRemoteDescription" }.AttachTo(yellow); // localPeerConnection.setRemoteDescription(desc); } ); } ) ); } ); new { }.With( async delegate { new IHTMLHorizontalRule { }.AttachToDocument(); //(await new IHTMLButton { "start" }.AttachToDocument().async.onclick).Element.Orphanize(); await new IHTMLButton { "createOffer" }.AttachToDocument().async.onclick; // createConnection // TypeError: Failed to construct 'RTCPeerConnection': Malformed constraints object. var localPeerConnection = new RTCPeerConnection(null, null //new { optional = new[] { new { RtpDataChannels = true } } } ); #region onicecandidate // onICE: It returns locally generated ICE candidates; so you can share them with other peer(s). localPeerConnection.onicecandidate = new Action<RTCPeerConnectionIceEvent>( (RTCPeerConnectionIceEvent e) => { if (e.candidate == null) return; // onicecandidate: {{ sdpMLineIndex = 0, candidate = candidate:630834096 1 tcp 1518214911 192.168.43.252 0 typ host tcptype active generation 0 }} new IHTMLPre { "localPeerConnection.onicecandidate: " + new { e.candidate.candidate, e.candidate.sdpMLineIndex, e.candidate.sdpMid } }.AttachToDocument(); } ); #endregion #region sendChannel var sendChannel = localPeerConnection.createDataChannel( "sendDataChannel", new { reliable = false }); sendChannel.onopen = new Action( async delegate { new IHTMLPre { "sendChannel.onopen" }.AttachToDocument(); sendChannel.send("hi!"); var counter = 0; Native.body.onmousemove += e => { if (Native.document.pointerLockElement != Native.body) return; counter++; // rpc switchTo sendChannel.send( new { counter, e.movementX, e.movementY }.ToString() ); //await for new message to continue? // webrtc meets async }; var btn = new IHTMLButton("pointerlock").AttachToDocument(); while (await btn.async.onclick) { new IHTMLPre { "requestPointerLock" }.AttachToDocument(); Native.body.requestPointerLock(); } } ); sendChannel.onclose = new Action( delegate { new IHTMLPre { "sendChannel.onclose" }.AttachToDocument(); } ); #endregion localPeerConnection.createOffer( x => { new IHTMLPre { "enter localPeerConnection.createOffer > setLocalDescription" }.AttachToDocument(); new IHTMLTextArea { readOnly = true, value = x.sdp }.AttachToDocument(); localPeerConnection.setLocalDescription(x, new Action( async delegate { new IHTMLPre { "enter localPeerConnection.createOffer > setLocalDescription done" }.AttachToDocument(); var z = new IHTMLTextArea { }.AttachToDocument(); await new IHTMLButton { "setRemoteDescription" }.AttachToDocument().async.onclick; localPeerConnection.setRemoteDescription( new RTCSessionDescription(new { sdp = z.value, type = "answer" }), new Action( async delegate { new IHTMLPre { "? done" }.AttachToDocument(); //// ncaught InvalidStateError: Failed to execute 'send' on 'RTCDataChannel': RTCDataChannel.readyState is not 'open' //sendChannel.send("hi?"); //remotePeerConnection.addIceCandidate(event.candidate); var xcandidate = new IHTMLTextArea { }.AttachToDocument(); await new IHTMLButton { "addIceCandidate" }.AttachToDocument().async.onclick; var candidate = new RTCIceCandidate(new { candidate = xcandidate.value, sdpMLineIndex = 0, sdpMid = "data" }); #region remotePeerConnection.addIceCandidate // http://stackoverflow.com/questions/23325510/not-able-to-add-remote-ice-candidate-in-webrtc // ??? wtf new IHTMLPre { "before localPeerConnection.addIceCandidate" }.AttachToDocument(); // TypeError: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Valid arities are: [1, 3], but 2 arguments provided. localPeerConnection.addIceCandidate( candidate, new Action( delegate { new IHTMLPre { "at localPeerConnection.addIceCandidate" }.AttachToDocument(); } ), new Action<object>( err => { // All callback-based methods have been moved to a legacy section, and replaced by same-named overloads using Promises instead // err remotePeerConnection.addIceCandidate {{ err = Error processing ICE candidate }} new IHTMLPre { "err localPeerConnection.addIceCandidate " + new { err } }.AttachToDocument(); } ) ); new IHTMLPre { "after localPeerConnection.addIceCandidate" }.AttachToDocument(); #endregion } ) ); } ) ); } ); // The PeerConnection won't start gathering candidates until you call setLocalDescription(); the information supplied to setLocalDescription tells PeerConnection how many candidates need to be gathered. // localPeerConnection.createOffer(gotLocalDescription); //new IHTMLPre { "now what? " + new { sendChannel } }.AttachToDocument(); } ); }