/// <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 serviceworker if (Native.serviceworker != null) { // since chrome does not yet tell us who the clients //are we need to collect the intel in user code? var clients = new { e = default(MessageEvent), edata = default(ClientData) }.AsEmptyListWithEvents(); Native.serviceworker.onmessage += e => { var edata = (ClientData)e.data; // if the data identity is already know, then its an update // we will ignore current ports and reuse previous ones. var known = clients.Source.FirstOrDefault(x => x.edata.identity == edata.identity); if (known != null) { if (known.edata.window_screenLeft == edata.window_screenLeft) { if (known.edata.window_screenTop == edata.window_screenTop) { if (known.edata.closed == edata.closed) { // discard as nop return; } } } Console.WriteLine( "serviceworker.onmessage update " + new { edata.window_screenLeft, edata.window_screenTop } ); known.edata.closed = edata.closed; known.edata.window_screenLeft = edata.window_screenLeft; known.edata.window_screenTop = edata.window_screenTop; known.edata.window_Width = edata.window_Width; known.edata.window_Height = edata.window_Height; // data updated // let everybody know clients.Source.WithEach( x => { // let each know of this specific data item, not about their own data x.e.postMessage(known.edata); } ); return; } // how could the as operator know if object is of a type //var edata = e.data as ClientData; // 48686ms serviceworker.onmessage {{ source = null, data = [object Object] }} // tab is telling us something. Console.WriteLine( "serviceworker.onmessage " + new { edata.screen_width, edata.screen_height } ); //e.postMessage("got it! " + new //{ // edata.screen_width, // edata.screen_height //} //); // echo back what the tab told us e.postMessage(edata); // late to the party? // let the newby know about the others. clients.Source.WithEach( n => { e.postMessage(n.edata); } ); clients.Source.Add(new { e, edata }); clients.Added += (n, nindex) => { Console.WriteLine( "serviceworker.onmessage clients.Added " + new { nindex } ); // report that somebody joined? e.postMessage(n.edata); }; }; return; } #endregion // this does not work within shadow root, due to css use? //FormStyler.AtFormCreated = FormStylerLikeChrome.LikeChrome; // wont see it on black background //FormStyler.AtFormCreated = FormStylerLikeFloat.LikeFloat; new IHTMLAnchor { href = "chrome://serviceworker-internals", innerText = "chrome://serviceworker-internals" }.AttachToDocument(); new IHTMLPre { "Opens the DevTools window for ServiceWorker on start for debugging." }.AttachToDocument(); new IHTMLBreak { }.AttachToDocument(); #region register if (Native.window.navigator.serviceWorker.controller == null) { Native.css.style.borderTop = "1em solid red"; // we need to register! new { }.With(async delegate { var sw = Stopwatch.StartNew(); new IHTMLPre { "service register!" }.AttachToDocument(); // should jsc do this automatically? // how many test cases should be made to understand it? var activated = await Native.window.navigator.serviceWorker.activate(); new IHTMLPre { "service activated! " + new { sw.ElapsedMilliseconds } }.AttachToDocument(); Native.css.style.borderTop = "1em solid yellow"; new IHTMLButton { "reload to become controlled client " }.AttachToDocument().onclick += delegate { // is this something jsc app should do automatically? Native.document.location.reload(); }; } ); return; } else { Native.css.style.borderTop = "1em solid green"; new IHTMLPre { "service as controller!" }.AttachToDocument(); } #endregion // we need to get roslyn compiler to work for scriptcorelib windows forms. // dual 4k is to be the max for visualization? // shall we use templates to bring the point across? // based on // X:\jsc.svn\examples\javascript\Test\TestServiceWorkerFetchHTML\TestServiceWorkerFetchHTML\Application.cs // X:\jsc.svn\examples\javascript\Test\TestIScreen\TestIScreen\Application.cs // X:\jsc.svn\examples\javascript\test\TestServiceWorkerVisualizedScreens\TestServiceWorkerVisualizedScreens\Application.cs // X:\jsc.svn\examples\javascript\Test\TestServiceWorkerScreens\TestServiceWorkerScreens\Application.cs // jsc, how do the templates work again, i forgot? //Native.tem //Native.shadow var desktop = new IHTMLDiv(); new IStyle(desktop) { backgroundColor = "black", // need to glue it position = IStyle.PositionEnum.absolute, top = "0px", right = "0px", bottom = "0px", left = "0px", // no scrollbars. thanks // how will this work for android multiscreeners? overflow = IStyle.OverflowEnum.hidden }; //__Form. //Native.shadow = desktop; desktop.AttachTo(Native.shadow); //Native.shadow // actully the offset and scale. // screen0 as background should be there as another element. var offsetandscale = new IHTMLDiv(); new IStyle(offsetandscale) { // the viewport info? //backgroundColor = "darkcyan", backgroundColor = "gray", // need to glue it position = IStyle.PositionEnum.absolute, // both screens should be able to fit here top = "100px", left = "100px", width = "600px", height = "600px", transformOrigin = "0% 0%", transform = "scale(0.3)" }; offsetandscale.AttachTo(desktop); var screen0 = new IHTMLDiv(); new IStyle(screen0) { // the viewport info? backgroundColor = "darkcyan", // need to glue it position = IStyle.PositionEnum.absolute, // both screens should be able to fit here top = "0px", left = "0px", width = "600px", height = "600px", }; screen0.AttachTo(offsetandscale); // why would it be a good idea to maximize? //new Form().AttachFormTo(desktop); //namespace ScriptCoreLib.JavaScript.Extensions // // where are they defined? //new Form().AttachControlTo(desktop); var data = new ClientData { identity = new Random().Next(), screen_width = Native.screen.width, screen_height = Native.screen.height, //Native.window.aspect, window_Width = Native.window.Width, window_Height = Native.window.Height, // where is this window on current screen? //(Native.window as dynamic).offsetLeft, //(Native.window as dynamic).offsetTop, window_screenLeft = (Native.window as dynamic).screenLeft, window_screenTop = (Native.window as dynamic).screenTop, // if we were to update, mutate this object, // how would we distribute the knowledge? // with sync events? }; var f = new Form { // frame0 Text = new { data.window_screenLeft, data.window_screenTop }.ToString(), Left = data.window_screenLeft, Top = data.window_screenTop }; f.GetHTMLTarget().AttachTo(offsetandscale); var fcontent = new IHTMLContent { select = "body" }; fcontent.AttachTo(f.GetHTMLTargetContainer()); f.Show(); #region Toggle Action Toggle = delegate { if (desktop.parentNode == null) { // show setup mode again Native.shadow.replaceChild( desktop, Native.shadow.firstChild ); } else { // remove the screen setup mode desktop.Orphanize(); new IHTMLContent { }.AttachTo(Native.shadow); } }; Native.document.onkeyup += e => { // US if (e.KeyCode == 222) { Toggle(); } // EE if (e.KeyCode == 192) { Toggle(); } }; #endregion var lookup = new Dictionary <int, Form> { { data.identity, f } }; new IHTMLPre { "lets tell the service, we have opened a new tab. " }.AttachToDocument(); #region postMessage Native.window.navigator.serviceWorker.controller.postMessage( data, // data updated o the other side. // lets decode. m => { var mdata = (ClientData)m.data; if (!lookup.ContainsKey(mdata.identity)) { var ff = new Form { Text = new { mdata.identity }.ToString() }; ff.GetHTMLTarget().AttachTo(offsetandscale); ff.Show(); ff.Opacity = 0.5; lookup[mdata.identity] = ff; } { var ff = lookup[mdata.identity]; ff.Left = mdata.window_screenLeft; ff.Top = mdata.window_screenTop; ff.Width = mdata.window_Width; ff.Height = mdata.window_Height; if (mdata.closed) { ff.Close(); } } } ); #endregion // keep it up to date #region onframe Native.window.onframe += delegate { if (data.closed) { return; } data.screen_width = Native.screen.width; data.screen_height = Native.screen.height; //Native.window.aspect, data.window_Width = Native.window.Width; data.window_Height = Native.window.Height; // where is this window on current screen? //(Native.window as dynamic).offsetLeft, //(Native.window as dynamic).offsetTop, data.window_screenLeft = (Native.window as dynamic).screenLeft; data.window_screenTop = (Native.window as dynamic).screenTop; // keep it in center offsetandscale.style.transform = "scale(" + ((data.window_Width * 0.5) / (data.screen_width + 200)) + ")"; offsetandscale.style.left = (data.window_Width / 2) + "px"; //offsetandscale.style.top = (Native.window.Height / 2) + "px"; // assume our monitors are side by side? offsetandscale.style.top = (data.window_Height / 4) + "px"; #region screen0 // what happens if we move to the other monitor? screen0.style.SetSize( data.screen_width, data.screen_height ); if (data.window_screenLeft < -(data.window_Width / 2)) { // assume we are on the other monitor to the left? // we do not know the actual offset until we go fullscreen. screen0.style.SetLocation( -data.screen_width, 0 ); } else { screen0.style.SetLocation( 0, 0 ); } #endregion //f.Text = new { data.window_screenLeft, data.window_screenTop }.ToString(); //f.Left = data.window_screenLeft; //f.Top = data.window_screenTop; //f.Width = data.window_Width; //f.Height = data.window_Height; // resend data Native.window.navigator.serviceWorker.controller.postMessage(data); }; #endregion Native.window.onbeforeunload += //Native.window.onunload += delegate { // move out of view to signify being closed? data.closed = true; // resend data Native.window.navigator.serviceWorker.controller.postMessage(data); }; }
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; //if (self_chrome_tabs == null) // return; // ....488: { SourceMethod = Void.ctor(ChromeExtensionHopToTabThenShadow.HTML.Pages.IApp), i = [0x00ba] brtrue.s + 0 - 1 } //1984:02:01 RewriteToAssembly error: System.ArgumentException: Value does not fall within the expected range. //at jsc.ILInstruction.ByOffset(Int32 i) in X:\jsc.internal.git\compiler\jsc\CodeModel\ILInstruction.cs:line 1184 //at jsc.ILInstruction.get_BranchTargets() in X:\jsc.internal.git\compiler\jsc\CodeModel\ILInstruction.cs:line 1225 #region self_chrome_tabs if (self_chrome_tabs != null) { Console.WriteLine("self_chrome_tabs"); chrome.tabs.Updated += async (i, x, tab) => { // chrome://newtab/ 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") return; //new chrome.Notification //{ // Message = "chrome.tabs.Updated " + new // { // tab.id, // tab.url, // tab.status, // tab.title // } //}; // while running tabs.insertCSS: The tab was closed. // public static Task<object> insertCSS(this TabIdInteger tabId, object details); // public static void insertCSS(this TabIdInteger tabId, object details, IFunction callback); // for some sites the bar wont show as they html element height is 0? await tab.id.insertCSS( new { code = @" html { border-left: 1em solid cyan; padding-left: 1em; } " } ); Console.WriteLine( "insertCSS done " + new { tab.id, tab.url } ); // 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; await (HopToChromeTab)tab; //await tab.id; // are we now on the tab? // can we jump back? // what about jumping with files/uploads? Console.WriteLine("// are we now on the tab yet?"); Native.body.style.borderLeft = "1em solid blue"; Native.document.documentElement.style.borderLeft = "1em solid blue"; // <div class="player-video-title">Ariana Grande - One Last Time (Official)</div> Native.document.title = "(" + Native.document.title + ")"; // this is a shadow application var pre = new IHTMLPre { "shadow application. repackage the ui. root html element still displays borders." }; // AttachToDocumentShadow // see jsc, we are proposing a convinience method pre.AttachTo( Native.document.documentElement.shadow ); var div = new IHTMLDiv { }.AttachTo(pre); new IStyle(div) { // time to tell where we want our content // css breaks? cannot use this scenario yet. without rewriting css position = IStyle.PositionEnum.@fixed, //position = IStyle.PositionEnum.absolute, top = "3em", left = "0.5em", right = "0.5em", bottom = "0.5em" }; var content = new IHTMLContent { // show only the body //select = "body" }.AttachTo(div); // 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\ChromeExtensionHopToTabThenShadow\ChromeExtensionHopToTabThenShadow\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 // we made the jump? Native.body.style.borderLeft = "1em 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 ChromeExtensionHopToTabThenShadow X:\jsc.svn\examples\javascript\chrome\extensions\ChromeExtensionHopToTabThenShadow\ChromeExtensionHopToTabThenShadow\Application.cs 272 // public static event System.Action<object, object, object> Message #region chrome.runtime.Message chrome.runtime.Message += (object message, chrome.MessageSender sender, IFunction sendResponse) => { var s = (TestSwitchToServiceContextAsync.ShadowIAsyncStateMachine)message; // 59ms onmessage {{ message = hello, id = aemlnmcokphbneegoefdckonejmknohh }} Console.WriteLine("xonmessage " + new { s.state, sender.id }); Native.body.style.borderLeft = "1px solid blue"; #region xAsyncStateMachineType var xAsyncStateMachineType = typeof(Application).Assembly.GetTypes().FirstOrDefault( item => { // safety check 1 //Console.WriteLine(new { sw.ElapsedMilliseconds, item.FullName }); var xisIAsyncStateMachine = typeof(IAsyncStateMachine).IsAssignableFrom(item); if (xisIAsyncStateMachine) { //Console.WriteLine(new { item.FullName, isIAsyncStateMachine }); return item.FullName == s.TypeName; } return false; } ); #endregion var NewStateMachine = FormatterServices.GetUninitializedObject(xAsyncStateMachineType); var isIAsyncStateMachine = NewStateMachine is IAsyncStateMachine; var NewStateMachineI = (IAsyncStateMachine)NewStateMachine; #region 1__state xAsyncStateMachineType.GetFields( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ).WithEach( AsyncStateMachineSourceField => { Console.WriteLine(new { AsyncStateMachineSourceField }); if (AsyncStateMachineSourceField.Name.EndsWith("1__state")) { AsyncStateMachineSourceField.SetValue( NewStateMachineI, s.state ); } } ); #endregion NewStateMachineI.MoveNext(); //Task.Delay(1000).ContinueWith( // delegate // { // sendResponse.apply(null, "response"); // } //); }; #endregion // Native.window.onmessage += e => //{ //}; }