text

The matter of song in early modern England: texts in and of the air / Katherine R. Larson

Barker Library - PR507.L37 2019




text

Shakespearean intersections: language, contexts, critical keywords / Patricia Parker

Hayden Library - PR3072.P37 2018




text

Eastern European Popular Music in a Transnational Context [electronic resource]: Beyond the Borders




text

Leadership in the Context of Religious Institutions [electronic resource] : The Case of Benedictine Monasteries / edited by Gèunter Mèuller-Stewens, Notker Wolf




text

Social Life Cycle Assessment [electronic resource]: Case Studies from the Textile and Energy Sectors




text

Rural Cinema Exhibition and Audiences in a Global Context [electronic resource]




text

The metamorphosis: a new translation, texts and contexts, criticism / Franz Kafka ; translated by Susan Bernofsky, Columbia University ; edited by Mark M. Anderson, Columbia University

Hayden Library - PT2621.A26 V413 2016




text

Fiesco's conspiracy at Genoa / by Friedrich Schiller ; translated by Flora Kimmich ; with an introduction and notes to the text by John Guthrie

Online Resource




text

The last days of mankind: the complete text / Karl Kraus ; translated by Fred Bridgham and Edward Timms ; with a glossary and index

Hayden Library - PT2621.R27 L4313 2015




text

Wallenstein: a dramatic poem / by Friedrich Schiller ; translation and notes to the text by Flora Kimmich ; introduction by Roger Paulin

Online Resource




text

Hermann Kurz und die 'Poesie der Wirklichkeit': Studien zum Frühwerk, Texte aus dem Nachlass / Matthias Slunitschek

Online Resource




text

Zwischen Intertextualität und Interpretation: Friedrich Schillers dramaturgische Arbeiten 1796-1805 / Marion Müller

Online Resource




text

Wallenstein: a dramatic poem / by Friedrich Schiller ; translation and notes to the text by Flora Kimmich ; introduction by Roger Paulin

Online Resource




text

Python programming in context / Bradley N. Miller, David L. Ranum, Julie Anderson

Miller, Bradley N., author




text

The African affairs reader : key texts in politics, development, and international relations / edited by Nic Cheeseman, Lindsay Whitfield and Carl Death




text

Babylonia, the Gulf Region, and the Indus : archaeological and textual evidence for contact in the third and early second millennium B.C. / Steffen Laursen and Piotr Steinkeller

Laursen, Steffen, author




text

It All Starts with a Humble <textarea>

Andy Bell rings out a fresh call in support of the timeless concept of progressive enhancement. What does it mean to build a modern JavaScript-focussed web experience that still works well if part of the stack isn’t supported or fails? Andy shows us how that might be done.


Those that know me well know that I make a lot of side projects. I most definitely make too many, but there’s one really useful thing about making lots of side projects: it allows me to experiment in a low-risk setting.

Side projects also allow me to accidentally create a context where I can demonstrate a really affective, long-running methodology for building on the web: progressive enhancement. That context is a little Progressive Web App that I’m tinkering with called Jotter. It’s incredibly simple, but under the hood, there’s a really solid experience built on top of a minimum viable experience which after reading this article, you’ll hopefully apply this methodology to your own work.

What is a minimum viable experience?

The key to progressive enhancement is distilling the user experience to its lowest possible technical solution and then building on it to improve the user experience. In the context of Jotter, that is a humble <textarea> element. That humble <textarea> is our minimum viable experience.

Let me show you how it’s built up, progressively real quick. If you disable CSS and JavaScript, you get this:

This result is great because I know that regardless of what happens, the user can do what they needed to do when the loaded Jotter in their browser: take some notes. That’s our minimum viable experience, completed with a few lines of code that work in every single browser—even very old browsers. Don’t you just love good ol’ HTML?

Now it’s time to enhance that minimum viable experience, progressively. It’s a good idea to do that in smaller steps rather than just provide a 0% experience or a 100% experience, which is the approach that’s often favoured by JavaScript framework enthusiasts. I think that process is counter-intuitive to the web, though, so building up from a minimum viable experience is the optimal way to go, in my opinion.

