public Application(IApp page) { // how does this worK? // run it to see what we have? // seems to work. but laptp is freezing up???? new forest5().With( async img => { await img; var st0 = new Stopwatch(); st0.Start(); var c0 = new CanvasRenderingContext2D( img.width, img.height ); c0.drawImage(img, 0, 0, img.width, img.height); var imageData = c0.getImageData(0, 0, img.width, img.height); var AnimatedColors = new List<int> { 0x3C4C8C, 0x2C407C, 0x2C3C84, 0x20306C }; #region f Func<int[], Task<CanvasRenderingContext2D>> f = AnimatedColorsTo => { var c1 = new CanvasRenderingContext2D( img.width, img.height ); var imageData1 = c1.getImageData(0, 0, img.width, img.height); // This loop gets every pixels on the image and for (var j = 0; j < imageData.width; j++) { for (var ji = 0; ji < imageData.height; ji++) { var index = (uint)((ji * 4) * imageData.width + (j * 4)); var red = imageData.data[index]; var green = imageData.data[index + 1]; var blue = imageData.data[index + 2]; var alpha = imageData.data[index + 3]; var average = (byte)((red + green + blue) / 3); var u8 = (red << 16) + (green << 8) + blue; var u8i = AnimatedColors.IndexOf(u8); if (u8i >= 0) { u8 = AnimatedColorsTo[u8i]; red = (byte)((u8 >> 16) & 0xff); green = (byte)((u8 >> 8) & 0xff); blue = (byte)((u8 >> 0) & 0xff); } else { alpha = 0x00; } // 3C4C8C // 2C407C // 20306C imageData1.data[index] = red; imageData1.data[index + 1] = green; imageData1.data[index + 2] = blue; //imageData.data[index + 1] = average; //imageData.data[index + 2] = average; imageData1.data[index + 3] = alpha; } } // overwrite original image c1.putImageData(imageData1, 0, 0, 0, 0, img.width, img.height); var xx = new TaskCompletionSource<CanvasRenderingContext2D>(); xx.SetResult(c1); return xx.Task; }; #endregion var st = new Stopwatch(); st.Start(); //{ ElapsedMilliseconds = 4795 } var a1 = new[]{ AnimatedColors[1], AnimatedColors[2], AnimatedColors[3], AnimatedColors[0], }; var o1 = f(a1).Result; var a2 = new[]{ AnimatedColors[2], AnimatedColors[3], AnimatedColors[0], AnimatedColors[1], }; var o2 = f(a2).Result; var a3 = new[]{ AnimatedColors[3], AnimatedColors[0], AnimatedColors[1], AnimatedColors[2], }; var o3 = f(a3).Result; Console.WriteLine(new { st.ElapsedMilliseconds }); c0.canvas.AttachToDocument().style.SetLocation(0, 0); o1.canvas.AttachToDocument().style.SetLocation(0, 0); o2.canvas.AttachToDocument().style.SetLocation(0, 0); o3.canvas.AttachToDocument().style.SetLocation(0, 0); new Timer( t => { if (t.Counter % AnimatedColors.Count == 0) { o1.canvas.Hide(); o2.canvas.Hide(); o3.canvas.Hide(); return; } if (t.Counter % AnimatedColors.Count == 1) { o1.canvas.Show(); o2.canvas.Hide(); o3.canvas.Hide(); return; } if (t.Counter % AnimatedColors.Count == 2) { o1.canvas.Hide(); o2.canvas.Show(); o3.canvas.Hide(); return; } if (t.Counter % AnimatedColors.Count == 3) { o1.canvas.Hide(); o2.canvas.Hide(); o3.canvas.Show(); return; } } ).StartInterval(1000 / 5); // { ElapsedMilliseconds = 1843 } Console.WriteLine("all: " + new { st.ElapsedMilliseconds }); } ); }
// dont we have our own encoder now?? // X:\jsc.svn\core\ScriptCoreLib\Shared\BCLImplementation\System\Tuple.cs //no implementation for System.Tuple b6efdcc2-6386-375e-84aa-6732b6518b3f //script: error JSC1000: No implementation found for this native method, please implement [static System.Tuple.Create(System.IProgress`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=ne //script: warning JSC1000: Did you reference ScriptCoreLib via IAssemblyReferenceToken? //script: error JSC1000: error at GIFEncoderWorker..ctor, // assembly: U:\jsgif.Application.exe // type: GIFEncoderWorker, jsgif.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null // offset: 0x0049 // method:Void .ctor(Int32, Int32, Int32, Int32, System.Collections.Generic.IEnumerable`1[System.Byte[]], System.Action`1[System.Int32]) //*** Compiler cannot continue... press enter to quit. // based on http://antimatter15.com/wp/2010/07/javascript-to-animated-gif/ //cript: error JSC1000: No implementation found for this native method, please implement [static System.Tuple.Create(System.IProgress`1[[System.Int32, //cript: warning JSC1000: Did you reference ScriptCoreLib via IAssemblyReferenceToken? //cript: error JSC1000: error at GIFEncoderWorker..ctor, //assembly: V:\jsgif.Application.exe //type: GIFEncoderWorker, jsgif.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null //offset: 0x0049 // method:Void .ctor(Int32, Int32, Int32, Int32, System.Collections.Generic.IEnumerable`1[System.Byte[]], System.Action`1[System.Int32]) //** Compiler cannot continue... press enter to quit. /// <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) { // https://bugzilla.mozilla.org/show_bug.cgi?id=709490 // http://stackoverflow.com/questions/7844886/using-webgl-from-inside-a-web-worker-is-it-possible-how const int x = 640; const int y = 480; // do we need automatic decomposer? var context = new CanvasRenderingContext2D(x, y); // needs to be in dom? no var canvas = context.canvas; context.fillStyle = "rgb(255,255,255)"; context.fillRect(0, 0, canvas.width, canvas.height); // rebuild redux? var my_gradient = context.createLinearGradient(0, 0, 16, 0); my_gradient.addColorStop(0, "blue"); my_gradient.addColorStop(1, "white"); //context.fillStyle = my_gradient; //"rgb(255,255,255)"; context.fillStyle = "rgb(255,255,255)"; context.fillRect(0, 0, 16, canvas.height); //GIF can't do transparent so do white Action yield = delegate { }; var r = new Random(); Func<byte> random = r.NextByte; //encoder.addFrame(context); // 4 : 3sec // 8 : 0.00:00:06 // 16 : 0.00:00:18 var frames = new List<byte[]>(); // whats the difference? should jsc switch to tyhe typed array yet? //var frames = new List<byte[]>(); for (int i = 0; i < 16; i++) { context.fillStyle = "rgb(" + random() + "," + random() + "," + random() + ")"; context.fillRect( random() / 4, random() / 4, 32 + random(), 32 + random() ); var data = context.getImageData().data; //Uint8Array // { data = [object Uint8ClampedArray] } Console.WriteLine(new { data }); frames.Add(data); } yield += delegate { }; new IHTMLButton { innerText = "encode!" }.AttachToDocument().WhenClicked( delegate { var e = new Stopwatch(); e.Start(); Console.WriteLine("new encoder"); var encoder = new GIFEncoder(); encoder.setSize(x, y); encoder.setRepeat(0); //auto-loop encoder.setDelay(1000 / 15); encoder.start(); foreach (var data in frames) { Console.WriteLine("addFrame"); encoder.addFrame((Uint8ClampedArray)(object)data, true); } Console.WriteLine("finish"); encoder.finish(); var bytes = Encoding.ASCII.GetBytes(encoder.stream().getData()); var src = "data:image/gif;base64," + Convert.ToBase64String(bytes); Console.WriteLine(e.Elapsed); new IHTMLImage { src = src }.AttachToDocument(); } ); new IHTMLButton { innerText = "encode via worker" }.AttachToDocument().WhenClicked( delegate { var e = new Stopwatch(); e.Start(); var w = new Worker( scope => { Console.WriteLine("new encoder"); var encoder = new GIFEncoder(); encoder.setSize(x, y); encoder.setRepeat(0); //auto-loop encoder.setDelay(1000 / 15); encoder.start(); scope.onmessage += ee => { dynamic xdata = ee.data; string message = xdata.message; //Console.WriteLine(new { message }); if (message == "addFrame") { Console.WriteLine("addFrame"); // http://stackoverflow.com/questions/8776751/web-worker-dealing-with-imagedata-working-with-firefox-but-not-chrome //byte[] data = xdata.data; Uint8ClampedArray data = xdata.data; //data[ // { data = [object Uint8ClampedArray] } //Console.WriteLine(new { data }); encoder.addFrame(data, true); } if (message == "finish") { Console.WriteLine("finish"); encoder.finish(); var bytes = Encoding.ASCII.GetBytes(encoder.stream().getData()); var src = "data:image/gif;base64," + Convert.ToBase64String(bytes); ee.ports.WithEach(port => port.postMessage(src)); } }; } ); foreach (var data in frames) { dynamic xdata = new object(); xdata.message = "addFrame"; xdata.data = data; // Error 4 Cannot convert lambda expression to type 'ScriptCoreLib.JavaScript.DOM.MessagePort[]' because it is not a delegate type X:\jsc.svn\examples\javascript\synergy\jsgif\jsgif\Application.cs 171 38 jsgif w.postMessage( (object)xdata, (MessageEvent ee) => { // ? Console.WriteLine("addFrame done"); } ); } w.postMessage( new { message = "finish" }, (MessageEvent ee) => { Console.WriteLine("finish done"); var src = (string)ee.data; Console.WriteLine(e.Elapsed); new IHTMLImage { src = src }.AttachToDocument(); w.terminate(); } ); //var bytes = Encoding.ASCII.GetBytes(encoder.stream().getData()); //var src = "data:image/gif;base64," + Convert.ToBase64String(bytes); //new IHTMLImage { src = src }.AttachToDocument(); } ); new IHTMLButton { innerText = "encode via GIFEncoderAsync. works!" }.AttachToDocument().WhenClicked( btn => { btn.disabled = true; var e = new Stopwatch(); e.Start(); var w = new GIFEncoderAsync( width: x, height: y, delay: 1000 / 10 ); //http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_meter var innerText = btn.innerText; btn.Clear(); dynamic meter = new IHTMLElement("meter").AttachTo(btn); meter.max = frames.Count; var value = 0; foreach (var data in frames) { w.addFrame((Uint8ClampedArray)(object)data, delegate { Console.WriteLine("addFrame done"); value++; meter.value = value; } ); } w.finish( src => { Console.WriteLine("finish done"); Console.WriteLine(e.Elapsed); new IHTMLImage { src = src }.AttachToDocument(); btn.innerText = innerText; btn.disabled = false; btn.title = new { e.Elapsed }.ToString(); } ); } ); new IHTMLButton { innerText = "encode via GIFEncoderWorker. crashes the system? why?" }.AttachToDocument().WhenClicked( async btn => { Console.WriteLine("encoding!"); btn.disabled = true; var e = new Stopwatch(); e.Start(); var src = await new GIFEncoderWorker( x, y, delay: 1000 / 10, frames: frames, AtFrame: index => { btn.innerText = new { index, frames.Count }.ToString(); } ); Console.WriteLine("done!"); Console.WriteLine(e.Elapsed); new IHTMLImage { src = src }.AttachToDocument(); btn.disabled = false; btn.title = new { e.Elapsed }.ToString(); } ); }
/// <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) { // https://github.com/tumblr/jumblr new Abstractatech.ConsoleFormPackage.Library.ConsoleForm() .InitializeConsoleFormWriter() .PopupInsteadOfClosing() .Show(); // new IHTMLIFrame { src = "http://www.whatsmyip.us/", //src = "http://whatsmyip.net/", frameBorder = "0", scrolling = "no", width = 400, height = 72 }.AttachToDocument().style.SetSize( 400, 72); new IHTMLBreak().AttachToDocument(); //new IHTMLButton { innerText = "swapCache" }.AttachToDocument().WhenClicked( // delegate // { // // Uncaught InvalidStateError: Failed to execute 'swapCache' on 'ApplicationCache': there is no newer application cache to swap to. // Native.window.applicationCache.swapCache(); // } //); @"Hello world".ToDocumentTitle(); // Send data from JavaScript to the server tier service.getNumberOfCameras( cameras => { Enumerable.Range(0, int.Parse(cameras)).Select(i => new { i }).WithEach( ii => { var i = ii.i; new IHTMLBreak().AttachToDocument(); #region show me stills new IHTMLButton { innerText = "show me stills " + new { i } }.AttachToDocument().onclick += delegate { service.WebMethod2( "" + i, value => { if (!value.StartsWith("data:")) { Console.WriteLine(value); return; } new IHTMLImage { src = value }.AttachToDocument(); } ); }; #endregion #region show me animation new IHTMLButton { innerText = "show me animation" }.AttachToDocument().onclick += delegate { var img = new IHTMLImage { }.AttachToDocument(); var data = new List<string>(); service.WebMethod2( "" + i, value => { if (!value.StartsWith("data:")) { Console.WriteLine(value); return; } data.Add(value); } ); new Timer( t => { if (data.Count == 0) return; img.src = data[t.Counter % data.Count]; } ).StartInterval(1000 / 15); }; #endregion #region show me animation async new IHTMLButton { innerText = "show me animation async" }.AttachToDocument().onclick += delegate { var img = new IHTMLImage { }.AttachToDocument(); var data = new List<string>(); service.async_WebMethod2( "" + i, value => { if (!value.StartsWith("data:")) { Console.WriteLine(value); return; } data.Add(value); } ); new Timer( t => { if (data.Count == 0) return; img.src = data[t.Counter % data.Count]; } ).StartInterval(1000 / 15); }; #endregion #region show me animation async and gif it new IHTMLButton { innerText = "gif it " + new { i } }.AttachToDocument().onclick += delegate { Console.WriteLine("working..."); new IHTMLBreak().AttachToDocument(); var img = new IHTMLImage { }.AttachToDocument(); var data = new List<string>(); var gifmaxframes = 60; #region Timer new Timer( t => { if (data.Count == 0) return; if (data.Count < gifmaxframes) { img.src = data.Last(); return; } img.src = data[t.Counter % data.Count]; } ).StartInterval(1000 / 15); #endregion var c0 = new CanvasRenderingContext2D(); // no scale! c0.canvas.width = 320; c0.canvas.height = 240; c0.canvas.style.SetSize(320, 240); var c1 = new CanvasRenderingContext2D(); // no scale! c1.canvas.width = 320; c1.canvas.height = 240; c1.canvas.style.SetSize(320, 240); //c0.canvas.AttachToDocument(); // http://stackoverflow.com/questions/1864756/web-workers-and-canvas service.async_WebMethod2( "" + i, value => { if (!value.StartsWith("data:")) { Console.WriteLine(value); return; } data.Add(value); if (data.Count == gifmaxframes) { // need webworker! #region gif var st = new Stopwatch(); st.Start(); var encoder1 = new GIFEncoderAsync( 320, 240 ); //encoder1.setRepeat(0); //auto-loop //encoder1.setDelay(1000 / 15); //encoder1.start(); var encoder2 = new GIFEncoderAsync( 320, 240 ); //encoder2.setRepeat(0); //auto-loop //encoder2.setDelay(1000 / 15); //encoder2.start(); #region frames Console.WriteLine("gif " + new { st.Elapsed }); for (int datai = 0; datai < data.Count; datai++) { Console.WriteLine("gif " + new { datai, st.Elapsed }); c1.drawImage(new IHTMLImage { src = data[datai] }, 0, 0, 320, 240); encoder2.addFrame(c1); c0.drawImage(new IHTMLImage { src = data[datai] }, 0, 0, 320, 240); #region grayscale var imageData = c0.getImageData(0, 0, 320, 240); // This loop gets every pixels on the image and for (var j = 0; j < imageData.width; j++) { for (var ji = 0; ji < imageData.height; ji++) { var index = (uint)((ji * 4) * imageData.width + (j * 4)); var red = imageData.data[index]; var green = imageData.data[index + 1]; var blue = imageData.data[index + 2]; var alpha = imageData.data[index + 3]; var average = (byte)((red + green + blue) / 3); imageData.data[index] = average; imageData.data[index + 1] = average; imageData.data[index + 2] = average; //imageData.data[index + 1] = average; //imageData.data[index + 2] = average; imageData.data[index + 3] = alpha; } } // overwrite original image c0.putImageData(imageData, 0, 0, 0, 0, 320, 240); #endregion encoder1.addFrame(c0); Console.WriteLine("gif done " + new { datai, st.Elapsed }); } encoder1.finish( src => { var image = new IHTMLImage(); image.src = src; image.style.SetSize(640, 480); Console.WriteLine("gif got src" + new { st.Elapsed }); image.AttachToDocument(); } ); encoder2.finish( src => { var image = new IHTMLImage(); image.src = src; image.style.SetSize(640, 480); Console.WriteLine("gif got src" + new { st.Elapsed }); image.AttachToDocument(); } ); #endregion #endregion } } ); }; #endregion } ); } ); new IHTMLBreak().AttachToDocument(); }
/// <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 ChromeTCPServer //dynamic self = Native.self; //dynamic self_chrome = self.chrome; //object self_chrome_socket = self_chrome.socket; //if (self_chrome_socket != null) //{ // //chrome.Notification.DefaultIconUrl = new HTML.Images.FromAssets.Preview().src; // chrome.Notification.DefaultTitle = "WebGLToAnimatedGIFExperiment"; // ChromeTCPServer.TheServerWithStyledForm.Invoke( // AppSource.Text // ); // return; //} //#endregion var ani6 = new WebGLEarthByBjorn.Application(null); ani6.canvas.AttachTo(page.e1); ani6.canvas.style.SetSize(96, 96); ani6.canvas.style.position = IStyle.PositionEnum.relative; var ani5 = new WebGLSVGAnonymous.Application(null); ani5.canvas.AttachTo(page.e1); // gif needs a bg? //ani4.canvas.style.backgroundColor = "yellow"; ani5.canvas.style.SetSize(96, 96); ani5.canvas.style.position = IStyle.PositionEnum.relative; var ani4 = new WebGLColladaExperiment.Application(null); ani4.canvas.AttachTo(page.e1); // gif needs a bg? //ani4.canvas.style.backgroundColor = "yellow"; ani4.canvas.style.SetSize(96, 96); ani4.canvas.style.position = IStyle.PositionEnum.relative; var ani3 = new WebGLTetrahedron.Application(); ani3.gl.canvas.AttachTo(page.e1); // : ScriptComponent var ani2 = new WebGLEscherDrosteEffect.Application(); ani2.gl.canvas.AttachTo(page.e1); var gl = new WebGLRenderingContext(alpha: false, preserveDrawingBuffer: true); // replace placeholder gl.canvas.id = page.canvas.id; page.canvas = gl.canvas; page.canvas.width = 96; page.canvas.height = 96; var s = new SpiralSurface(this); this.onsurface(gl); this.onresize(page.canvas.width, page.canvas.height); var st = new Stopwatch(); st.Start(); Native.window.onframe += delegate { s.ucolor_1 = (float)Math.Sin(st.ElapsedMilliseconds * 0.001) * 0.5f + 0.5f; this.onframe(); }; // jsc should link that js file once we reference it. for now its manual #region activate Action<IHTMLCanvas> activate = xcanvas => { var context = new { canvas = xcanvas }; context.canvas.style.border = "2px solid yellow"; context.canvas.style.cursor = IStyle.CursorEnum.pointer; context.canvas.onclick += delegate { var c0 = new CanvasRenderingContext2D(96, 96); c0.canvas.AttachToDocument(); var frames = new List<byte[]>(); // view-source:36524 //{ ToBase64String_while_timeout = 00:00:00.504, i = 911952, length = 1454096 } view-source:36524 //var framecount = 240; //var delay = 1000 / 60; var framecount = 16; var delay = 1000 / 15; new ScriptCoreLib.JavaScript.Runtime.Timer( async t => { if (t.Counter == framecount) { Console.WriteLine("GIFEncoderWorker!"); var src = await new GIFEncoderWorker( 96, 96, delay: delay, frames: frames ); Console.WriteLine("done!"); new IHTMLImage { src = src }.AttachToDocument(); return; } if (t.Counter >= framecount) { c0.bytes = frames[t.Counter % frames.Count]; return; } #region force redraw all s.ucolor_2 = t.Counter / 32.0f; // force redraw this.onframe(); #endregion if (!t.IsAlive) return; c0.drawImage(context.canvas, 0, 0, 96, 96); frames.Add(c0.getImageData().data); } ).StartInterval(1000 / 60); }; }; #endregion activate(gl.canvas); activate(ani2.gl.canvas); activate(ani3.gl.canvas); activate(ani4.canvas); activate(ani5.canvas); activate(ani6.canvas); }
// X:\jsc.svn\examples\javascript\Test\TestPackageAsApplication\TestPackageAsApplication\Application.cs /// <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) { Console.WriteLine("before"); { var c = new CanvasRenderingContext2D(256, 256); var bytes = new byte[256 * 256 * 4]; for (int x = 0; x < 256; x++) { for (int y = 0; y < 256; y++) { bytes[x * 4 + 0 + 256 * 4 * y] = (byte)x; bytes[x * 4 + 1 + 256 * 4 * y] = (byte)y; bytes[x * 4 + 2 + 256 * 4 * y] = 0xff; bytes[x * 4 + 3 + 256 * 4 * y] = 0xcf; } } var i = c.getImageData(); i.data.set(bytes, 0); c.putImageData(i, 0, 0, 0, 0, 256, 256); c.canvas.AttachToDocument(); } { var bytes = new byte[256 * 256 * 4]; for (int x = 0; x < 256; x++) { for (int y = 0; y < 256; y++) { bytes[x * 4 + 0 + 256 * 4 * y] = 0; bytes[x * 4 + 1 + 256 * 4 * y] = 0; bytes[x * 4 + 2 + 256 * 4 * y] = 0; // alpha? bytes[x * 4 + 3 + 256 * 4 * y] = (byte)x; } } // 1824 of 65536 // 0.02783203125 // 262144 var slider = new IHTMLInput { type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range, max = 256 * 256 }.AttachToDocument(); new IHTMLPre { () => new { bytes.Length, md5 = bytes.ToMD5Bytes().ToHexString(), slider.valueAsNumber, u4 = new [] { bytes[slider.valueAsNumber * 4 + 0], bytes[slider.valueAsNumber * 4 +1], bytes[slider.valueAsNumber * 4 +2], bytes[slider.valueAsNumber * 4 +3] }.ToHexString() } }.AttachToDocument(); var c = new CanvasRenderingContext2D(256, 256) { bytes = bytes }; c.canvas.AttachToDocument(); // https://code.google.com/p/chromium/issues/detail?id=312187 // save for disk saving // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement var csrc = c.canvas.toDataURL("image/png"); var csrci = new IHTMLImage { src = csrc }.AttachToDocument(); // do the reverse var z = new CanvasRenderingContext2D(256, 256); z.drawImage(csrci, 0, 0, 256, 256); z.canvas.AttachToDocument(); // whats the bytes? var zbytes = z.bytes; new IHTMLPre { () => new { zbytes.Length, md5 = zbytes.ToMD5Bytes().ToHexString() , slider.valueAsNumber, u4 = new [] { zbytes[slider.valueAsNumber * 4 + 0], zbytes[slider.valueAsNumber * 4 +1], zbytes[slider.valueAsNumber * 4 +2], zbytes[slider.valueAsNumber * 4 +3] }.ToHexString() } }.AttachToDocument(); // 00ff80cf vs 00ff7fcf } Console.WriteLine("after"); new IHTMLButton { "make me the link " + new { Native.document.location.protocol } }.AttachToDocument().WhenClicked( makelink => { makelink.disabled = true; #region PackageAsApplication Action<IHTMLScript, XElement, Action<string>> PackageAsApplication = (source0, xml, yield) => { new IXMLHttpRequest( ScriptCoreLib.Shared.HTTPMethodEnum.GET, source0.src, handler: (IXMLHttpRequest r) => { // store hash xml.Add(new XElement("link", new XAttribute("rel", "location"), new XAttribute("href", Native.Document.location.hash))); xml.Add( new XElement("script", "/* source */" ) ); var data = ""; Action later = delegate { data = data.Replace("/* source */", r.responseText); }; //Native.Document.getElementsByTagName("link").AsEnumerable().ToList().ForEach( xml.Elements("link").ToList().ForEach( (XElement link, Action next) => { #region style var rel = link.Attribute("rel"); if (rel.Value != "stylesheet") { next(); return; } var href = link.Attribute("href"); var placeholder = "/* " + href.Value + " */"; //page.DragHTM.innerText += " " + placeholder; xml.Add(new XElement("style", placeholder)); new IXMLHttpRequest(ScriptCoreLib.Shared.HTTPMethodEnum.GET, href.Value, rr => { later += delegate { data = data.Replace(placeholder, rr.responseText); }; Console.WriteLine("link Remove"); link.Remove(); next(); } ); #endregion } )( delegate { data = xml.ToString(); Console.WriteLine("data: " + data); later(); yield(data); } ); } ); }; #endregion // XMLHttpRequest cannot load file:///D:/view-source. Cross origin requests are only supported for HTTP. Console.WriteLine("before PackageAsApplication"); PackageAsApplication( // how would we know our current source location? new IHTMLScript { src = "view-source" }, XElement.Parse(AppSource.Text), async data => { Console.WriteLine("enter PackageAsApplication"); var bytes0 = Encoding.UTF8.GetBytes(data); var w0 = (int)Math.Ceiling(Math.Sqrt(bytes0.Length)); var padding0 = (w0 * w0) - bytes0.Length; // { Length = 2072331, padding0 = 1269 } new IHTMLPre { new { bytes0.Length, padding0 } }.AttachToDocument(); var bytes = Encoding.UTF8.GetBytes( data + Encoding.UTF8.GetString(new byte[padding0]) // too slow? //+ new string(' ', padding0) ); //var bytes = Encoding.ASCII.GetBytes(data); // { Length = 2019412 } // why wont intellisense work like excel, debugger // and tell me the anwser without running // the other option is to step in via F11 // Math.Sqrt(2019412) 1421.0601676213432 var w = (int)Math.Ceiling(Math.Sqrt(bytes.Length)); //{ Length = 2049266, w = 1432 } //{ Length = 8202496 } new IHTMLPre { new { bytes.Length, w, u8 = new [] { bytes[0 * 4 + 0], bytes[0 * 4 +1], bytes[0 * 4 +2], bytes[0 * 4 +3], bytes[1 * 4 + 0], bytes[1 * 4 +1], bytes[1 * 4 +2], bytes[1 * 4 +3] }.ToHexString() , md5 = bytes.ToMD5Bytes().ToHexString() } }.AttachToDocument(); // 77,828 bytes) var wbyteswatch = Stopwatch.StartNew(); // { Length = 2069090, w = 1439, u8 = 3c68746d6c3e0a20, md5 = 4fa4af629b63b267da4d4a142c9cb171 } // { Length = 2070721, md5 = 0186a2c2d01257cf4ba6a5524ec4743d, u8 = 3c68746d6c3e0a20 } #region encode var wbytes = await Task.Factory.StartNew( new { bytes, w }, scope => { // Native.Console.WriteLine += ? // { Length = 2053956, u4 = 3c68746d } Console.WriteLine( new { scope.bytes.Length, u4 = new[] { scope.bytes[0 * 4 + 0], scope.bytes[0 * 4 +1], scope.bytes[0 * 4 +2], scope.bytes[0 * 4 +3] }.ToHexString() } ); // Uncaught Error: InvalidOperationException: { MethodToken = dAAABv_a4OTKgLfLC20SaJA } function is not available at { href = var ww = scope.w; var wwbytes = new byte[ww * ww * 4]; var wi = 0; for (int i = 0; i < wwbytes.Length; i += 4) { //bytes[x * 4 + 0 + 256 * 4 * y] = 0; //bytes[x * 4 + 1 + 256 * 4 * y] = 0; //bytes[x * 4 + 2 + 256 * 4 * y] = 0; // can we get a red picture? // unless we alpha everything out! // 692 KB! //wwbytes[i + 0] = (byte)(0xff); wwbytes[i + 0] = 0; wwbytes[i + 1] = 0; wwbytes[i + 2] = 0; // alpha wwbytes[i + 3] = // the bytes histogram seems // to be in the middle? scope.bytes[wi]; // reverse alpha? //(byte)(255 - scope.bytes[wi]); //(byte)~scope.bytes[wi]; wi++; } return wwbytes; } ); #endregion //{ Length = 2071072, w = 1440, u4 = 3c68746d, md5 = 5c45e67b07d9045882dfe305e9bf23fd } //{ Length = 8294400, ElapsedMilliseconds = 9971, u8 = ff00003cff00003c } new IHTMLPre { new { wbytes.Length, wbyteswatch.ElapsedMilliseconds, u8 = new [] { wbytes[0 * 4 + 0], wbytes[0 * 4 +1], wbytes[0 * 4 +2], wbytes[0 * 4 +3], wbytes[1 * 4 + 0], wbytes[1 * 4 +1], wbytes[1 * 4 +2], wbytes[1 * 4 +3] }.ToHexString() } }.AttachToDocument(); new IHTMLPre { new { wbytes.Length, wbyteswatch.ElapsedMilliseconds, md5 = wbytes.ToMD5Bytes().ToHexString() } }.AttachToDocument(); // { Length = 8236900, ElapsedMilliseconds = 2476, md5 = 166c1b692fad548789a12a3ae5f0a7ae } var c = new CanvasRenderingContext2D(w, w) { bytes = wbytes }; // this would touch our precious alpha channel! //c.fillText( // "rgb channel for preview, while alpha channel has the data of " // + new { bytes.Length }, // 64, 64, c.canvas.width // ); c.canvas.style.backgroundColor = "yellow"; c.canvas.style.border = "1px solid red"; c.canvas.AttachToDocument(); // https://code.google.com/p/chromium/issues/detail?id=312187 // save for disk saving // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement var csrc = c.canvas.toDataURL("image/png"); // this wont help at all // https://bugzilla.mozilla.org/show_bug.cgi?id=676619 var csrca = new IHTMLAnchor { download = "view-source.png", href = csrc, title = "view-source", innerText = "do not drag, click to download view-source.png" }.AttachToDocument(); // http://caniuse.com/download var csrci = new IHTMLImage { src = csrc }.AttachToDocument(); csrci.style.backgroundColor = "yellow"; csrci.style.border = "1px solid red"; // um. time to reverse? // do the reverse var z = new CanvasRenderingContext2D(w, w); z.drawImage(csrci, 0, 0, w, w); z.canvas.AttachToDocument(); // whats the bytes? var zbytes = z.bytes; new IHTMLPre { new { zbytes.Length, md5 = zbytes.ToMD5Bytes().ToHexString() , u8 = new [] { zbytes[0 * 4 + 0], zbytes[0 * 4 +1], zbytes[0 * 4 +2], zbytes[0 * 4 +3], zbytes[1 * 4 + 0], zbytes[1 * 4 +1], zbytes[1 * 4 +2], zbytes[1 * 4 +3] }.ToHexString() } }.AttachToDocument(); // { Length = 8236900, md5 = 166c1b692fad548789a12a3ae5f0a7ae, u4 = 0000003c } #region decode var decodebytes = await Task.Factory.StartNew( new { zbytes }, scope => { // Native.Console.WriteLine += ? // { Length = 2053956, u4 = 3c68746d } Console.WriteLine( new { scope.zbytes.Length, u4 = new[] { scope.zbytes[0 * 4 + 0], scope.zbytes[0 * 4 +1], scope.zbytes[0 * 4 +2], scope.zbytes[0 * 4 +3] }.ToHexString() } ); // Uncaught Error: InvalidOperationException: { MethodToken = dAAABv_a4OTKgLfLC20SaJA } function is not available at { href = var wwbytes = new byte[scope.zbytes.Length / 4]; var wi = 0; for (int i = 0; i < scope.zbytes.Length; i += 4) { // that be the red //wwbytes[wi] = scope.zbytes[i]; // bet we need alpha wwbytes[wi] = scope.zbytes[i + 3]; wi++; } return wwbytes; } ); #endregion //{ Length = 8282884, md5 = ece6f7e935f0b424082445b273b8ed65, u4 = ff00003c } //{ Length = 2070721, md5 = 47f7ec04a0b7cfc27e706583cc1a9bf7, u4 = 3c3c3c3c } new IHTMLPre { new { decodebytes.Length, md5 = decodebytes.ToMD5Bytes().ToHexString() , u8 = new [] { decodebytes[0 * 4 + 0], decodebytes[0 * 4 +1], decodebytes[0 * 4 +2], decodebytes[0 * 4 +3], decodebytes[1 * 4 + 0], decodebytes[1 * 4 +1], decodebytes[1 * 4 +2], decodebytes[1 * 4 +3] }.ToHexString() } }.AttachToDocument(); } ); } ); }