Skip to content

Commit 4a10285

Browse files
committed
merge
2 parents f4d1f95 + 0873473 commit 4a10285

21 files changed

Lines changed: 60 additions & 110 deletions

File tree

1-js/05-data-types/03-string/1-ucfirst/solution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ There are two variants here:
1515

1616
Here's the 2nd variant:
1717

18-
```js run
18+
```js run demo
1919
function ucFirst(str) {
2020
if (!str) return str;
2121

1-js/11-async/02-promise-basics/article.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Everyone is happy, because the people don't crowd you any more, and fans, becaus
88

99
This is a real-life analogy for things we often have in programming:
1010

11-
1. A "producing code" that does something and takes time. For instance, the code loads a remote script. That's a "singer".
11+
1. A "producing code" that does something and takes time. For instance, the code loads data over a network. That's a "singer".
1212
2. A "consuming code" that wants the result of the "producing code" once it's ready. Many functions may need that result. These are the "fans".
1313
3. A *promise* is a special JavaScript object that links the "producing code" and the "consuming code" together. In terms of our analogy: this is the "subscription list". The "producing code" takes whatever time it needs to produce the promised result, and the "promise" makes that result available to all of the subscribed code when it's ready.
1414

@@ -27,7 +27,7 @@ The function passed to `new Promise` is called the *executor*. When the promise
2727
The resulting `promise` object has internal properties:
2828

2929
- `state` — initially "pending", then changes to either "fulfilled" or "rejected",
30-
- `result` — an arbitrary value of your choosing, initially `undefined`.
30+
- `result` — an arbitrary value, initially `undefined`.
3131

3232
When the executor finishes the job, it should call one of the functions that it gets as arguments:
3333

@@ -56,7 +56,7 @@ let promise = new Promise(function(resolve, reject) {
5656
We can see two things by running the code above:
5757

5858
1. The executor is called automatically and immediately (by the `new Promise`).
59-
2. The executor receives two arguments: `resolve` and `reject` — these functions are pre-defined by the JavaScript engine. So we don't need to create them. Instead, we should write the executor to call them when ready.
59+
2. The executor receives two arguments: `resolve` and `reject` — these functions are pre-defined by the JavaScript engine. So we don't need to create them. We only should call one of them when ready.
6060

6161
After one second of "processing" the executor calls `resolve("done")` to produce the result:
6262

@@ -77,7 +77,7 @@ let promise = new Promise(function(resolve, reject) {
7777

7878
To summarize, the executor should do a job (something that takes time usually) and then call `resolve` or `reject` to change the state of the corresponding Promise object.
7979

80-
The Promise that is either resolved or rejected is called "settled", as opposed to a "pending" Promise.
80+
The Promise that is either resolved or rejected is called "settled", as opposed to a initially "pending" Promise.
8181

8282
````smart header="There can be only a single result or an error"
8383
The executor should call only one `resolve` or one `reject`. The promise's state change is final.
@@ -112,9 +112,9 @@ let promise = new Promise(function(resolve, reject) {
112112
});
113113
```
114114

115-
For instance, this might happen when we start to do a job but then see that everything has already been completed.
115+
For instance, this might happen when we start to do a job but then see that everything has already been completed and cached.
116116

117-
That's fine. We immediately have a resolved Promise, nothing wrong with that.
117+
That's fine. We immediately have a resolved promise.
118118
````
119119
120120
```smart header="The `state` and `result` are internal"
@@ -140,12 +140,12 @@ promise.then(
140140
141141
The first argument of `.then` is a function that:
142142
143-
1. runs when the Promise is resolved, and
143+
1. runs when the promise is resolved, and
144144
2. receives the result.
145145
146146
The second argument of `.then` is a function that:
147147
148-
1. runs when the Promise is rejected, and
148+
1. runs when the promise is rejected, and
149149
2. receives the error.
150150
151151
For instance, here's a reaction to a successfully resolved promise:
@@ -233,10 +233,10 @@ new Promise((resolve, reject) => {
233233
.then(result => show result, err => show error)
234234
```
235235
236-
It's not exactly an alias though. There are several important differences:
236+
It's not exactly an alias of `then(f,f)` though. There are several important differences:
237237
238238
1. A `finally` handler has no arguments. In `finally` we don't know whether the promise is successful or not. That's all right, as our task is usually to perform "general" finalizing procedures.
239-
2. Finally passes through results and errors to the next handler.
239+
2. A `finally` handler passes through results and errors to the next handler.
240240
241241
For instance, here the result is passed through `finally` to `then`:
242242
```js run
@@ -257,11 +257,11 @@ It's not exactly an alias though. There are several important differences:
257257
.catch(err => alert(err)); // <-- .catch handles the error object
258258
```
259259
260-
That's very convenient, because finally is not meant to process promise results. So it passes them through.
260+
That's very convenient, because `finally` is not meant to process a promise result. So it passes it through.
261261
262262
We'll talk more about promise chaining and result-passing between handlers in the next chapter.
263263
264-
3. Last, but not least, `.finally(f)` is a more convenient syntax than `.then(f, f)`: no need to duplicate the function.
264+
3. Last, but not least, `.finally(f)` is a more convenient syntax than `.then(f, f)`: no need to duplicate the function `f`.
265265
266266
````smart header="On settled promises handlers runs immediately"
267267
If a promise is pending, `.then/catch/finally` handlers wait for the result. Otherwise, if a promise has already settled, they execute immediately:

1-js/11-async/03-promise-chaining/head.html

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,6 @@
1010
document.head.append(script);
1111
});
1212
}
13-
14-
class HttpError extends Error {
15-
constructor(response) {
16-
super(`${response.status} for ${response.url}`);
17-
this.name = 'HttpError';
18-
this.response = response;
19-
}
20-
}
21-
22-
function loadJson(url) {
23-
return fetch(url)
24-
.then(response => {
25-
if (response.status == 200) {
26-
return response.json();
27-
} else {
28-
throw new HttpError(response);
29-
}
30-
})
31-
}
3213
</script>
3314

3415
<style>

1-js/11-async/04-promise-error-handling/head.html

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
11
<script>
2-
function loadScript(src) {
3-
return new Promise(function(resolve, reject) {
4-
let script = document.createElement('script');
5-
script.src = src;
6-
7-
script.onload = () => resolve(script);
8-
script.onerror = () => reject(new Error("Script load error: " + src));
9-
10-
document.head.append(script);
11-
});
12-
}
13-
142
class HttpError extends Error {
153
constructor(response) {
164
super(`${response.status} for ${response.url}`);

2-ui/4-forms-controls/2-focus-blur/3-editable-div/solution.view/my.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@
2020
}
2121

2222
.edit:focus {
23-
outline: none;
2423
/* remove focus border in Safari */
24+
outline: none;
2525
}

2-ui/4-forms-controls/2-focus-blur/3-editable-div/source.view/my.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@
2020
}
2121

2222
.edit:focus {
23-
outline: none;
2423
/* remove focus border in Safari */
24+
outline: none;
2525
}

2-ui/4-forms-controls/2-focus-blur/4-edit-td-click/solution.view/my.css

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
margin: 0;
44
padding: 0;
55
display: block;
6-
resize: none;
6+
77
/* remove resizing handle in Firefox */
8+
resize: none;
89

9-
outline: none;
1010
/* remove outline on focus in Chrome */
11+
outline: none;
1112

12-
overflow: auto;
1313
/* remove scrollbar in IE */
14+
overflow: auto;
1415
}
1516

1617
.edit-controls {

2-ui/4-forms-controls/2-focus-blur/5-keyboard-mouse/solution.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
We can use `mouse.onclick` to handle the click and make the mouse "moveable" with `position:fixed`, then then `mouse.onkeydown` to handle arrow keys.
2+
We can use `mouse.onclick` to handle the click and make the mouse "moveable" with `position:fixed`, then `mouse.onkeydown` to handle arrow keys.
33

44
The only pitfall is that `keydown` only triggers on elements with focus. So we need to add `tabindex` to the element. As we're forbidden to change HTML, we can use `mouse.tabIndex` property for that.
55

2-ui/4-forms-controls/2-focus-blur/article.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
An element receives a focus when the user either clicks on it or uses the `key:Tab` key on the keyboard. There's also an `autofocus` HTML attribute that puts the focus into an element by default when a page loads and other means of getting a focus.
44

5-
Focusing generally means: "prepare to accept the data here", so that's the moment when we can run the code to initialize or load something.
5+
Focusing on an element generally means: "prepare to accept the data here", so that's the moment when we can run the code to initialize the required functionality.
66

77
The moment of losing the focus ("blur") can be even more important. That's when a user clicks somewhere else or presses `key:Tab` to go to the next form field, or there are other means as well.
88

99
Losing the focus generally means: "the data has been entered", so we can run the code to check it or even to save it to the server and so on.
1010

11-
There are important peculiarities when working with focus events. We'll do the best to cover them here.
11+
There are important peculiarities when working with focus events. We'll do the best to cover them further on.
1212

1313
## Events focus/blur
1414

@@ -203,7 +203,6 @@ So here's another working variant:
203203

204204
<script>
205205
*!*
206-
// put the handler on capturing phase (last argument true)
207206
form.addEventListener("focusin", () => form.classList.add('focused'));
208207
form.addEventListener("focusout", () => form.classList.remove('focused'));
209208
*/!*

2-ui/5-loading/02-script-async-defer/article.md

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ There are some workarounds to that. For instance, we can put a script at the bot
2929
</body>
3030
```
3131

32-
But this solution is far from perfect. For example, the browser actually notices the script (and can start downloading it) only after it downloaded the full HTML document. For long HTML documents, that may be a noticeable delay.
32+
But this solution is far from perfect. For example, the browser notices the script (and can start downloading it) only after it downloaded the full HTML document. For long HTML documents, that may be a noticeable delay.
3333

34-
Such things are invisible for people using very fast connections, but many people in the world still have slower internet speeds and far-from-perfect mobile connectivity.
34+
Such things are invisible for people using very fast connections, but many people in the world still have slower internet speeds and use far-from-perfect mobile internet.
3535

36-
Luckily, there are two `<script>` attributes that solve the problem for us: `defer` and `async`
36+
Luckily, there are two `<script>` attributes that solve the problem for us: `defer` and `async`.
3737

3838
## defer
3939

@@ -86,7 +86,7 @@ But the specification requires scripts to execute in the document order, so it w
8686
```
8787

8888
```smart header="The `defer` attribute is only for external scripts"
89-
The `defer` attribute is ignored if the script has no `src`.
89+
The `defer` attribute is ignored if the `<script>` tag has no `src`.
9090
```
9191
9292
@@ -120,16 +120,17 @@ So, if we have several `async` scripts, they may execute in any order. Whatever
120120
2. `DOMContentLoaded` may happen both before and after `async`, no guarantees here.
121121
3. Async scripts don't wait for each other. A smaller script `small.js` goes second, but probably loads before `long.js`, so runs first. That's called a "load-first" order.
122122

123-
Async scripts are great when we integrate an independent third-party script into the page: counters, ads and so on.
123+
Async scripts are great when we integrate an independent third-party script into the page: counters, ads and so on, as they don't depend on our scripts, and our scripts shouldn't wait for them:
124124

125125
```html
126+
<!-- Google Analytics is usually added like this -->
126127
<script async src="https://google-analytics.com/analytics.js"></script>
127128
```
128129

129130

130131
## Dynamic scripts
131132

132-
We can also create a script dynamically using JavaScript:
133+
We can also add a script dynamically using JavaScript:
133134

134135
```js run
135136
let script = document.createElement('script');
@@ -145,7 +146,7 @@ That is:
145146
- They don't wait for anything, nothing waits for them.
146147
- The script that loads first -- runs first ("load-first" order).
147148

148-
We can change the load-first order into the document order by explicitly setting `async` to `false`:
149+
We can change the load-first order into the document order (just like regular scripts) by explicitly setting `async` property to `false`:
149150

150151
```js run
151152
let script = document.createElement('script');
@@ -191,7 +192,4 @@ Please note that if you're using `defer`, then the page is visible before the sc
191192
192193
So, buttons should be disabled by CSS or by other means, to let the user
193194
194-
In practice, `defer` is used for scripts that need DOM and/or their relative execution order is important.
195-
196-
197-
So `async` is used for independent scripts, like counters or ads, that don't need to access page content. And their relative execution order does not matter.
195+
In practice, `defer` is used for scripts that need the whole DOM and/or their relative execution order is important. And `async` is used for independent scripts, like counters or ads. And their relative execution order does not matter.

0 commit comments

Comments
 (0)