Understanding how a minimum viable experience works can be a bit tough, admittedly, so I like to use a the following diagram to explain the process:

Let me break down this diagram for both folks who can and can’t see it. On the top row, there’s four stages of a broken-up car, starting with just a wheel, all the way up to a fully functioning car. The car enhances only in a way that it is still mostly useless until it gets to its final form when the person is finally happy.

On the second row, instead of building a car, we start with a skateboard which immediately does the job of getting the person from point A to point B. This enhances to a Micro Scooter and then to a Push Bike. Its final form is a fancy looking Motor Scooter. I choose that instead of a car deliberately because generally, when you progressively enhance a project, it turns out to be way simpler and lighter than a project that was built without progressive enhancement in mind.

Now that we know what a minimum viable experience is and how it works, let’s apply this methodology to Jotter!

Add some CSS

The first enhancement is CSS. Jotter has a very simple design, which is mostly a full height <textarea> with a little sidebar. A flexbox-based, auto-stacking layout, inspired by a layout called The Sidebar is used and we’re good to go.

Based on the diagram from earlier, we can comfortably say we’re in Skateboard territory now.

Add some JavaScript

We’ve got styles now, so let’s enhance the experience again. A user can currently load up the site and take notes. If the CSS loads, it’ll be a more pleasant experience, but if they refresh their browser, they’re going to lose all of their work.

We can fix that by adding some local storage into the mix.

The functionality flow is pretty straightforward. As a user inputs content, the JavaScript listens to an input event and pushes the content of the <textarea> into localStorage. If we then set that localStorage data to populate the <textarea> on load, that user’s experience is suddenly enhanced because they can’t lose their work by accidentally refreshing.

The JavaScript is incredibly light, too:

const textArea = document.querySelector('textarea');
const storageKey = 'text';

const init = () => {

  textArea.value = localStorage.getItem(storageKey);

  textArea.addEventListener('input', () => {
    localStorage.setItem(storageKey, textArea.value);
  });
}

init();

In around 13 lines of code (which you can see a working demo here), we’ve been able to enhance the user’s experience considerably, and if we think back to our diagram from earlier, we are very much in Micro Scooter territory now.

Making it a PWA

We’re in really good shape now, so let’s turn Jotter into a Motor Scooter and make this thing work offline as an installable Progressive Web App (PWA).

Making a PWA is really achievable and Google have even produced a handy checklist to help you get going. You can also get guidance from a Lighthouse audit.

For this little app, all we need is a manifest and a Service Worker to cache assets and serve them offline for us if needed.

The Service Worker is actually pretty slim, so here it is in its entirety:

const VERSION = '0.1.3';
const CACHE_KEYS = {
  MAIN: `main-${VERSION}`
};

// URLS that we want to be cached when the worker is installed
const PRE_CACHE_URLS = ['/', '/css/global.css', '/js/app.js', '/js/components/content.js'];

/**
 * Takes an array of strings and puts them in a named cache store
 *
 * @param {String} cacheName
 * @param {Array} items=[]
 */
const addItemsToCache = function(cacheName, items = []) {
  caches.open(cacheName).then(cache => cache.addAll(items));
};

self.addEventListener('install', evt => {
  self.skipWaiting();

  addItemsToCache(CACHE_KEYS.MAIN, PRE_CACHE_URLS);
});

self.addEventListener('activate', evt => {
  // Look for any old caches that don't match our set and clear them out
  evt.waitUntil(
    caches
      .keys()
      .then(cacheNames => {
        return cacheNames.filter(item => !Object.values(CACHE_KEYS).includes(item));
      })
      .then(itemsToDelete => {
        return Promise.all(
          itemsToDelete.map(item => {
            return caches.delete(item);
          })
        );
      })
      .then(() => self.clients.claim())
  );
});

