ant - Dave's Blog

Search
My timeline on Mastodon

Right-To-Left Override Twitter Name

2020 Oct 21, 3:50

Its rare to find devs anticipating Unicode control characters showing up in user input. And the most fun when unanticipated is the Right-To-Left Override character U+202E. Unicode characters have an implicit direction so that for example by default Hebrew characters are rendered from right to left, and English characters are rendered left to right. The override characters force an explicit direction for all the text that follows.

I chose my Twitter display name to include the HTML encoding of the Right-To-Left Override character #x202E; as a sort of joke or shout out to my favorite Unicode control character. I did not anticipate that some Twitter clients in some of their UI would fail to encode it correctly. There's no way I can remove that from my display name now.


Try it on Amazon.


How about pages that want to tell you about the U+202E. 


PermalinkCommentsUnicode

Scrollbars in EdgeHtml WebView and Edge browser

2019 Aug 22, 5:35

The scrollbars in UWP WebView and in Edge have different default behavior leading to many emails to my team. (Everything I talk about here is for the EdgeHtml based WebView and Edge browser and does not apply to the Chromium based Edge browser and WebView2).

There is a Edge only -ms-overflow-style CSS property that controls scroll behavior. We have a different default for this in the WebView as compared to the Edge browser. If you want the appearance of the scrollbar in the WebView to match the browser then you must explicitly set that CSS property. The Edge browser default is scrollbar which gives us a Windows desktop styled non-auto-hiding scrollbar. The WebView default is -ms-autohiding-scrollbar which gives a sort of compromise between desktop and UWP app scrollbar behavior. In this configuration it is auto-hiding. When used with the mouse you'll get Windows desktop styled scrollbars and when used with touch you'll get the UWP styled scrollbars.

Since WebViews are intended to be used in apps this style is the default in order to better match the app's scrollbars. However this difference between the browser and WebView has led to confusion.

Here’s an -ms-overflow-style JSFiddle showing the difference between the two styles. Try it in the Edge browser and in WebView. An easy way to try it in the Edge WebView is using the JavaScript Browser.

PermalinkComments

Changing the User Agent string in UWP WebView

2018 Oct 23, 9:32

There's no perfect way to change the user agent string for the UWP WebView (x-ms-webview in HTML, Windows.UI.Xaml.Controls.WebView in XAML, and Windows.Web.UI.Interop.WebViewControl in Win32) but there are two imperfect methods folks end up using.

The first is to call UrlMkSetSessionOption. This is an old public API that allows you to configure various arcane options including one that is the default user agent string for requests running through urlmon. This API is allowed by the Microsoft Store for UWP apps. The change it applies is process wide which has two potential drawbacks. If you want to be able to have different UA strings set for different requests from a WebView that's not really possible with this solution. The other drawback is if you're using out of process WebView, you need to ensure you're calling into UrlMkSetSessionOption in the WebView's process. You'll need to write third party WinRT that calls UrlMkSetSessionOption, create the out of proc WebView, navigate it to some trusted local page, use AddWebAllowedObject or provide that URI WinRT access, and call into your third party WinRT. You'll need to do that for any new WebView process you create.

The second less generally applicable solution is to use NavigateWithHttpRequestMessage and set the User-Agent HTTP header. In this case you get to control the scope of the user agent string changes but has the limitations that not all sub resource downloads will use this user agent string and for navigations you don't initiate you have to manually intercept and re-request being careful to transfer over all POST body state and HTTP headers correctly. That last part is not actually possible for iframes.

PermalinkCommentsuser-agent uwp webview

GoBack/GoForward in Win10 UWP WebView

2018 Oct 23, 9:18

The GoBack and GoForward methods on the UWP WebView (x-ms-webview in HTML, Windows.UI.Xaml.Controls.WebView in XAML, and Windows.Web.UI.Interop.WebViewControl in Win32) act the same as the Back and Forward buttons in the Edge browser. They don't necessarily change the top level document of the WebView. If inside the webview an iframe navigates then that navigation will be recorded in the forward/back history and the GoBack / GoForward call may result in navigating that iframe. This makes sense as an end user using the Edge browser since if I click a link to navigate one place and then hit Back I expect to sort of undo that most recent navigation regardless of if that navigation happened in an iframe or the top level document.

If that doesn't make sense for your application and you want to navigate forward or back ignoring iframe navigates, unfortunately there's no perfect workaround.

One workaround could be to try calling GoBack and then checking if a FrameNavigationStarting event fires or a NavigationStarting event fires. If a frame navigates then try calling GoBack again. There could be async races in this case since other navigates could come in and send you the wrong signal and interrupt your multi step GoBack operation.

