play - Dave's Blog


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. 


Tiny browser features: JSBrowser zoom

2018 May 10, 3:49

JSBrowser is a basic browser built as a Win10 JavaScript UWP app around the WebView HTML element. Its fun and relatively simple to implement tiny browser features in JavaScript and in this post I'm implementing zoom.

My plan to implement zoom is to add a zoom slider to the settings div that controls the scale of the WebView element via CSS transform. My resulting zoom change is in git and you can try the whole thing out in my JSBrowser fork.


I can implement the zoom settings slider as a range type input HTML element. This conveniently provides me a min, max, and step property and suits exactly my purposes. I chose some values that I thought would be reasonable so the browser can scale between half to 3x by increments of one quarter. This is a tiny browser feature after all so there's no custom zoom entry.

<a><label for="webviewZoom">Zoom</label><input type="range" min="50" max="300" step="25" value="100" id="webviewZoom" /></a>

To let the user know this slider is for controlling zoom, I make a label HTML element that says Zoom. The label HTML element has a for attribute which takes the id of another HTML element. This lets the browser know what the label is labelling and lets the browser do things like when the label is clicked to put focus on the slider.


There are no explicit scale APIs for WebView so to change the size of the content in the WebView we use CSS.

        this.applyWebviewZoom = state => {
const minValue = this.webviewZoom.getAttribute("min");
const maxValue = this.webviewZoom.getAttribute("max");
const scaleValue = Math.max(Math.min(parseInt(this.webviewZoom.value, 10), maxValue), minValue) / 100;

// Use setAttribute so they all change together to avoid weird visual glitches
this.webview.setAttribute("style", [
["width", (100 / scaleValue) + "%"],
["height", "calc(" + (-40 / scaleValue) + "px + " + (100 / scaleValue) + "%)"],
["transform", "scale(" + scaleValue + ")"]
].map(pair => pair[0] + ": " + pair[1]).join("; "));

Because the user changes the scale at runtime I accordingly replace the static CSS for the WebView element with the script above to programmatically modify the style of the WebView. I change the style with one setAttribute call to do my best to avoid the browser performing unnecessary work or displaying the WebView in an intermediate and incomplete state. Applying the scale to the element is as simple as adding 'transform: scale(X)' but then there are two interesting problems.

The first is that the size of the WebView is also scaled not just the content within it. To keep the WebView the same effective size so that it still fits properly into our browser UI, we must compensate for the scale in the WebView width and height. Accordingly, you can see that we scale up by scaleValue and then in width and height we divide by the scaleValue.

transform-origin: 0% 0%;

The other issue is that by default the scale transform's origin is the center of the WebView element. This means when scaled up all sides of the WebView would expand out. But when modifying the width and height those apply relative to the upper left of the element so our inverse scale application to the width and height above aren't quite enough. We also have to change the origin of the scale transform to match the origin of the changes to the width and height.

PermalinkCommentsbrowser css-transform javascript JS jsbrowser uwp webview win10

Multiple Windows in Win10 JavaScript UWP apps

2018 Mar 10, 1:47

Win10 Changes

In Win8.1 JavaScript UWP apps we supported multiple windows using MSApp DOM APIs. In Win10 we use and window and a new MSApp API getViewId and the previous MSApp APIs are gone:

Win10 Win8.1
Create new window MSApp.createNewView
New window object window MSAppView
viewId MSApp.getViewId(window) MSAppView.viewId

WinRT viewId

We use and window for creating new windows, but then to interact with WinRT APIs we add the MSApp.getViewId API. It takes a window object as a parameter and returns a viewId number that can be used with the various Windows.UI.ViewManagement.ApplicationViewSwitcher APIs.

Delaying Visibility

Views in WinRT normally start hidden and the end developer uses something like TryShowAsStandaloneAsync to display the view once it is fully prepared. In the web world, shows a window immediately and the end user can watch as content is loaded and rendered. To have your new windows act like views in WinRT and not display immediately we have added a option. For example
let newWindow ="", null, "msHideView=yes");

Primary Window Differences

The primary window that is initially opened by the OS acts differently than the secondary windows that it opens:

Primary Secondary Allowed Disallowed
window.close Close app Close window
Navigation restrictions ACUR only No restrictions