self.addEventListener('fetch', evt => {
  evt.respondWith(
    caches.match(evt.request).then(cachedResponse => {
      // Item found in cache so return
      if (cachedResponse) {
        return cachedResponse;
      }

      // Nothing found so load up the request from the network
      return caches.open(CACHE_KEYS.MAIN).then(cache => {
        return fetch(evt.request)
          .then(response => {
            // Put the new response in cache and return it
            return cache.put(evt.request, response.clone()).then(() => {
              return response;
            });
          })
          .catch(ex => {
            return;
          });
      });
    })
  );
});

What the Service Worker does here is pre-cache our core assets that we define in PRE_CACHE_URLS. Then, for each fetch event which is called per request, it’ll try to fulfil the request from cache first. If it can’t do that, it’ll load the remote request for us. With this setup, we achieve two things:

  1. We get offline support because we stick our critical assets in cache immediately so they will be accessible offline
  2. Once those critical assets and any other requested assets are cached, the app will run faster by default

Importantly now, because we have a manifest, some shortcut icons and a Service Worker that gives us offline support, we have a fully installable PWA!

Wrapping up

I hope with this simplified example you can see how approaching web design and development with a progressive enhancement approach, everyone gets an acceptable experience instead of those who are lucky enough to get every aspect of the page at the right time.

Jotter is very much live and in the process of being enhanced further, which you can see on its little in-app roadmap, so go ahead and play around with it.

Before you know it, it’ll be a car itself, but remember: it’ll always start as a humble little <textarea>.


About the author

Andy Bell is an independent designer and front-end developer who’s trying to make everyone’s experience on the web better with a focus on progressive enhancement and accessibility.

More articles by Andy





text

JSJ 376: Trix: A Rich Text Editor for Everyday Writing with Javan Makhmali

Sponsors

Panel

  • Aimee Knight

  • Chris Ferdinandi

  • Christopher Beucheler

  • AJ O’Neal

With Special Guest: Javan Makhmali

Episode Summary

Today’s guest is Javan Makhmali, who works for Basecamp and helped develop Trix. Trix is a rich text editor for the web, made purposefully simple for everyday use instead of a full layout tool. Trix is not the same as Tiny MCE, and Javan discusses some of the differences. He talks about the benefits of using Trix over other native browser features for text editing. He talks about how Trix has simplified the work at Basecamp, especially when it came to crossing platforms. Javan talks more about how Trix differs from other text editors like Google Docs and contenteditable, how to tell if Trix is functioning correctly, and how it works with Markdown.

The panel discusses more specific aspects of Trix, such as Exec command. One of the features of Trix is it is able to output consistently in all browsers and uses semantic, clean HTML instead of classnames. Javan talks about how Trix handles getting rid of the extraneous cruft of formatting when things are copy and pasted, the different layers of code, and the undo feature. He talks about whether or not there will be more features added to Trix. The panel discusses who could benefit from using Trix. The show finishes with Javan talking about Basecamp’s decision to make Trix open source and why they code in CoffeeScript. 

Links

Follow DevChat on Facebook and Twitter

Picks

Javan Makhmali:

Chris Ferdinandi:

AJ O’Neal:

Christopher Beucheler: 

Aimee Knight:




text

"The yellow wall-paper" by Charlotte Perkins Gilman [electronic resource] : a dual-text critical edition / edited by Shawn St. Jean

Gilman, Charlotte Perkins, 1860-1935




text

Young children's literacy development and the role of televisual texts [electronic resource] / Naima Browne

Browne, Naima




text

The Zen canon [electronic resource] : understanding the classic texts / edited by Steven Heine and Dale S. Wright




text

Error in Text

In the Editorial titled “Eliminating Wasteful Health Care Spending—Is the United States Simply Spinning Its Wheels?,” published in January 2020, 2 errors appeared in the text. The surname of a cited author, Hackbarth, was mispelled as Hackbert. In addition, a mention of $282 billion was wrong; the correct value is $286 billion. The article has been corrected online.




text

Aquatic pollution : an introductory text / Edward A. Laws, Los Angeles, US