You could also try keeping track of all top level document navigations and manually navigate back to the URIs you care about. However, GoBack and GoForward also restore some amount of user state (form fills etc) in addition to navigating. Manually calling navigate will not give this same behavior.

PermalinkCommentsuri uwp webview

MSApp.getHtmlPrintDocumentSourceAsync - JavaScript UWP app printing

2017 Oct 11, 5:49

The documentation for printing in JavaScript UWP apps is out of date as it all references MSApp.getHtmlPrintDocumentSource but that method has been replaced by MSApp.getHtmlPrintDocumentSourceAsync since WinPhone 8.1.

Background

Previous to WinPhone 8.1 the WebView's HTML content ran on the UI thread of the app. This is troublesome for rendering arbitrary web content since in the extreme case the JavaScript of some arbitrary web page might just sit in a loop and never return control to your app's UI. With WinPhone 8.1 we added off thread WebView in which the WebView runs HTML content on a separate UI thread.

Off thread WebView required changing our MSApp.getHtmlPrintDocumentSource API which could no longer synchronously produce an HtmlPrintDocumentSource. With WebViews running on their own threads it may take some time for them to generate their print content for the HtmlPrintDocumentSource and we don't want to hang the app's UI thread in the interim. So the MSApp.getHtmlPrintDocumentSource API was replaced with MSApp.getHtmlPrintDocumentSourceAsync which returns a promise the resolved value of which is the eventual HtmlPrintDocumentSource.

Sample

