diff --git a/1-js/01-getting-started/4-devtools/article.md b/1-js/01-getting-started/4-devtools/article.md
index c84d927047..50926d4f76 100644
--- a/1-js/01-getting-started/4-devtools/article.md
+++ b/1-js/01-getting-started/4-devtools/article.md
@@ -29,10 +29,15 @@ The exact look of developer tools depends on your version of Chrome. It changes
- Here we can see the red-colored error message. In this case, the script contains an unknown "lalala" command.
- On the right, there is a clickable link to the source `bug.html:12` with the line number where the error has occurred.
-Below the error message, there is a blue `>` symbol. It marks a "command line" where we can type JavaScript commands. Press `key:Enter` to run them (`key:Shift+Enter` to input multi-line commands).
+Below the error message, there is a blue `>` symbol. It marks a "command line" where we can type JavaScript commands. Press `key:Enter` to run them.
Now we can see errors, and that's enough for a start. We'll come back to developer tools later and cover debugging more in-depth in the chapter .
+```smart header="Multi-line input"
+Usually, when we put a line of code into the console, and then press `key:Enter`, it executes.
+
+To insert multiple lines, press `key:Shift+Enter`. This way one can enter long fragments of JavaScript code.
+```
## Firefox, Edge, and others
@@ -50,12 +55,6 @@ Open Preferences and go to the "Advanced" pane. There's a checkbox at the bottom
Now `key:Cmd+Opt+C` can toggle the console. Also, note that the new top menu item named "Develop" has appeared. It has many commands and options.
-```smart header="Multi-line input"
-Usually, when we put a line of code into the console, and then press `key:Enter`, it executes.
-
-To insert multiple lines, press `key:Shift+Enter`. This way one can enter long fragments of JavaScript code.
-```
-
## Summary
- Developer tools allow us to see errors, run commands, examine variables, and much more.
diff --git a/1-js/02-first-steps/03-strict-mode/article.md b/1-js/02-first-steps/03-strict-mode/article.md
index 573d76bc55..a96432002e 100644
--- a/1-js/02-first-steps/03-strict-mode/article.md
+++ b/1-js/02-first-steps/03-strict-mode/article.md
@@ -42,7 +42,7 @@ Only comments may appear above `"use strict"`.
```warn header="There's no way to cancel `use strict`"
There is no directive like `"no use strict"` that reverts the engine to old behavior.
-Once we enter strict mode, there's no return.
+Once we enter strict mode, there's no going back.
```
## Browser console
diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md
index 0da6173735..cce9267dba 100644
--- a/1-js/02-first-steps/05-types/article.md
+++ b/1-js/02-first-steps/05-types/article.md
@@ -10,9 +10,9 @@ message = 123456;
Programming languages that allow such things are called "dynamically typed", meaning that there are data types, but variables are not bound to any of them.
-There are seven basic data types in JavaScript. Here, we'll cover them in general and in the next chapters we'll talk about each of them in detail.
+There are eight basic data types in JavaScript. Here, we'll cover them in general and in the next chapters we'll talk about each of them in detail.
-## A number
+## Number
```js
let n = 123;
@@ -62,14 +62,33 @@ Special numeric values formally belong to the "number" type. Of course they are
We'll see more about working with numbers in the chapter .
-## A string
+## BigInt
+
+In JavaScript, the "number" type cannot represent integer values larger than 253 (or less than -253 for negatives), that's a technical limitation caused by their internal representation. That's about 16 decimal digits, so for most purposes the limitation isn't a problem, but sometimes we need really big numbers, e.g. for cryptography or microsecond-precision timestamps.
+
+`BigInt` type was recently added to the language to represent integers of arbitrary length.
+
+A `BigInt` is created by appending `n` to the end of an integer literal:
+
+```js
+// the "n" at the end means it's a BigInt
+const bigInt = 1234567890123456789012345678901234567890n;
+```
+
+As `BigInt` numbers are rarely needed, we devoted them a separate chapter .
+
+```smart header="Compatability issues"
+Right now `BigInt` is supported in Firefox and Chrome, but not in Safari/IE/Edge.
+```
+
+## String
A string in JavaScript must be surrounded by quotes.
```js
let str = "Hello";
let str2 = 'Single quotes are ok too';
-let phrase = `can embed ${str}`;
+let phrase = `can embed another ${str}`;
```
In JavaScript, there are 3 types of quotes.
@@ -78,7 +97,7 @@ In JavaScript, there are 3 types of quotes.
2. Single quotes: `'Hello'`.
3. Backticks: `Hello`.
-Double and single quotes are "simple" quotes. There's no difference between them in JavaScript.
+Double and single quotes are "simple" quotes. There's practically no difference between them in JavaScript.
Backticks are "extended functionality" quotes. They allow us to embed variables and expressions into a string by wrapping them in `${…}`, for example:
@@ -102,12 +121,12 @@ alert( "the result is ${1 + 2}" ); // the result is ${1 + 2} (double quotes do n
We'll cover strings more thoroughly in the chapter .
```smart header="There is no *character* type."
-In some languages, there is a special "character" type for a single character. For example, in the C language and in Java it is `char`.
+In some languages, there is a special "character" type for a single character. For example, in the C language and in Java it is called "char".
In JavaScript, there is no such type. There's only one type: `string`. A string may consist of only one character or many of them.
```
-## A boolean (logical type)
+## Boolean (logical type)
The boolean type has only two values: `true` and `false`.
@@ -198,6 +217,8 @@ typeof undefined // "undefined"
typeof 0 // "number"
+typeof 10n // "bigint"
+
typeof true // "boolean"
typeof "foo" // "string"
@@ -223,12 +244,12 @@ The last three lines may need additional explanation:
2. The result of `typeof null` is `"object"`. That's wrong. It is an officially recognized error in `typeof`, kept for compatibility. Of course, `null` is not an object. It is a special value with a separate type of its own. So, again, this is an error in the language.
3. The result of `typeof alert` is `"function"`, because `alert` is a function. We'll study functions in the next chapters where we'll also see that there's no special "function" type in JavaScript. Functions belong to the object type. But `typeof` treats them differently, returning `"function"`. That's not quite correct, but very convenient in practice.
-
## Summary
-There are 7 basic data types in JavaScript.
+There are 8 basic data types in JavaScript.
-- `number` for numbers of any kind: integer or floating-point.
+- `number` for numbers of any kind: integer or floating-point, integers are limited by ±253.
+- `bigint` is for integer numbers of arbitrary length.
- `string` for strings. A string may have one or more characters, there's no separate single-character type.
- `boolean` for `true`/`false`.
- `null` for unknown values -- a standalone type that has a single value `null`.
diff --git a/1-js/02-first-steps/06-type-conversions/article.md b/1-js/02-first-steps/06-type-conversions/article.md
index 20d093ea46..e7c381252f 100644
--- a/1-js/02-first-steps/06-type-conversions/article.md
+++ b/1-js/02-first-steps/06-type-conversions/article.md
@@ -1,6 +1,6 @@
# Type Conversions
-Most of the time, operators and functions automatically convert the values given to them to the right type.
+Most of the time, operators and functions automatically convert the values given to them to the right type.
For example, `alert` automatically converts any value to a string to show it. Mathematical operations convert values to numbers.
@@ -81,18 +81,7 @@ alert( Number(false) ); // 0
Please note that `null` and `undefined` behave differently here: `null` becomes zero while `undefined` becomes `NaN`.
-````smart header="Addition '+' concatenates strings"
-Almost all mathematical operations convert values to numbers. A notable exception is addition `+`. If one of the added values is a string, the other one is also converted to a string.
-
-Then, it concatenates (joins) them:
-
-```js run
-alert( 1 + '2' ); // '12' (string to the right)
-alert( '1' + 2 ); // '12' (string to the left)
-```
-
-This only happens when at least one of the arguments is a string. Otherwise, values are converted to numbers.
-````
+Most mathematical operators also perform such conversion, we'll see that in the next chapter.
## Boolean Conversion
diff --git a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md b/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md
similarity index 100%
rename from 1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/solution.md
rename to 1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md
diff --git a/1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md b/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/task.md
similarity index 100%
rename from 1-js/02-first-steps/06-type-conversions/1-primitive-conversions-questions/task.md
rename to 1-js/02-first-steps/07-operators/3-primitive-conversions-questions/task.md
diff --git a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md b/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md
index 6437b512e8..a86a9f73ee 100644
--- a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md
+++ b/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md
@@ -13,7 +13,7 @@ null === +"\n0\n" → false
Some of the reasons:
1. Obviously, true.
-2. Dictionary comparison, hence false.
+2. Dictionary comparison, hence false. `"a"` is smaller than `"p"`.
3. Again, dictionary comparison, first char of `"2"` is greater than the first char of `"1"`.
4. Values `null` and `undefined` equal each other only.
5. Strict equality is strict. Different types from both sides lead to false.
diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg
index cbc8c78401..ca3e0aead0 100644
--- a/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg
+++ b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg
index 6f729fd3ae..1f7d21288c 100644
--- a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg
+++ b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg
index e9b28655fc..6fb4332f1d 100644
--- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg
+++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg
index 61f08d25c9..0d5bde9c41 100644
--- a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg
+++ b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/03-code-quality/02-coding-style/code-style.svg b/1-js/03-code-quality/02-coding-style/code-style.svg
index e8e374048d..bd62691c62 100644
--- a/1-js/03-code-quality/02-coding-style/code-style.svg
+++ b/1-js/03-code-quality/02-coding-style/code-style.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md
index b399fd4287..75db49d2f7 100644
--- a/1-js/03-code-quality/06-polyfills/article.md
+++ b/1-js/03-code-quality/06-polyfills/article.md
@@ -19,7 +19,7 @@ Here Babel comes to the rescue.
Actually, there are two parts in Babel:
-1. First, the transpiler program, which rewrites the code. The developer runs it on their own computer. It rewrites the code into the older standard. And then the code is delivered to the website for users. Modern project build systems like [webpack](http://webpack.github.io/) provide means to run transpiler automatically on every code change, so that very easy to integrate into development process.
+1. First, the transpiler program, which rewrites the code. The developer runs it on their own computer. It rewrites the code into the older standard. And then the code is delivered to the website for users. Modern project build systems like [webpack](http://webpack.github.io/) provide means to run transpiler automatically on every code change, so that it's very easy to integrate into development process.
2. Second, the polyfill.
diff --git a/1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg b/1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg
index 133b3908d3..2ae1f664cb 100644
--- a/1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg
+++ b/1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-family.svg b/1-js/04-object-basics/02-garbage-collection/family-no-family.svg
index 8ba3b9f9fd..655d1982e3 100644
--- a/1-js/04-object-basics/02-garbage-collection/family-no-family.svg
+++ b/1-js/04-object-basics/02-garbage-collection/family-no-family.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-father.svg b/1-js/04-object-basics/02-garbage-collection/family-no-father.svg
index 59f0b2afc0..b76c868e04 100644
--- a/1-js/04-object-basics/02-garbage-collection/family-no-father.svg
+++ b/1-js/04-object-basics/02-garbage-collection/family-no-father.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/family.svg b/1-js/04-object-basics/02-garbage-collection/family.svg
index 8fbbc35ea2..bec2f4ddcb 100644
--- a/1-js/04-object-basics/02-garbage-collection/family.svg
+++ b/1-js/04-object-basics/02-garbage-collection/family.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg
index 125031ee44..2563c8185a 100644
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg
+++ b/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg
index b4f1a08701..acd5025e9c 100644
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg
+++ b/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg
index 7477c4ba78..4421ec7846 100644
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg
+++ b/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg
index 6b13c1dc03..74adc81351 100644
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg
+++ b/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg
index 5cb54dc289..abb127ab23 100644
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg
+++ b/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md
index ea00c970d5..c1aaf4f973 100644
--- a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md
+++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md
@@ -22,6 +22,17 @@ The value of `this` is one for the whole function, code blocks and object litera
So `ref: this` actually takes current `this` of the function.
+We can rewrite the function and return the same `this` with `undefined` value:
+
+```js run
+function makeUser(){
+ return this; // this time there's no object literal
+}
+
+alert( makeUser().name ); // Error: Cannot read property 'name' of undefined
+```
+As you can see the result of `alert( makeUser().name )` is the same as the result of `alert( user.ref.name )` from the previous example.
+
Here's the opposite case:
```js run
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index f9ffdd81be..ad333c5ab0 100644
--- a/1-js/05-data-types/02-number/article.md
+++ b/1-js/05-data-types/02-number/article.md
@@ -1,8 +1,12 @@
# Numbers
-All numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), also known as "double precision floating point numbers".
+In modern JavaScript, there are two types of numbers:
-Let's expand upon what we currently know about them.
+1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter.
+
+2. BigInt numbers, to represent integers of arbitrary length. They are sometimes needed, because a regular number can't exceed 253 or be less than -253. As bigints are used in few special areas, we devote them a special chapter .
+
+So here we'll talk about regular numbers. Let's expand our knowledge of them.
## More ways to write a number
@@ -29,14 +33,13 @@ In other words, `"e"` multiplies the number by `1` with the given zeroes count.
1.23e6 = 1.23 * 1000000
```
-
Now let's write something very small. Say, 1 microsecond (one millionth of a second):
```js
let ms = 0.000001;
```
-Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could say:
+Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could say the same as:
```js
let ms = 1e-6; // six zeroes to the left from 1
@@ -271,13 +274,11 @@ JavaScript doesn't trigger an error in such events. It does its best to fit the
```smart header="Two zeroes"
Another funny consequence of the internal representation of numbers is the existence of two zeroes: `0` and `-0`.
-That's because a sign is represented by a single bit, so every number can be positive or negative, including a zero.
+That's because a sign is represented by a single bit, so it can be set or not set for any number including a zero.
In most cases the distinction is unnoticeable, because operators are suited to treat them as the same.
```
-
-
## Tests: isFinite and isNaN
Remember these two special numeric values?
@@ -409,10 +410,10 @@ There are more functions and constants in `Math` object, including trigonometry,
## Summary
-To write big numbers:
+To write numbers with many zeroes:
-- Append `"e"` with the zeroes count to the number. Like: `123e6` is `123` with 6 zeroes.
-- A negative number after `"e"` causes the number to be divided by 1 with given zeroes. That's for one-millionth or such.
+- Append `"e"` with the zeroes count to the number. Like: `123e6` is the same as `123` with 6 zeroes `123000000`.
+- A negative number after `"e"` causes the number to be divided by 1 with given zeroes. E.g. `123e-6` means `0.000123` (`123` millionth).
For different numeral systems:
diff --git a/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md b/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md
index 4c8af1f248..1606751852 100644
--- a/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md
+++ b/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md
@@ -36,7 +36,7 @@ Letter-sorting is done by the chain of calls in the line `(*)`.
For convenience let's split it into multiple lines:
```js
-let sorted = arr[i] // PAN
+let sorted = word // PAN
.toLowerCase() // pan
.split('') // ['p','a','n']
.sort() // ['a','n','p']
diff --git a/1-js/05-data-types/11-date/8-format-date-relative/solution.md b/1-js/05-data-types/11-date/8-format-date-relative/solution.md
index 2507c840c7..7186185284 100644
--- a/1-js/05-data-types/11-date/8-format-date-relative/solution.md
+++ b/1-js/05-data-types/11-date/8-format-date-relative/solution.md
@@ -62,6 +62,8 @@ function formatDate(date) {
year = year.toString().slice(-2);
month = month < 10 ? '0' + month : month;
dayOfMonth = dayOfMonth < 10 ? '0' + dayOfMonth : dayOfMonth;
+ hour = hour < 10 ? '0' + hour : hour;
+ minutes = minutes < 10 ? '0' + minutes : minutes;
if (diffSec < 1) {
return 'right now';
diff --git a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.svg b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.svg
index 28f0c9b135..59e6a52c41 100644
--- a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.svg
+++ b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/fibonacci-recursion-tree.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg
index 346c436a3f..edec239124 100644
--- a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg
+++ b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/01-recursion/recursion-pow.svg b/1-js/06-advanced-functions/01-recursion/recursion-pow.svg
index 910b2aa500..8bd4a43fef 100644
--- a/1-js/06-advanced-functions/01-recursion/recursion-pow.svg
+++ b/1-js/06-advanced-functions/01-recursion/recursion-pow.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/01-recursion/recursive-salaries.svg b/1-js/06-advanced-functions/01-recursion/recursive-salaries.svg
index 9a3296655b..f47f0668bc 100644
--- a/1-js/06-advanced-functions/01-recursion/recursive-salaries.svg
+++ b/1-js/06-advanced-functions/01-recursion/recursive-salaries.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/8-make-army/task.md b/1-js/06-advanced-functions/03-closure/8-make-army/task.md
index ede8fd0458..93e64f2d02 100644
--- a/1-js/06-advanced-functions/03-closure/8-make-army/task.md
+++ b/1-js/06-advanced-functions/03-closure/8-make-army/task.md
@@ -31,5 +31,5 @@ army[5](); // and number 5 also outputs 10...
// ... all shooters show 10 instead of their 0, 1, 2, 3...
```
-Why all shooters show the same? Fix the code so that they work as intended.
+Why do all of the shooters show the same value? Fix the code so that they work as intended.
diff --git a/1-js/06-advanced-functions/03-closure/lexenv-if.svg b/1-js/06-advanced-functions/03-closure/lexenv-if.svg
index 48dd7d1bf2..b644fe1541 100644
--- a/1-js/06-advanced-functions/03-closure/lexenv-if.svg
+++ b/1-js/06-advanced-functions/03-closure/lexenv-if.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg
index f70fb41f0d..66e5200f8f 100644
--- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg
+++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-2.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg
index 9a3298ca3e..28c526c4fe 100644
--- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg
+++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-3.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg
index 02d8a93fb4..acc1e8fb98 100644
--- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg
+++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-4.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg
index 6c8f66495b..cf91c331d9 100644
--- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg
+++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-5.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg
index 3b0ac9d0c7..def542cebf 100644
--- a/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg
+++ b/1-js/06-advanced-functions/03-closure/lexenv-nested-makecounter-6.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg
index 40e2b92ad6..1ad0ab6c34 100644
--- a/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg
+++ b/1-js/06-advanced-functions/03-closure/lexical-environment-simple-lookup.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg b/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg
index a962f0e5f7..179ce75d2e 100644
--- a/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg
+++ b/1-js/06-advanced-functions/03-closure/lexical-environment-simple.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/lexical-search-order.svg b/1-js/06-advanced-functions/03-closure/lexical-search-order.svg
index 44db4b0c10..89a9d110a7 100644
--- a/1-js/06-advanced-functions/03-closure/lexical-search-order.svg
+++ b/1-js/06-advanced-functions/03-closure/lexical-search-order.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/article.md b/1-js/06-advanced-functions/09-call-apply-decorators/article.md
index 373500e13b..7d43c0be3b 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/article.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/article.md
@@ -149,8 +149,8 @@ let user = { name: "John" };
let admin = { name: "Admin" };
// use call to pass different objects as "this"
-sayHi.call( user ); // this = John
-sayHi.call( admin ); // this = Admin
+sayHi.call( user ); // John
+sayHi.call( admin ); // Admin
```
And here we use `call` to call `say` with the given context and phrase:
diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md
index 16a50942d5..ff60e559f5 100644
--- a/1-js/06-advanced-functions/10-bind/article.md
+++ b/1-js/06-advanced-functions/10-bind/article.md
@@ -279,7 +279,7 @@ What if we'd like to fix some arguments, but not the context `this`? For example
The native `bind` does not allow that. We can't just omit the context and jump to arguments.
-Fortunately, a helper function `partial` for binding only arguments can be easily implemented.
+Fortunately, a function `partial` for binding only arguments can be easily implemented.
Like this:
diff --git a/1-js/07-object-properties/01-property-descriptors/article.md b/1-js/07-object-properties/01-property-descriptors/article.md
index e894f0662d..3593bffae5 100644
--- a/1-js/07-object-properties/01-property-descriptors/article.md
+++ b/1-js/07-object-properties/01-property-descriptors/article.md
@@ -66,7 +66,7 @@ Object.defineProperty(obj, propertyName, descriptor)
: The object and its property to apply the descriptor.
`descriptor`
-: Property descriptor to apply.
+: Property descriptor object to apply.
If the property exists, `defineProperty` updates its flags. Otherwise, it creates the property with the given value and flags; in that case, if a flag is not supplied, it is assumed `false`.
diff --git a/1-js/07-object-properties/02-property-accessors/article.md b/1-js/07-object-properties/02-property-accessors/article.md
index 726529c5b2..52c1528110 100644
--- a/1-js/07-object-properties/02-property-accessors/article.md
+++ b/1-js/07-object-properties/02-property-accessors/article.md
@@ -94,11 +94,7 @@ alert(user.name); // Alice
alert(user.surname); // Cooper
```
-As the result, we have a "virtual" property `fullName`. It is readable and writable, but in fact does not exist.
-
-```smart header="No way to handle `delete`"
-There's no similar method to handle deletion of an accessor property. Only getter/setter methods may exist.
-```
+As the result, we have a "virtual" property `fullName`. It is readable and writable.
## Accessor descriptors
diff --git a/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg b/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg
index caa5ec04b3..36cc81cd9d 100644
--- a/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg
+++ b/1-js/08-prototypes/03-native-prototypes/native-prototypes-classes.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg b/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg
index 2f994f7b73..3471904ab9 100644
--- a/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg
+++ b/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg b/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg
index 8ad09f484d..f13d441c92 100644
--- a/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg
+++ b/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/06-instanceof/instanceof.svg b/1-js/09-classes/06-instanceof/instanceof.svg
index 8b63f20709..78bff9f12f 100644
--- a/1-js/09-classes/06-instanceof/instanceof.svg
+++ b/1-js/09-classes/06-instanceof/instanceof.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/10-error-handling/1-try-catch/article.md b/1-js/10-error-handling/1-try-catch/article.md
index 09b1ee398a..149a95f1f2 100644
--- a/1-js/10-error-handling/1-try-catch/article.md
+++ b/1-js/10-error-handling/1-try-catch/article.md
@@ -298,7 +298,7 @@ try {
*!*
alert(e.name); // SyntaxError
*/!*
- alert(e.message); // Unexpected token o in JSON at position 2
+ alert(e.message); // Unexpected token b in JSON at position 2
}
```
diff --git a/1-js/10-error-handling/1-try-catch/try-catch-flow.svg b/1-js/10-error-handling/1-try-catch/try-catch-flow.svg
index ab17dcda04..ac816e356b 100644
--- a/1-js/10-error-handling/1-try-catch/try-catch-flow.svg
+++ b/1-js/10-error-handling/1-try-catch/try-catch-flow.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/11-async/01-callbacks/article.md b/1-js/11-async/01-callbacks/article.md
index daab933168..5860410025 100644
--- a/1-js/11-async/01-callbacks/article.md
+++ b/1-js/11-async/01-callbacks/article.md
@@ -2,10 +2,12 @@
# Introduction: callbacks
-```warn header="We use browser methods here"
-To demonstrate the use of callbacks, promises and other abstract concepts, we'll be using some browser methods; specifically, loading scripts and performing simple document manipulations.
+```warn header="We use browser methods in examples here"
+To demonstrate the use of callbacks, promises and other abstract concepts, we'll be using some browser methods — specifically, loading scripts and performing simple document manipulations.
-If you're not familiar with these methods, and their usage in the examples is confusing, or if you would just like to understand them better, you may want to read a few chapters from the [next part](/document) of the tutorial.
+If you're not familiar with these methods, and their usage in the examples is confusing, you may want to read a few chapters from the [next part](/document) of the tutorial.
+
+Although, we'll try to make things clear anyway. There won't be anything really complex browser-wise.
```
Many actions in JavaScript are *asynchronous*. In other words, we initiate them now, but they finish later.
@@ -14,17 +16,19 @@ For instance, we can schedule such actions using `setTimeout`.
There are other real-world examples of asynchronous actions, e.g. loading scripts and modules (we'll cover them in later chapters).
-Take a look at the function `loadScript(src)`, that loads a script with the given `src`:
+Take a look at the function `loadScript(src)` that loads a script with the given `src`:
```js
function loadScript(src) {
+ // creates a
-w3.org
+w3.org
```
Also we can use `event.preventDefault()`, like this:
@@ -35,5 +35,5 @@ Also we can use `event.preventDefault()`, like this:
*/!*
-w3.org
+w3.org
```
diff --git a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md
index 8fa4fb29a9..9a5bb98ac8 100644
--- a/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md
+++ b/2-ui/2-events/04-default-browser-action/1-why-return-false-fails/task.md
@@ -14,7 +14,7 @@ Why in the code below `return false` doesn't work at all?
}
-the browser will go to w3.org
+the browser will go to w3.org
```
The browser follows the URL on click, but we don't want it.
diff --git a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.view/index.html b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.view/index.html
index 90aecd9dc7..51ac0838be 100644
--- a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.view/index.html
+++ b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/solution.view/index.html
@@ -16,7 +16,7 @@
diff --git a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/source.view/index.html b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/source.view/index.html
index b88834c96f..f0c9343919 100644
--- a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/source.view/index.html
+++ b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/source.view/index.html
@@ -16,7 +16,7 @@
diff --git a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md
index 6439376bf8..6ca456c2c3 100644
--- a/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md
+++ b/2-ui/2-events/04-default-browser-action/2-catch-link-navigation/task.md
@@ -12,5 +12,5 @@ Like this:
Details:
-- HTML inside the element may be loaded or regenerated dynamically at any time, so we can't find all links and put handlers on them. Use the event delegation.
+- HTML inside the element may be loaded or regenerated dynamically at any time, so we can't find all links and put handlers on them. Use event delegation.
- The content may have nested tags. Inside links too, like `...`.
diff --git a/2-ui/2-events/04-default-browser-action/article.md b/2-ui/2-events/04-default-browser-action/article.md
index 0a0131a1c6..8bb2ffc6ab 100644
--- a/2-ui/2-events/04-default-browser-action/article.md
+++ b/2-ui/2-events/04-default-browser-action/article.md
@@ -8,7 +8,7 @@ For instance:
- A click on a form submit button - initiates its submission to the server.
- Pressing a mouse button over a text and moving it - selects the text.
-If we handle an event in JavaScript, we may not want the corresponding browser action to happen, to implement another behavior instead.
+If we handle an event in JavaScript, we may not want the corresponding browser action to happen, and want to implement another behavior instead.
## Preventing browser actions
@@ -207,7 +207,7 @@ As we can clearly see, `event.stopPropagation()` and `event.preventDefault()` (a
```
```smart header="Nested context menus architecture"
-There are also alternative ways to implement nested context menus. One of them is to have a single global object with a handler for `document.oncontextmenu`, and also methods that allow to store other handlers in it.
+There are also alternative ways to implement nested context menus. One of them is to have a single global object with a handler for `document.oncontextmenu`, and also methods that allow us to store other handlers in it.
The object will catch any right-click, look through stored handlers and run the appropriate one.
@@ -240,5 +240,5 @@ But we should generally keep the semantic meaning of HTML elements. For instance
Besides being "just a good thing", that makes your HTML better in terms of accessibility.
-Also if we consider the example with ``, then please note: a browser allows to open such links in a new window (by right-clicking them and other means). And people like that. But if we make a button behave as a link using JavaScript and even look like a link using CSS, then ``-specific browser features still won't work for it.
+Also if we consider the example with ``, then please note: a browser allows us to open such links in a new window (by right-clicking them and other means). And people like that. But if we make a button behave as a link using JavaScript and even look like a link using CSS, then ``-specific browser features still won't work for it.
```
diff --git a/2-ui/2-events/05-dispatch-events/article.md b/2-ui/2-events/05-dispatch-events/article.md
index 771f5527bd..ad9092fd86 100644
--- a/2-ui/2-events/05-dispatch-events/article.md
+++ b/2-ui/2-events/05-dispatch-events/article.md
@@ -211,7 +211,7 @@ Please note: the event must have the flag `cancelable: true`, otherwise the call
## Events-in-events are synchronous
-Usually events are processed asynchronously. That is: if the browser is processing `onclick` and in the process a new event occurs, then it awaits till `onclick` processing is finished.
+Usually events are processed asynchronously. That is: if the browser is processing `onclick` and in the process a new event occurs, then it waits until the `onclick` processing is finished.
The exception is when one event is initiated from within another one.
diff --git a/2-ui/3-event-details/1-mouse-events-basics/article.md b/2-ui/3-event-details/1-mouse-events-basics/article.md
index 412c40073e..42f4b6f50a 100644
--- a/2-ui/3-event-details/1-mouse-events-basics/article.md
+++ b/2-ui/3-event-details/1-mouse-events-basics/article.md
@@ -47,7 +47,7 @@ In cases when a single action initiates multiple events, their order is fixed. T
```online
Click the button below and you'll see the events. Try double-click too.
-On the teststand below all mouse events are logged, and if there are more than 1 second delay between them, then they are separated by a horizontal ruler.
+On the teststand below all mouse events are logged, and if there is more than a 1 second delay between them they are separated by a horizontal ruler.
Also we can see the `which` property that allows to detect the mouse button.
@@ -110,7 +110,7 @@ So if we want to support combinations like `key:Ctrl`+click, then for Mac it mak
Even if we'd like to force Mac users to `key:Ctrl`+click -- that's kind of difficult. The problem is: a left-click with `key:Ctrl` is interpreted as a *right-click* on MacOS, and it generates the `contextmenu` event, not `click` like Windows/Linux.
-So if we want users of all operational systems to feel comfortable, then together with `ctrlKey` we should check `metaKey`.
+So if we want users of all operating systems to feel comfortable, then together with `ctrlKey` we should check `metaKey`.
For JS-code it means that we should check `if (event.ctrlKey || event.metaKey)`.
```
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/index.html b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/index.html
index df0f136568..0982321741 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/index.html
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/index.html
@@ -20,20 +20,17 @@
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/test.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/test.js
index 7c7f6d23df..f5d4aaffb3 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/test.js
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/test.js
@@ -49,18 +49,18 @@ describe("hoverIntent", function() {
}
})
- it("mouseover -> immediately no tooltip", function() {
+ it("mouseover -> when the pointer just arrived, no tooltip", function() {
mouse('mouseover', 10, 10);
assert.isFalse(isOver);
});
- it("mouseover -> pause shows tooltip", function() {
+ it("mouseover -> after a delay, the tooltip shows up", function() {
mouse('mouseover', 10, 10);
this.clock.tick(100);
assert.isTrue(isOver);
});
- it("mouseover -> fast mouseout no tooltip", function() {
+ it("mouseover -> followed by fast mouseout leads doesn't show tooltip", function() {
mouse('mouseover', 10, 10);
setTimeout(
() => mouse('mouseout', 300, 300, { relatedTarget: document.body}),
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js
index caca940b1d..a38b42bc24 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/hoverIntent.js
@@ -45,6 +45,7 @@ class HoverIntent {
destroy() {
/* your code to "disable" the functionality, remove all handlers */
+ /* it's needed for the tests to work */
}
}
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/index.html b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/index.html
index 856daf3a8f..0982321741 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/index.html
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/index.html
@@ -3,10 +3,9 @@
-
Document
-
+
@@ -21,18 +20,17 @@
Tooltip
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/style.css b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/style.css
index 980e9457e7..fa2f09eba8 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/style.css
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/style.css
@@ -2,6 +2,10 @@
color: red;
}
+body {
+ margin: 0;
+}
+
.minutes {
color: green;
}
@@ -20,9 +24,15 @@
top: 0;
}
-.tooltip {
+#tooltip {
position: absolute;
- background: #eee;
- border: 1px brown solid;
- padding: 3px;
+ padding: 10px 20px;
+ border: 1px solid #b3c9ce;
+ border-radius: 4px;
+ text-align: center;
+ font: italic 14px/1.3 sans-serif;
+ color: #333;
+ background: #fff;
+ z-index: 100000;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, .3);
}
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/test.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/test.js
index 44369d8c3f..f5d4aaffb3 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/test.js
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/source.view/test.js
@@ -3,7 +3,7 @@
describe("hoverIntent", function() {
function mouse(eventType, x, y, options) {
- let eventOptions = Object.assign({
+ let eventOptions = Object.assign({
bubbles: true,
clientX: x,
clientY: y,
@@ -11,15 +11,15 @@ describe("hoverIntent", function() {
pageY: y,
target: elem
}, options || {});
-
+
elem.dispatchEvent(new MouseEvent(eventType, eventOptions));
}
let isOver;
let hoverIntent;
-
-
+
+
before(function() {
this.clock = sinon.useFakeTimers();
});
@@ -27,11 +27,11 @@ describe("hoverIntent", function() {
after(function() {
this.clock.restore();
});
-
-
+
+
beforeEach(function() {
isOver = false;
-
+
hoverIntent = new HoverIntent({
elem: elem,
over: function() {
@@ -49,18 +49,18 @@ describe("hoverIntent", function() {
}
})
- it("mouseover -> immediately no tooltip", function() {
+ it("mouseover -> when the pointer just arrived, no tooltip", function() {
mouse('mouseover', 10, 10);
assert.isFalse(isOver);
});
-
- it("mouseover -> pause shows tooltip", function() {
+
+ it("mouseover -> after a delay, the tooltip shows up", function() {
mouse('mouseover', 10, 10);
this.clock.tick(100);
assert.isTrue(isOver);
});
- it("mouseover -> fast mouseout no tooltip", function() {
+ it("mouseover -> followed by fast mouseout leads doesn't show tooltip", function() {
mouse('mouseover', 10, 10);
setTimeout(
() => mouse('mouseout', 300, 300, { relatedTarget: document.body}),
@@ -94,5 +94,5 @@ describe("hoverIntent", function() {
this.clock.tick(200);
assert.isFalse(isOver);
});
-
+
});
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md
index be6090aef2..cbabd2f4b6 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md
@@ -145,7 +145,7 @@ When the pointer leaves an element -- `mouseleave` triggers.
```online
This example is similar to the one above, but now the top element has `mouseenter/mouseleave` instead of `mouseover/mouseout`.
-As you can see, the only generated events are the ones related to moving the pointer in and out of the top element. Nothing happens when the pointer goes to the child and back. Transitions between descendants are ignores
+As you can see, the only generated events are the ones related to moving the pointer in and out of the top element. Nothing happens when the pointer goes to the child and back. Transitions between descendants are ignored
[codetabs height=340 src="https://github.com/mouseleave"]
```
diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg
index f5562f97a9..ca8bbc3bd2 100644
--- a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg
+++ b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/field.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.js b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.js
index 1c1443a7e7..10ae2eeed0 100644
--- a/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.js
+++ b/2-ui/3-event-details/4-mouse-drag-and-drop/2-drag-heroes/solution.view/soccer.js
@@ -7,7 +7,7 @@ document.addEventListener('mousedown', function(event) {
if (!dragElement) return;
event.preventDefault();
-
+
dragElement.ondragstart = function() {
return false;
};
@@ -19,7 +19,7 @@ document.addEventListener('mousedown', function(event) {
function onMouseUp(event) {
finishDrag();
};
-
+
function onMouseMove(event) {
moveAt(event.clientX, event.clientY);
}
@@ -31,9 +31,9 @@ document.addEventListener('mousedown', function(event) {
if(isDragging) {
return;
}
-
+
isDragging = true;
-
+
document.addEventListener('mousemove', onMouseMove);
element.addEventListener('mouseup', onMouseUp);
@@ -50,10 +50,10 @@ document.addEventListener('mousedown', function(event) {
if(!isDragging) {
return;
}
-
+
isDragging = false;
- dragElement.style.top = parseInt(dragElement.style.top) + pageYOffset + 'px';
+ dragElement.style.top = parseInt(dragElement.style.top) + window.pageYOffset + 'px';
dragElement.style.position = 'absolute';
document.removeEventListener('mousemove', onMouseMove);
@@ -113,4 +113,4 @@ document.addEventListener('mousedown', function(event) {
dragElement.style.top = newY + 'px';
}
-});
\ No newline at end of file
+});
diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md
index 2418ffd66f..b74c13f1e2 100644
--- a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md
+++ b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md
@@ -1,12 +1,12 @@
# Drag'n'Drop with mouse events
-Drag'n'Drop is a great interface solution. Taking something, dragging and dropping is a clear and simple way to do many things, from copying and moving documents (as in file managers) to ordering (drop into cart).
+Drag'n'Drop is a great interface solution. Taking something and dragging and dropping it is a clear and simple way to do many things, from copying and moving documents (as in file managers) to ordering (dropping items into a cart).
-In the modern HTML standard there's a [section about Drag and Drop](https://html.spec.whatwg.org/multipage/interaction.html#dnd) with special events such as `dragstart`, `dragend` and so on.
+In the modern HTML standard there's a [section about Drag and Drop](https://html.spec.whatwg.org/multipage/interaction.html#dnd) with special events such as `dragstart`, `dragend`, and so on.
-They are interesting because they allow to solve simple tasks easily, and also allow to handle drag'n'drop of "external" files into the browser. So we can take a file in the OS file-manager and drop it into the browser window. Then JavaScript gains access to its contents.
+These events are useful in that they allow us to solve simple tasks easily. For instance, they allow us to handle the drag'n'drop of "external" files into the browser, so we can take a file in the OS file-manager and drop it into the browser window, thereby giving JavaScript access to its contents.
-But native Drag Events also have limitations. For instance, we can't limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. There are other drag'n'drop tasks that can't be done using that API. Besides, mobile devices support for such events is almost non-existant.
+But native Drag Events also have limitations. For instance, we can't limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. And there are other drag'n'drop tasks that can't be done using that API. Also, mobile device support for such events is almost non-existant.
So here we'll see how to implement Drag'n'Drop using mouse events.
@@ -124,7 +124,7 @@ Let's update our algorithm:
```js
// onmousemove
- // у мяча ball стоит position:absoute
+ // ball has position:absoute
ball.style.left = event.pageX - *!*shiftX*/!* + 'px';
ball.style.top = event.pageY - *!*shiftY*/!* + 'px';
```
diff --git a/2-ui/3-event-details/5-keyboard-events/german-layout.svg b/2-ui/3-event-details/5-keyboard-events/german-layout.svg
index d107c22400..8a880e8e03 100644
--- a/2-ui/3-event-details/5-keyboard-events/german-layout.svg
+++ b/2-ui/3-event-details/5-keyboard-events/german-layout.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/3-event-details/8-onscroll/3-load-visible-img/source.view/index.html b/2-ui/3-event-details/8-onscroll/3-load-visible-img/source.view/index.html
index 5c6027a6f8..9953ace660 100644
--- a/2-ui/3-event-details/8-onscroll/3-load-visible-img/source.view/index.html
+++ b/2-ui/3-event-details/8-onscroll/3-load-visible-img/source.view/index.html
@@ -169,38 +169,8 @@
Neptune
* It's enough that the top or bottom edge of the element are visible
*/
function isVisible(elem) {
-
- let coords = elem.getBoundingClientRect();
-
- let windowHeight = document.documentElement.clientHeight;
-
- // top elem edge is visible OR bottom elem edge is visible
- let topVisible = coords.top > 0 && coords.top < windowHeight;
- let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;
-
- return topVisible || bottomVisible;
- }
-
- /**
- A variant of the test that considers the element visible if it's no more than
- one page after/behind the current screen.
-
- function isVisible(elem) {
-
- let coords = elem.getBoundingClientRect();
-
- let windowHeight = document.documentElement.clientHeight;
-
- let extendedTop = -windowHeight;
- let extendedBottom = 2 * windowHeight;
-
- // top visible || bottom visible
- let topVisible = coords.top > extendedTop && coords.top < extendedBottom;
- let bottomVisible = coords.bottom < extendedBottom && coords.bottom > extendedTop;
-
- return topVisible || bottomVisible;
+ // todo: your code
}
- */
function showVisible() {
for (let img of document.querySelectorAll('img')) {
diff --git a/2-ui/3-event-details/8-onscroll/article.md b/2-ui/3-event-details/8-onscroll/article.md
index 22ff8d8599..7b5cf48484 100644
--- a/2-ui/3-event-details/8-onscroll/article.md
+++ b/2-ui/3-event-details/8-onscroll/article.md
@@ -10,7 +10,7 @@ Here's a small function to show the current scroll:
```js autorun
window.addEventListener('scroll', function() {
- document.getElementById('showScroll').innerHTML = pageYOffset + 'px';
+ document.getElementById('showScroll').innerHTML = window.pageYOffset + 'px';
});
```
diff --git a/2-ui/4-forms-controls/1-form-elements/1-add-select-option/task.md b/2-ui/4-forms-controls/1-form-elements/1-add-select-option/task.md
index 9b218aa7f7..a0e74da576 100644
--- a/2-ui/4-forms-controls/1-form-elements/1-add-select-option/task.md
+++ b/2-ui/4-forms-controls/1-form-elements/1-add-select-option/task.md
@@ -18,3 +18,5 @@ Use JavaScript to:
1. Show the value and the text of the selected option.
2. Add an option: ``.
3. Make it selected.
+
+Note, if you've done everything right, your alert should show `blues`.
diff --git a/2-ui/4-forms-controls/1-form-elements/form-navigation.svg b/2-ui/4-forms-controls/1-form-elements/form-navigation.svg
index 113e7da552..b112e250a2 100644
--- a/2-ui/4-forms-controls/1-form-elements/form-navigation.svg
+++ b/2-ui/4-forms-controls/1-form-elements/form-navigation.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/4-forms-controls/2-focus-blur/article.md b/2-ui/4-forms-controls/2-focus-blur/article.md
index 6a605bc018..d42013e5b5 100644
--- a/2-ui/4-forms-controls/2-focus-blur/article.md
+++ b/2-ui/4-forms-controls/2-focus-blur/article.md
@@ -49,7 +49,7 @@ Your email please:
```
-Modern HTML allows to do many validations using input attributes: `required`, `pattern` and so on. And sometimes they are just what we need. JavaScript can be used when we want more flexibility. Also we could automatically send the changed value to the server if it's correct.
+Modern HTML allows us to do many validations using input attributes: `required`, `pattern` and so on. And sometimes they are just what we need. JavaScript can be used when we want more flexibility. Also we could automatically send the changed value to the server if it's correct.
## Methods focus/blur
diff --git a/2-ui/99-ui-misc/01-mutation-observer/article.md b/2-ui/99-ui-misc/01-mutation-observer/article.md
index 4cbff3ea8c..6a458fa02f 100644
--- a/2-ui/99-ui-misc/01-mutation-observer/article.md
+++ b/2-ui/99-ui-misc/01-mutation-observer/article.md
@@ -3,7 +3,7 @@
`MutationObserver` is a built-in object that observes a DOM element and fires a callback in case of changes.
-We'll first take a look at the syntax, and then explore a real-world use case.
+We'll first take a look at the syntax, and then explore a real-world use case, to see where such thing may be useful.
## Syntax
@@ -65,7 +65,7 @@ observer.observe(elem, {
```
-Now if we change the text inside `edit`, we'll get a single mutation:
+If we run this code in the browser, then focus on the given `
` and change the text inside `edit`, `console.log` will show one mutation:
```js
mutationRecords = [{
@@ -76,7 +76,7 @@ mutationRecords = [{
}];
```
-If we select and remove the `edit` altogether, we'll get multiple mutations:
+If we make more complex editing operations, e.g. remove the `edit`, the mutation event may contain multiple mutation records:
```js
mutationRecords = [{
@@ -101,15 +101,15 @@ So, `MutationObserver` allows to react on any changes within DOM subtree.
When such thing may be useful?
-Imagine the situation when you attach a third-party script that adds useful functionality on the page, but also does something unwanted, e.g. shows ads `
Unwanted ads
`.
+Imagine the situation when you need to add a third-party script that contains useful functionality, but also does something unwanted, e.g. shows ads `
Unwanted ads
`.
Naturally, the third-party script provides no mechanisms to remove it.
-Using `MutationObserver`, we can detect when such element appears in our DOM and remove it. While leaving the useful functionality intact. Surely though, creators of that script won't be happy that you took their useful stuff and removed the ads.
+Using `MutationObserver`, we can detect when the unwanted element appears in our DOM and remove it.
There are other situations when a third-party script adds something into our document, and we'd like to detect, when it happens, to adapt our page, dynamically resize something etc.
-`MutationObserver` can easily handle this.
+`MutationObserver` allows to implement this.
## Usage for architecture
@@ -213,7 +213,7 @@ Please run the previous code (above, observes that element), and then the code b
A demo-element with id="highlight-demo", run the code above to observe it.
-The following code populates its `innerHTML`. Please run the code above first, it will watch and highlight the new content:
+The following code populates its `innerHTML`, that causes the `MutationObserver` to react and highlight its contents:
```js run
let demoElem = document.getElementById('highlight-demo');
@@ -236,22 +236,26 @@ There's a method to stop observing the node:
- `observer.disconnect()` -- stops the observation.
-Another method often used with it:
+When we stop the observing, it might be possible that some changes were not processed by the observer yet.
-- `mutationRecords = observer.takeRecords()` -- gets a list of unprocessed mutation records, those that happened, but the callback did not handle them.
+- `observer.takeRecords()` -- gets a list of unprocessed mutation records, those that happened, but the callback did not handle them.
+
+These methods can be used together, like this:
```js
// we'd like to stop tracking changes
observer.disconnect();
-// it might have not yet handled some mutations
+// handle unprocessed some mutations
let mutationRecords = observer.takeRecords();
-// process mutationRecords
+...
```
-## Garbage collection
+```smart header="Garbage collection interaction"
+Observers use weak references to nodes internally. That is: if a node is removed from DOM, and becomes unreachable, then it becomes garbage collected.
-Observers use weak references to nodes internally. That is: if a node is removed from DOM, and becomes unreachable, then it becomes garbage collected, an observer doesn't prevent that.
+The mere fact that a DOM node is observed doesn't prevent the garbage collection.
+```
## Summary
diff --git a/2-ui/99-ui-misc/02-selection-range/article.md b/2-ui/99-ui-misc/02-selection-range/article.md
index d6c8762c1f..862975dc14 100644
--- a/2-ui/99-ui-misc/02-selection-range/article.md
+++ b/2-ui/99-ui-misc/02-selection-range/article.md
@@ -428,7 +428,7 @@ Form elements, such as `input` and `textarea` provide [special API for selection
Properties:
- `input.selectionStart` -- position of selection start (writeable),
-- `input.selectionEnd` -- position of selection start (writeable),
+- `input.selectionEnd` -- position of selection end (writeable),
- `input.selectionDirection` -- selection direction, one of: "forward", "backward" or "none" (if e.g. selected with a double mouse click),
Events:
diff --git a/2-ui/99-ui-misc/02-selection-range/range-example-p-2-b-3-range.svg b/2-ui/99-ui-misc/02-selection-range/range-example-p-2-b-3-range.svg
index cb21d022c6..66397f20f9 100644
--- a/2-ui/99-ui-misc/02-selection-range/range-example-p-2-b-3-range.svg
+++ b/2-ui/99-ui-misc/02-selection-range/range-example-p-2-b-3-range.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/99-ui-misc/02-selection-range/selection-firefox.svg b/2-ui/99-ui-misc/02-selection-range/selection-firefox.svg
index 8ce5b47c71..879e1cecb6 100644
--- a/2-ui/99-ui-misc/02-selection-range/selection-firefox.svg
+++ b/2-ui/99-ui-misc/02-selection-range/selection-firefox.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/99-ui-misc/03-event-loop/eventLoop-full.svg b/2-ui/99-ui-misc/03-event-loop/eventLoop-full.svg
index 044bab6f34..9e4691404b 100644
--- a/2-ui/99-ui-misc/03-event-loop/eventLoop-full.svg
+++ b/2-ui/99-ui-misc/03-event-loop/eventLoop-full.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/99-ui-misc/03-event-loop/eventLoop.svg b/2-ui/99-ui-misc/03-event-loop/eventLoop.svg
index 57f5188ce9..f7de0b6ad1 100644
--- a/2-ui/99-ui-misc/03-event-loop/eventLoop.svg
+++ b/2-ui/99-ui-misc/03-event-loop/eventLoop.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/5-network/02-formdata/article.md b/5-network/02-formdata/article.md
index fb028f5c86..1c28296d29 100644
--- a/5-network/02-formdata/article.md
+++ b/5-network/02-formdata/article.md
@@ -54,14 +54,14 @@ In this example, the server code is not presented, as it's beyound our scope. Th
We can modify fields in `FormData` with methods:
- `formData.append(name, value)` - add a form field with the given `name` and `value`,
-- `formData.append(name, blob, fileName)` - add a field as if it were ``, the third argument `fileName` sets file name (not form field name), as it it were a name of the file in user's filesystem,
+- `formData.append(name, blob, fileName)` - add a field as if it were ``, the third argument `fileName` sets file name (not form field name), as it were a name of the file in user's filesystem,
- `formData.delete(name)` - remove the field with the given `name`,
- `formData.get(name)` - get the value of the field with the given `name`,
- `formData.has(name)` - if there exists a field with the given `name`, returns `true`, otherwise `false`
A form is technically allowed to have many fields with the same `name`, so multiple calls to `append` add more same-named fields.
-There's also method `set`, with the same syntax as `append`. The difference is that `.set` removes all fields with the given `name`, and then appends a new field. So it makes sure there's only field with such `name`, the rest is just like `append`:
+There's also method `set`, with the same syntax as `append`. The difference is that `.set` removes all fields with the given `name`, and then appends a new field. So it makes sure there's only one field with such `name`, the rest is just like `append`:
- `formData.set(name, value)`,
- `formData.set(name, blob, fileName)`.
diff --git a/5-network/05-fetch-crossorigin/cors-gmail-messages.svg b/5-network/05-fetch-crossorigin/cors-gmail-messages.svg
index 48dc029307..8b6963345d 100644
--- a/5-network/05-fetch-crossorigin/cors-gmail-messages.svg
+++ b/5-network/05-fetch-crossorigin/cors-gmail-messages.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/5-network/10-long-polling/long-polling.svg b/5-network/10-long-polling/long-polling.svg
index a2fd05b5de..bac56f1142 100644
--- a/5-network/10-long-polling/long-polling.svg
+++ b/5-network/10-long-polling/long-polling.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/5-network/11-websocket/article.md b/5-network/11-websocket/article.md
index 4eaf47ed2f..eab41b18ff 100644
--- a/5-network/11-websocket/article.md
+++ b/5-network/11-websocket/article.md
@@ -119,9 +119,9 @@ For instance:
- `Sec-WebSocket-Extensions: deflate-frame` means that the browser supports data compression. An extension is something related to transferring the data, functionality that extends WebSocket protocol. The header `Sec-WebSocket-Extensions` is sent automatically by the browser, with the list of all extenions it supports.
-- `Sec-WebSocket-Protocol: soap, wamp` means that we'd like to transfer not just any data, but the data in [SOAP](http://en.wikipedia.org/wiki/SOAP) or WAMP ("The WebSocket Application Messaging Protocol") protocols. WebSocket subprotocols are registered in the [IANA catalogue](http://www.iana.org/assignments/websocket/websocket.xml).
+- `Sec-WebSocket-Protocol: soap, wamp` means that we'd like to transfer not just any data, but the data in [SOAP](http://en.wikipedia.org/wiki/SOAP) or WAMP ("The WebSocket Application Messaging Protocol") protocols. WebSocket subprotocols are registered in the [IANA catalogue](http://www.iana.org/assignments/websocket/websocket.xml). So, this header describes data formats that we're going to use.
- This optional header is set by us, to tell the server which subprotocols our code supports, using the second (optional) parameter of `new WebSocket`. That's the array of subprotocols, e.g. if we'd like to use SOAP or WAMP:
+ This optional header is set using the second parameter of `new WebSocket`. That's the array of subprotocols, e.g. if we'd like to use SOAP or WAMP:
```js
let socket = new WebSocket("wss://javascript.info/chat", ["soap", "wamp"]);
diff --git a/6-data-storage/01-cookie/cookie-third-party-2.svg b/6-data-storage/01-cookie/cookie-third-party-2.svg
index 373e195d9c..94003610a4 100644
--- a/6-data-storage/01-cookie/cookie-third-party-2.svg
+++ b/6-data-storage/01-cookie/cookie-third-party-2.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/6-data-storage/01-cookie/cookie-third-party-3.svg b/6-data-storage/01-cookie/cookie-third-party-3.svg
index 76356a2d07..a67f09c7fd 100644
--- a/6-data-storage/01-cookie/cookie-third-party-3.svg
+++ b/6-data-storage/01-cookie/cookie-third-party-3.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/6-data-storage/01-cookie/cookie-third-party.svg b/6-data-storage/01-cookie/cookie-third-party.svg
index 4a512a4987..567f25595d 100644
--- a/6-data-storage/01-cookie/cookie-third-party.svg
+++ b/6-data-storage/01-cookie/cookie-third-party.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/6-data-storage/01-cookie/cookie-xsrf.svg b/6-data-storage/01-cookie/cookie-xsrf.svg
index 88843043e5..968b42d5b4 100644
--- a/6-data-storage/01-cookie/cookie-xsrf.svg
+++ b/6-data-storage/01-cookie/cookie-xsrf.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/6-data-storage/03-indexeddb/indexeddb-index.svg b/6-data-storage/03-indexeddb/indexeddb-index.svg
index de4e7fa02e..9bee3ef814 100644
--- a/6-data-storage/03-indexeddb/indexeddb-index.svg
+++ b/6-data-storage/03-indexeddb/indexeddb-index.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/figures.sketch b/figures.sketch
index 6230b60d98..d926fea536 100644
Binary files a/figures.sketch and b/figures.sketch differ