DOM Exception 22 - Quota Exceeded on Safari Private Browsing with localStorage

ERROR: QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota.”

Safari in Private Browsing on iOS and OSX

So apparently Apple didn’t want to (or for undisclosed technical reasons couldn’t) support the WebStorage standard (known as localStorage and sessionStorage) in Private Browsing mode.

EDIT 2017-10-17: Alexander points out in the comments below that Apple fixed this, and that it should ship in iOS 11

3 Things I Learned This Week 2016-06-03

node-notifier: cross platform pop up notifications for node.js

I had a little node script that would warm up a server by hitting a bunch of URLS and wanted it to send a notification when it finished. I found node-notifier that makes it easy to add this. And it’s even cross-platform!

const notifier = require("node-notifier");
notifier.notify({
        title: "Warmup complete!",
        message: "You should be able to use the site now.",
        sound: true
});

Webforms with multiple submits

So in Webforms there is a single HTML form element for the whole page. The downside of this is that if you have multiple inputs with submit buttons on your page, for example a search box in the top and a log-in form in the middle, you will get surprising behavior when you press the Enter key.

HTML treats an Enter press as a click to the first submit button on the page, which may not be what the user expected. For example, if you press enter after typing your password it would send a click against the search button, since that came first in the markup.

Luckily you can wrap each user input area in a panel with the and set the DefaultButton property with the ID of the expected button.

THat renders a mess of inline javascript (because of course it does). This will make your FE team cry, but you’re using webforms so perfect markup is obviously not that high on your priority list.

Kentico CacheDependencies

When using the CacheHelper class you can define a cache dependency. These are magic strings that indicate what changes in the system should invalidate the cached object. For example if you were caching a list of instances of a custom Page Type, you might use the cache dependency to tell the system to drop the cache if there are any changes to that Page Type.

Cloud Savings: Bundle Up Your Databases

I run a few different side projects or demo sites in Azure. Each site generally costs about $15/month to host. Thats about $10 for the Shared Azure Website (D1) and about $5 for the smallest Basic Azure SQL Database (B).

I wanted to get that price down a bit more. There’s not much I can do about the $10 per website (App-Service as its called these days). If I want a custom domain, and not *.azurewebsites.net, the D1 is the cheapest option. After I get up to about 7 or 8 sites, it then makes sense to switch to the Standard service tier (S1), where I can cram all the sites into a single underlying VM for about $72/month. For each new site after that, the cost per-site is less than the shared D1 plan.

The databases are a different story: they are priced per database and have different tiers for various performance needs. I don’t need performance, and the Basic (B) tier is plenty for my hobby projects.

But I’d like to not have to spend $5/month for each hobby project.

Luckily with some creative coding I was able to cram multiple site’s data into the same B database. The trick is to use SQL Server Schemas.

New Directions for Nerdery Overnight Website Challenge

Over at the Nerdery Blog, Mike Durheim posted about new directions for the Overnight Website Challenge. For those that don’t know, the OWC is an annual event put on by the Nerdery where teams of web developers from inside and outside the company come together to donate their time towards helping a non-profit build a new website in just 24 hours. I’ve participated in the past and had an excellent time helping out a non-profit here in KC.

Blog List

Below are some of the blogs I read regulary through my feed reader. They’re sorted by category and then roughly by popularity. This doesnt have everything, but I think its a good start.

Kentico Layout Webpart Without The Chaos

In Kentico, a Layout Webpart (or Layout Widget) is a component you can drop into a WebPartZone that itself defines new WebPartZones.

If you check out the documentation on building your own custom Layout Webpart, you’ll find its a nutty mess of string concatenation, tables, and magic javascript. If you have more simpler needs, as I did, you will be sorely disappointed: who would want to maintain that over time.

The gist of the example given in the documentation is to generate a layout on the fly, presumably calling AddZone at the right place. This will output the markup needed to dynamically create a zone for other Webparts to be added.

Just ask your designer to go in there and tweak some styles. They can update C# strings no problem right?

If, like me, you find this approach to be completely unacceptable, you might start wondering about a better way. And indeed, spelunking in the CMS base classes can prove fruitful. There is an overload for AddZone that takes a parameter for a container. So you just need to drop some placeholders in your view (.ascx file) and use them in the code behind:

ThreeColumnLayout.ascx
<div class="row"> <div class="col-3"> <asp:PlaceHolder runat="server" ID="Left"></asp:PlaceHolder> </div> <div class="col-3"> <asp:PlaceHolder runat="server" ID="Middle"></asp:PlaceHolder> </div> <div class="col-3"> <asp:PlaceHolder runat="server" ID="Right"></asp:PlaceHolder> </div> </div>

Then just override PrepareLayout as follows:

ThreeColumnLayout.cs
protected override void PrepareLayout() { // Dynamically generate zone IDs and names StartLayout(keepExistingControls: true); AddZone(this.ID + "_left", this.ID + " Left", Left); AddZone(this.ID + "_middle", this.ID + " Middle", Middle); AddZone(this.ID + "_right", this.ID + " Right", Right); EndLayout(addToControls: false); }

All of this comes about because the ZoneID of a WebpartZone needs to be unique on a page, even if you use the same Layout Webpart twice on a page. The PrepareLayout hook allows you to reliably generate unique IDs.

Still, Kentico support should bury the example they have in their docs into an “Advanced Custom Layouts” section. No one’s first introduction to building a user control should be a StringBuilder.

Advent of Code

I’ve been working on the Advent of Code challenges this year (big thanks to Eric Wastl for putting that together). It’s been a lot of fun.

Every day he posts two new Christmas themed challenges. The challenges are pitched as being for all skill levels, and I’ve definitely found some of them to be more time consuming than others.

The first few were fairly straight forward string processing, but some later challenges were more complicated: they probably could have been solved with a well crafted regex, but I opted for a custom State-Machine based parser. Some could be solved fairly iteratively, and some were prime opportunities to try a little recursion. It’s been great to stretch my mind trying to solve problems that are quite a bit different than my day-to-day.

I’ll probably update this post with commentary on some of my solutions, which are available on GitHub.

The projects pose a good chance to synthesize a bunch of skills and develop new knowledge of C# and some of the community libraries. So far I’ve used:

  • xUnit.NET
  • NFluent
  • Recursively processing JSON using JSON.NET
  • Build a graph to solve traveling salesman
  • Build a graph to solve a virtual circuit
  • State machines for escaping and unescaping strings

Looking forward to the rest of Advent of Code!

On Side-Projects for New Programmers

The other week I was involved in a couple panel sessions for high school students interested in going into the tech industry. They got a tour of our office and the opportunity to ask myself and some of the other engineers questions about our experiences.

One of the recurring points brought up by the engineers is the importance of having some personal projects to work on. You learn so much more by doing things on your own.

Fix Broken "Open With Code" Shell Extension

The last update to Visual Studio Code broke the convenient “Open With Code” shell extension. Previously, you’d be able to right click on a file or folder in Explorer and open it in a new instance of Code. But after the update, the icon is broken and Windows instead opens a dialog to choose what program you’d like to use to view the file.