However, the usage of the API is otherwise unchanged. So in sample code you see referencing MSApp.getHtmlPrintDocumentSource the sample code is still reasonable but you need to call MSApp.getHtmlPrintDocumentSourceAsync instead and wait for the promise to complete. For example the PrintManager docs has an example implementing a PrintTaskRequested event handler in a JavaScript UWP app.

    function onPrintTaskRequested(printEvent) {    
var printTask = printEvent.request.createPrintTask("Print Sample", function (args) {
args.setSource(MSApp.getHtmlPrintDocumentSource(document));
});

Instead we need to obtain a deferral in the event handler so we can asynchronously wait for getHtmlPrintDocumentSourceAsync to complete:

    function onPrintTaskRequested(printEvent) {    
var printTask = printEvent.request.createPrintTask("Print Sample", function (args) {
const deferral = args.getDeferral();
MSApp.getHtmlPrintDocumentSourceAsync(document).then(htmlPrintDocumentSource => {
args.setSource(htmlPrintDocumentSource);
deferral.complete();
}, error => {
console.error("Error: " + error.message + " " + error.stack);
deferral.complete();
});
});
PermalinkCommentsjavascript MSApp printing programming uwp webview win10 windows

Tweet from Seth Abramson

2017 Jan 22, 5:21
Retweet if you want networks to stop booking Kellyanne Conway, the first U.S. presidential counselor to openly advocate lying to the public.
PermalinkComments

Tweet from David Risney

2016 Dec 7, 2:19
I'm going to pretend that The Circle is a sequel to Antitrust http://kottke.org/16/12/trailer-for-the-circle 
PermalinkComments

Tweet from The Atlantic

2016 Nov 28, 10:07
The lasting damage done by Tump's 'voter fraud' allegations: http://theatln.tc/2gczqDz 
PermalinkComments

Tweet from David Risney

2016 Nov 18, 4:11
@PA_Megacorp I read the title as Couchomancy and imagined a necromancer that summons couches. No one steal my new YA fantasy novel idea pls
PermalinkComments

Tweet from Chris Heilmann

2016 Nov 2, 4:57
The static on TV is referred to as “hangyafoci” by Hungarians, which translates to “ant soccer” https://en.wikipedia.org/wiki/Noise_(video) 
PermalinkComments

Tweet from David Risney

2016 Oct 11, 5:52
@David_Risney But OTOH he also demonstrated viability of explicitly racist populism - just avoid the misogyny - for future misanthropes
PermalinkComments

Tweet from David Risney

2016 Sep 8, 11:31
@thejohnjansen @k_seks or in the case of hotdog & sandwich, casual communication vs pedantic contrarianism
PermalinkComments

Tweet from David Risney

2016 Aug 30, 1:46
Turning up @Kevecca's plug them on latest comedy bang bang http://www.earwolf.com/episode/atlantis-dire-warning/ 
PermalinkComments

Tweet from Patrick Claybon

2016 Aug 21, 1:53
Gonna open a restaurant that serves food 4 hrs after cooking to 20% of customers and then blame them for not eating
PermalinkComments

Data breakpoints in JavaScript

2016 Jun 17, 5:44

The other day I had to debug a JavaScript UWA that was failing when trying to use an undefined property. In a previous OS build this code would run and the property was defined. I wanted something similar to windbg/cdb's ba command that lets me set a breakpoint on read or writes to a memory location so I could see what was creating the object in the previous OS build and what that code was doing now in the current OS build. I couldn't find such a breakpoint mechanism in Visual Studio or F12 so I wrote a little script to approximate JavaScript data breakpoints.

The script creates a stub object with a getter and setter. It actually performs the get or set but also calls debugger; to break in the debugger. In order to handle my case of needing to break when window.object1.object2 was created or accessed, I further had it recursively set up such stub objects for the matching property names.

Its not perfect because it is an enumerable property and shows up in hasOwnProperty and likely other places. But for your average code that checks for the existence of a property via if (object.property) it works well.

PermalinkCommentsdebug debugging javascript

WinRT Toast from PowerShell

2016 Jun 15, 3:54

I've made a PowerShell script to show system toast notifications with WinRT and PowerShell. Along the way I learned several interesting things.

First off calling WinRT from PowerShell involves a strange syntax. If you want to use a class you write [-Class-,-Namespace-,ContentType=WindowsRuntime] first to tell PowerShell about the type. For example here I create a ToastNotification object:

[void][Windows.UI.Notifications.ToastNotification,Windows.UI.Notifications,ContentType=WindowsRuntime];
$toast = New-Object Windows.UI.Notifications.ToastNotification -ArgumentList $xml;
And here I call the static method CreateToastNotifier on the ToastNotificationManager class:
[void][Windows.UI.Notifications.ToastNotificationManager,Windows.UI.Notifications,ContentType=WindowsRuntime];
$notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppUserModelId);
With this I can call WinRT methods and this is enough to show a toast but to handle the click requires a little more work.

To handle the user clicking on the toast I need to listen to the Activated event on the Toast object. However Register-ObjectEvent doesn't handle WinRT events. To work around this I created a .NET event wrapper class to turn the WinRT event into a .NET event that Register-ObjectEvent can handle. This is based on Keith Hill's blog post on calling WinRT async methods in PowerShell. With the event wrapper class I can run the following to subscribe to the event:

function WrapToastEvent {
param($target, $eventName);

Add-Type -Path (Join-Path $myPath "PoshWinRT.dll")
$wrapper = new-object "PoshWinRT.EventWrapper[Windows.UI.Notifications.ToastNotification,System.Object]";
$wrapper.Register($target, $eventName);
}

[void](Register-ObjectEvent -InputObject (WrapToastEvent $toast "Activated") -EventName FireEvent -Action {
...
});

To handle the Activated event I want to put focus back on the PowerShell window that created the toast. To do this I need to call the Win32 function SetForegroundWindow. Doing so from PowerShell is surprisingly easy. First you must tell PowerShell about the function:

Add-Type @"
using System;
using System.Runtime.InteropServices;
public class PInvoke {
[DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hwnd);
}
"@
Then to call:
[PInvoke]::SetForegroundWindow((Get-Process -id $myWindowPid).MainWindowHandle);

But figuring out the HWND to give to SetForegroundWindow isn't totally straight forward. Get-Process exposes a MainWindowHandle property but if you start a cmd.exe prompt and then run PowerShell inside of that, the PowerShell process has 0 for its MainWindowHandle property. We must follow up process parents until we find one with a MainWindowHandle:

$myWindowPid = $pid;
while ($myWindowPid -gt 0 -and (Get-Process -id $myWindowPid).MainWindowHandle -eq 0) {
$myWindowPid = (gwmi Win32_Process -filter "processid = $($myWindowPid)" | select ParentProcessId).ParentProcessId;
}
PermalinkComments.net c# powershell toast winrt

Tweet from David Risney

2016 Jun 9, 3:48
Is this how we find out who Trump wants as his VP? https://twitter.com/7im/status/740670716870156288 
PermalinkComments

Tweet from David Risney

2016 Jun 9, 3:26
Trying to avoid regulation? Put a gun on it. You can't regulate that! http://arstechnica.com/tech-policy/2016/06/man-who-built-gun-drone-flamethrower-drone-argues-faa-cant-regulate-him/ 
PermalinkComments

Tweet from David Risney

2016 Jun 2, 4:40
Answering the important questions: Tab v Spaces https://ukupat.github.io/tabs-or-spaces/  Broken down by programming language & using GitHub as population
PermalinkComments

Tweet from David Risney

2016 Apr 28, 7:21
Wired's pay readers get https: http://www.niemanlab.org/2016/04/wireds-making-the-long-and-slow-switch-to-https-and-it-wants-to-help-other-news-sites-do-the-same/  Sounds like you're paying for https but really its lack of ads makes https practical
PermalinkComments
Older Entries Creative Commons License Some rights reserved.