Laws, Edward A., 1945- author




text

Indian Ocean adventure / photographs by Mike Wilson ; text by Arthur C. Clarke

Clarke, Arthur C. (Arthur Charles), 1917-2008




text

Writing scientific English : a textbook of English as a foreign language for students of physical and engineering sciences / John Swales

Swales, John




text

New trends in natural dyes for textiles / Padma Shree Vankar, Dhara Shukla

Online Resource




text

Recent advances in decolorization and degradation of dyes in textile effluent by biological approaches / Ram Lakhan Singh, Pradeep Kumar Singh and Rajat Pratap Singh

Online Resource




text

Paul's corporate Christophany : an evaluation of Paul's Christophanic references in their epistolary contexts / Rob A. Fringer

Fringer, Rob A., author




text

The body in biblical, Christian and Jewish texts / edited by Joan E. Taylor




text

1 Peter : a handbook on the Greek text / Mark Dubis

Dubis, Mark, 1960-




text

The Mysteries, resurrection, and 1 Corinthians 15 : comparative methodology and contextual exegesis / Terri Moore

Moore, Terri (New Testament teacher), author




text

Reading Ephesians : exploring social entrepreneurship in the text / Minna Shkul

Shkul, Minna, author




text

The vehement Jesus : grappling with troubling Gospel texts / David J. Neville

Neville, David J., author




text

The earliest perceptions of Jesus in context : essays in honour of John Nolland on his 70th birthday / edited by Aaron W. White, Craig A. Evans and David Wenham




text

Scripture, texts, and tracings in 1 Corinthians / edited by Linda L. Belleville and B. J. Oropeza ; afterword by Christopher D. Stanley




text

Acts : a handbook on the Greek text / Martin M. Culy, Mikeal C. Parsons

Culy, Martin M., author




text

James : a handbook on the Greek text / A.K.M. Adam

Adam, A. K. M. (Andrew Keith Malcolm), 1957-




text

The Pastoral Letters : a handbook on the Greek text / Larry J. Perkins

Perkins, Larry J. (Larry James), 1948- author




text

Revelation : a handbook on the Greek text / David L. Mathewson

Mathewson, David, author




text

Jesus, skepticism & the problem of history : criteria & context in the study of Christian origins / Darrell L. Bock and J. Ed Komoszewski, editors ; foreword by N.T. Wright




text

The making of Christian morality : reading Paul in ancient and modern contexts / David G. Horrell

Horrell, David G., author




text

Troublesome texts : the Bible in colonial and contemporary culture / R.S. Sugirtharajah

Sugirtharajah, R. S. (Rasiah S.), author




text

An unsuitable book : the Bible as scandalous text / Hugh S. Pyper

Pyper, Hugh S., author




text

Story as history--history as story : the gospel tradition in the context of ancient oral history / by Samuel Byrskog

Byrskog, Samuel




text

Myths and mistakes in New Testament textual criticism / edited by Elijah Hixson and Peter J. Gurry ; foreword by Daniel B. Wallace




text

Essential essays for the study of the military in first-century Palestine : soldiers and the New Testament context / edited by Christopher B. Zeichman




text

A poly(allylamine hydrochloride)/poly(styrene sulfonate) microcapsule-coated cotton fabric for stimulus-responsive textiles

RSC Adv., 2020, 10,17731-17738
DOI: 10.1039/D0RA02474K, Paper
Open Access
Zhiqi Zhao, Qiujin Li, Jixian Gong, Zheng Li, Jianfei Zhang
This study reports a stimulus-responsive fabric incorporating a combination of microcapsules, containing polyelectrolytes poly(allylamine hydrochloride) (PAH) and poly(styrene sulfonate) sodium salt (PSS), formed via a layer-by-layer (LBL) approach.
The content of this RSS Feed (c) The Royal Society of Chemistry




text

Tapping into unstructured data [electronic resource] : integrating unstructured data and textual analytics into business intelligence / William H. Inmon, Anthony Nesavich

Inmon, William H