The restriction on secondary windows such that they cannot open secondary windows could change in the future depending on feedback.

Same Origin Communication Restrictions

Lastly, there is a very difficult technical issue preventing us from properly supporting synchronous, same-origin, cross-window, script calls. That is, when you open a window that's same origin, script in one window is allowed to directly call functions in the other window and some of these calls will fail. postMessage calls work just fine and is the recommended way to do things if that's possible for you. Otherwise we continue to work on improving this.


Tweet from David Risney

2017 Jan 19, 12:51
Playing The Witness again after seeing an area I hadn't visited in the Xbox trailer. Listening to a lot of Hall of the Mountain King now...

Tweet from David Risney

2016 Dec 4, 3:47
Astounding realization during Westworld finale: My wife doesn't care that I can identify all the Radiohead cover titles played on Westworld.

Tweet from David Risney

2016 Sep 19, 3:04
Playing No Man's Sky collecting resources on an hospitable planet and suddenly notice several creatures approaching. I quickly scan them.

Tweet from David Risney

2016 Jun 5, 4:10
I played Chrome, Edge, FF & IE against each other in WebDriverChess. Edge just beats out Firefox for #1. Results: 

Tweet from David Risney

2016 Jun 5, 3:55
I finished WebDriverChess : Two webdriver supporting browsers play a friendly game of chess.

Tweet from Eric Lawrence

2016 Jun 2, 10:32
Chrome relaxes IDN display of Punycode (old restrictions were like IE) to match Firefox instead: 

Tweet from Ryan Estrada

2016 Apr 25, 7:05
The mayor of podcasts himself @PFTompkins plays Greg in  and tries to save the internet!

Retweet of doctorow

2016 Feb 8, 5:08
A digital, 3D printed sundial whose precise holes cast a shadow displaying the current time …

Retweet of Real_CSS_Tricks

2016 Jan 30, 8:30
display: contents;It's new. …parent (disp flex) child (disp contents) grandchildgrandchild now flex item

Retweet of FakeUnicode

2016 Jan 24, 10:52
.@alolita How Ancient Egypt fell. "But great Pharaoh, we need a snake playing croquet." "You have like 50 snake symbols." "But, croquet!"

Unicode Clock

2016 Jan 24, 2:00

I've made a Unicode Clock in JavaScript.

Unicode has code points for all 30 minute increments of clock faces. This is a simple project to display the one closest to the current time written in JavaScript.

Because the code points are all above 0xFFFF, I make use of some ES6 additions. I use the \u{XXXXXX} style escape sequence since the old style JavaScript escape sequence \uXXXX only supports code points up to 0xFFFF. I also use the method String.codePointAt rather than String.charCodeAt because the code points larger than 0xFFFF are represented in JavaScript strings using surrogate pairs and charCodeAt gives the surrogate value rather than codePointAt which gives the code point represented by the pair of surrogates.



The ordering of the code points does not make it simple to do this. I initially guessed the first code point in the range would be 12:00 followed by 12:30, 1:00 and so on. But actually 1:00 is first followed by all the on the hour times then all the half hour times.

PermalinkCommentsjavascript Unicode

Tweet from David_Risney

2015 Dec 24, 5:53
Playing Guess Who with 4yo. First turn after explaining rules: "Daddy did you pick the birthday cake, like I did?"

Retweet of blubbfiction

2015 Dec 12, 6:22
Replay attacks against HTTPS - …

Retweet of moody

2015 Nov 19, 8:36
The @USNatArchives just announced it is displaying The Refugee Act in its rotunda today. …

Retweet of SwiftOnSecurity

2015 Nov 15, 11:34
@snowden please stop teaching terrorists how to encrypt their communications with PlayStation 4

Retweet of FTC

2015 Nov 4, 6:03
Our #StartWithSecurity workshop starts now. Watch live: … Agenda: …

laughingsquid: ‘Everything Is a Remix’ Celebrates Its Five-Year...

2015 Sep 17, 3:05


‘Everything Is a Remix’ Celebrates Its Five-Year Anniversary With a Remastered Release and New Merchandise

Older Entries Creative Commons License Some rights reserved.