theme | style |
---|---|
gaia |
/*@import url('https://fonts.googleapis.com/css2?family=Cantarell:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://cdn.jsdelivr.net/npm/hack-font@3/build/web/hack-subset.css');*/
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css');
.twocolumn { display: flex; }
.col { flex: 1 }
section {
background-color: white;
background-image: linear-gradient(90deg, rgba(216, 216, 216, .03) 50%,
transparent 50%),
linear-gradient(90deg, rgba(216, 216, 216, .06) 50%, transparent 50%),
linear-gradient(90deg, transparent 50%, rgba(216, 216, 216, .08) 50%),
linear-gradient(90deg, transparent 50%, rgba(216, 216, 216, .1) 50%);
background-size: 26px, 58px, 74px, 106px;
color: black;
font-family: Cantarell;
letter-spacing: 0;
}
section:not(.gaia):not(.invert) h1, section:not(.gaia):not(.invert) h2 {
color: #0288d1;
}
code {
background-color: rgb(216, 216, 216);
border-radius: 5px;
color: black;
font-family: Hack
}
pre code {
background-color: black;
color: white;
}
.hljs-number, .hljs-params { color: rgb(71, 155, 204); }
.time {
background-color: black;
color: white;
font-size: 150%;
padding: 0.2em;
text-decoration: underline 2px red;
}
.credit {
font-size: 80%;
position: absolute;
bottom: 5%;
left: 70%;
}
.hat::before {
content: '🗣';
margin: 0 0.25em;
}
.hat { font-weight: bold; }
|
Philip Chimento • pchimento • ptomato • @therealptomato GUADEC Online, July 25, 2020
- Same thing we talk about every year!
- What's new in GJS?
- Including a bit about a lesser-known corner:
Intl
- Including a bit about a lesser-known corner:
- What's next in GJS?
- We need some help! Here's what you can do
- Shout-outs are a thank-you to someone who contributed a feature
- Presentation is full of links if you want to click through later
- If you want to follow along: ptomato.name/talks/guadec2020
- gjs-docs is now way easier to maintain and contribute to Meg Ford
- Documentation added for GNOME Shell internals Andy Holmes
- 9 crashing bugs still open
- 6 fixed, 5 new since last GUADEC 📈
- Improvements to type safety Marco Trevisan
- Looking up properties that may come from C:
- e.g.
myWindow.present()
- Don't look up
myWindow.customProperty
- Negative lookup cache Daniel Van Vugt
- e.g.
- Calling C functions
- Translating arguments is slow
- e.g.
void gtk_c_func(int arg1, double arg2)
→Gtk.c_func(number, number)
- Argument cache Giovanni Campagna
- Adding GObject properties to your class was always really verbose
- Easy to do notifications incorrectly, for example
- Now you can leave out the boring part:
// Just delete all this!
get my_property() {
return this._myProperty;
}
set my_property(value) {
if (this._myProperty === value)
return;
this._myProperty = value;
this.notify('my-property');
}
- JavaScript is gaining features every year
- No longer the language that everyone loved to hate
- Which of these new features can you use in GJS?
String.trimStart()
,String.trimEnd()
String.matchAll()
Array.flat()
Array.flatMap()
Object.fromEntries()
globalThis
BigInt
,BigInt64Array
,BigUint64Array
- String generics removed
- New
Intl
features
- Nonstandard way of calling String methods on a non-string object
- Use moz68tool to scan your code for them
- Don't use array generics either, Mozilla will remove them soon
👎
let num = 15;
String.endsWith(num, 5);
👍
String.prototype.endsWith.call(num, 5);
String(num).endsWith(5);
`${num}`.endsWith(5);
// ⇒ true
Intl.RelativeTimeFormat
- Useful for user interfaces
rtf = new Intl.RelativeTimeFormat('en',
{style: 'narrow'})
rtf.format(-1, 'day')
// ⇒ "1 day ago"
rtf = new Intl.RelativeTimeFormat('es',
{numeric: 'auto'})
rtf.format(2, 'day')
// ⇒ "pasado mañana"
- A global object
- Does internationalization stuff for you
- Some things awkward to do with
gettext
.Intl
makes them easy - Some things
gettext
does well.Intl
mostly doesn't do those
Intl.Collator
- locale-sensitive sortingIntl.DateTimeFormat
- printing dates and times ("Fri Jul 17"
)Intl.NumberFormat
- printing numbers ("€ 0,00"
)Intl.RelativeTimeFormat
- printing relative times ("3 days ago"
)- More in future editions of JS!
/* Translators: this is the month name and day number
followed by a time string in 24h format.
i.e. "May 25, 14:30" */
format = N_("%B %-d, %H\u2236%M");
- How does the translator know what to put there for their locale?
#. Translators: this is the month name and day number
#. followed by a time string in 24h format.
#. i.e. "May 25, 14:30"
#: js/misc/util.js:255
#, no-c-format
msgid "%B %-d, %H∶%M"
msgstr "%j, %R %p" 😱😱😱
- More readable, even if longer
- Less burden on GNOME translators
format = new Intl.DateTimeFormat(myLocale, {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h24',
})
format.format(Date.now())
// ⇒ "Jul. 17, 18:01" in my locale
- Who does translate those, anyway?
- ICU project
- Unicode Common Locale Data Repository (CLDR)
- They have the power of major browser vendors behind them
- What if I don't like the ICU/CLDR's translations in my UI?
- You can still customize them using
formatToParts()
- Supported by most
Intl
formatters
- You can still customize them using
- What if I don't like the ICU/CLDR's translations in my UI?
- You can still customize them using
formatToParts()
- Supported by most
Intl
formatters
- You can still customize them using
- Progress towards removing the Big Hammer
- Progress towards ES Modules
- Following edition of JS language (based on Firefox 78)
- What is the Big Hammer?
- Why does it need to be removed?
- Why isn't it removed yet?
- I gave a talk about this at GUADEC last year
- Some objects accidentally survive a garbage collection
- The “Big Hammer” detects this and runs an extra garbage collection
- When memory is constantly being used and discarded, extra garbage collections happen quite often
- Bad for performance
- We have a fix and it (mostly) works
- Except for a few strange cases... Evan Welsh
- Ironically, the fix leads to higher average memory usage
- Public relations catastrophe! 😬
- We need to tune the garbage collector to work better for our use case
- We need help quantifying acceptable memory usage
- We need to tune the garbage collector to work better for our use case
- We need help quantifying acceptable memory usage
- We need to figure out some solution that fits:
- Shell
- Apps
- Random scripts that don't even run a main loop
- What are ES modules?
- When can we use them?
<input type="text" id="phone-number"
onchange="if ($('phone-number').val().length !== 10) alert('Invalid phone number!')">
- GJS had its own module system:
imports
👎
const System = imports.system; // loads built-in System module
const {Gtk} = imports.gi; // loads binding for Gtk
imports.searchPath.unshift('.');
const MyModule = imports.src.myModule; // loads ./src/myModule.js
- Now we have one solution for this across JavaScript platforms
- Standardized in ECMAScript 2015: "ES Modules"
👍
import System from 'system';
import Gtk from 'gi://Gtk';
import { MyClass } from './src/myModule.js';
- Currently working on a way to use the two module systems side by side Evan Welsh
- Technically, ES modules are a slightly different syntax than regular JavaScript
- Based on Firefox 78 Evan Welsh
??
operator?.
operator- Static class fields
- Numeric separators (
1_000_000
) String.replaceAll()
Promise.allSettled()
Intl.Locale
Intl.ListFormat
- For GNOME Shell
- For apps
- For shell extensions
- Shell extensions seen as "separate" from GNOME
- One of the biggest sources of community unhappiness
- Sri gave a talk on Friday on this topic
- Join the unconference session on Sunday 18:00 UTC!
- Despite some improvements, developer tools are still not very good
- Here are some ideas
- These projects are not too large
- Can be picked up without knowledge of all of the internals of GJS
gjs> ({a:5, b:3, foo:true})
[object Object]
gjs> [undefined, null]
,
gjs> 😬😬😬
Issue #104 — Better console interpreter output
-
Debugger is quite bare-bones
-
Doesn't handle multiple source files very well
-
Most code is spread over multiple source files
-
Issue #207 — Source locations and
list
command -
Issue #208 —
backtrace full
command
- Become a code reviewer for GJS
- Create a good workflow for people who want to get started contributing to GJS
- Create a good process for measuring performance and memory usage in GNOME Shell
- GJS contributors from 3.36 and 3.38
- Background pattern by Randy Merrill — MIT license
Presentation licensed under Creative Commons BY-NC-ND 4.0
String.trimStart()
, String.trimEnd()
- New standardized methods for trimming whitespace
- replaces the old nonstandard
trimLeft
,trimRight
👍
' foo '.trimStart()
// ⇒ "foo "
' foo '.trimEnd()
// ⇒ " foo"
👎
' foo '.trimLeft()
' foo '.trimRight()
String.matchAll()
- Easier access to regular expression capture groups
- Easier iterating through multiple matches in a string
const s = 'GNOME 3.36 and 3.38';
const pat = /(\d+)\.(\d+)/g;
for (let [v, major, minor] of s.matchAll(pat)) {
// On first iteration:
// v = '3.36'
// major = '3'
// minor = '36'
// On second iteration:
// v = '3.38'
// major = '3'
// minor = '38'
}
Array.flat()
- Well known from lodash and friends
[1, 2, [3, 4]].flat()
// ⇒ [1, 2, 3, 4]
Array.flatMap()
- A sort of reverse
Array.filter()
- You can add elements while iterating functional-style
function dashComponents(strings) {
return strings.flatMap(s => s.split('-'));
}
dashComponents(['foo-bar', 'a-b-c'])
// ⇒ ['foo', 'bar', 'a', 'b', 'c']
Object.fromEntries()
- Create an object from iterable key-value pairs
o = Object.fromEntries(['a', 1], ['b', 2])
o.a
// ⇒ 1
o.b
// ⇒ 2
globalThis
- Ever find it weird that GJS's global object is named
window
?
👍
if (typeof globalThis.foo === 'undefined')
👎
if (typeof window.foo === 'undefined')
- Large numbers in JS are inexact
- BigInt is a new type in JS, arbitrary-precision integers
- BigInt literals are a number suffixed with
n
Number.MAX_SAFE_INTEGER
// ⇒ 9007199254740991
9007199254740992 === 9007199254740993
// ⇒ true
BigInt(Number.MAX_SAFE_INTEGER)
// ⇒ 9007199254740991n
9007199254740992n === 9007199254740993n
// ⇒ false
- If you didn't already need to use it? Probably ignore it for now
- In the future, 64-bit APIs will accept BigInt as well as numbers
- Looking for a way to change the type of constants like
GLib.MAXINT64
without breaking existing code Evan Welsh
- Also two new typed array types for BigInts that fit in 64 bits
let s = new BigInt64Array([-1n, -2n]);
let u = new BigUint64Array([1n, 2n]);