diff --git a/1-js/13-modules/01-modules-intro/article.md b/1-js/13-modules/01-modules-intro/article.md
index a746aa1a..9cf16b3c 100644
--- a/1-js/13-modules/01-modules-intro/article.md
+++ b/1-js/13-modules/01-modules-intro/article.md
@@ -1,8 +1,7 @@
# Modules, introduction
-As our application grows bigger, we want to split it into multiple files, so called 'modules'.
-A module usually contains a class or a library of useful functions.
+As our application grows bigger, we want to split it into multiple files, so called "modules". A module usually contains a class or a library of functions.
For a long time, JavaScript existed without a language-level module syntax. That wasn't a problem, because initially scripts were small and simple, so there was no need.
@@ -14,13 +13,15 @@ For instance:
- [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) -- the module system created for Node.js server.
- [UMD](https://github.com/umdjs/umd) -- one more module system, suggested as a universal one, compatible with AMD and CommonJS.
-Now all these slowly become a part of history, but we still can find them in old scripts. The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js.
+Now all these slowly become a part of history, but we still can find them in old scripts.
+
+The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js. So we'll study it from now on.
## What is a module?
-A module is just a file, a single script, as simple as that.
+A module is just a file. One script is one module.
-There are directives `export` and `import` to interchange functionality between modules, call functions of one module from another one:
+Modules can load each other and use special directives `export` and `import` to interchange functionality, call functions of one module from another one:
- `export` keyword labels variables and functions that should be accessible from outside the current module.
- `import` allows to import functionality from other modules.
@@ -44,7 +45,9 @@ alert(sayHi); // function...
sayHi('John'); // Hello, John!
```
-In this tutorial we concentrate on the language itself, but we use browser as the demo environment, so let's see how to use modules in the browser.
+The `import` directive loads the module by path `./sayHi.js` relative the current file and assigns exported function `sayHi` to the corresponding variable.
+
+Let's run the example in-browser.
As modules support special keywords and features, we must tell the browser that a script should be treated as module, by using the attribute `
```
-Here we can see it in the browser, but the same is true for any module.
-
### Module-level scope
Each module has its own top-level scope. In other words, top-level variables and functions from a module are not seen in other scripts.
@@ -82,7 +83,7 @@ In the example below, two scripts are imported, and `hello.js` tries to use `use
Modules are expected to `export` what they want to be accessible from outside and `import` what they need.
-So we should import `user.js` directly into `hello.js` instead of `index.html`.
+So we should import `user.js` into `hello.js` and get the required functionality from it instead of relying on global variables.
That's the correct variant:
@@ -125,10 +126,10 @@ alert("Module is evaluated!");
import `./alert.js`; // Module is evaluated!
// 📁 2.js
-import `./alert.js`; // (nothing)
+import `./alert.js`; // (shows nothing)
```
-In practice, top-level module code is mostly used for initialization. We create data structures, pre-fill them, and if we want something to be reusable -- export it.
+In practice, top-level module code is mostly used for initialization, creation of internal data structures, and if we want something to be reusable -- export it.
Now, a more advanced example.
@@ -160,9 +161,9 @@ alert(admin.name); // Pete
*/!*
```
-So, let's reiterate -- the module is executed only once. Exports are generated, and then they are shared between importers, so if something changes the `admin` object, other modules will see that .
+So, let's reiterate -- the module is executed only once. Exports are generated, and then they are shared between importers, so if something changes the `admin` object, other modules will see that.
-Such behavior is great for modules that require configuration. We can set required properties on the first import, and then in further imports it's ready.
+Such behavior allows to *configure* modules on first import. We can setup its properties once, and then in further imports it's ready.
For instance, `admin.js` module may provide certain functionality, but expect the credentials to come into the `admin` object from outside:
@@ -175,7 +176,7 @@ export function sayHi() {
}
```
-Now, in `init.js`, the first script of our app, we set `admin.name`. Then everyone will see it, including calls made from inside `admin.js` itself:
+In `init.js`, the first script of our app, we set `admin.name`. Then everyone will see it, including calls made from inside `admin.js` itself:
```js
// 📁 init.js
@@ -183,6 +184,8 @@ import {admin} from './admin.js';
admin.name = "Pete";
```
+Another module can also see `admin.name`:
+
```js
// 📁 other.js
import {admin, sayHi} from './admin.js';
@@ -204,11 +207,13 @@ Its content depends on the environment. In the browser, it contains the url of t
```
-### Top-level "this" is undefined
+### In a module, "this" is undefined
That's kind of a minor feature, but for completeness we should mention it.
-In a module, top-level `this` is undefined, as opposed to a global object in non-module scripts:
+In a module, top-level `this` is undefined.
+
+Compare it to non-module scripts, where `this` is a global object:
```html run height=0
```
-2. External scripts that are fetched from another origin (e.g. another site) require [CORS](mdn:Web/HTTP/CORS) headers, as described in the chapter . In other words, if a module script is fetched from another origin, the remote server must supply a header `Access-Control-Allow-Origin: *` (may use site domain instead of `*`) to indicate that the fetch is allowed.
+2. External scripts that are fetched from another origin (e.g. another site) require [CORS](mdn:Web/HTTP/CORS) headers, as described in the chapter . In other words, if a module script is fetched from another origin, the remote server must supply a header `Access-Control-Allow-Origin` allowing the fetch.
```html
@@ -332,13 +339,6 @@ Old browsers do not understand `type="module"`. Scripts of the unknown type are
```
-If we use bundle tools, then as scripts are bundled together into a single file (or few files), `import/export` statements inside those scripts are replaced by special bundler functions. So the resulting "bundled" script does not contain any `import/export`, it doesn't require `type="module"`, and we can put it into a regular script:
-
-```html
-
-
-```
-
## Build tools
In real-life, browser modules are rarely used in their "raw" form. Usually, we bundle them together with a special tool such as [Webpack](https://webpack.js.org/) and deploy to the production server.
@@ -357,13 +357,20 @@ Build tools do the following:
- Modern, bleeding-edge JavaScript syntax may be transformed to older one with similar functionality using [Babel](https://babeljs.io/).
- The resulting file is minified (spaces removed, variables replaced with shorter named etc).
+If we use bundle tools, then as scripts are bundled together into a single file (or few files), `import/export` statements inside those scripts are replaced by special bundler functions. So the resulting "bundled" script does not contain any `import/export`, it doesn't require `type="module"`, and we can put it into a regular script:
+
+```html
+
+
+```
+
That said, native modules are also usable. So we won't be using Webpack here: you can configure it later.
## Summary
To summarize, the core concepts are:
-1. A module is a file. To make `import/export` work, browsers need `
-```smart header="Edge spaces and in-between empty text are usually hidden in tools"
+```smart header="Spaces at string start/end and space-only text nodes are usually hidden in tools"
Browser tools (to be covered soon) that work with DOM usually do not show spaces at the start/end of the text and empty text nodes (line-breaks) between tags.
-That's because they are mainly used to decorate HTML, and do not affect how it is shown (in most cases).
+Developer tools save screen space this way.
-On further DOM pictures we'll sometimes omit them where they are irrelevant, to keep things short.
+On further DOM pictures we'll sometimes omit them when they are irrelevant. Such spaces usually do not affect how the document is displayed.
```
-
## Autocorrection
If the browser encounters malformed HTML, it automatically corrects it when making DOM.
@@ -148,7 +159,9 @@ You see? The `` appeared out of nowhere. You should keep this in mind whi
## Other node types
-Let's add more tags and a comment to the page:
+There are some other node types besides elements and text nodes.
+
+For example, comments:
```html
@@ -174,7 +187,7 @@ let node6 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,
drawHtmlTree(node6, 'div.domtree', 690, 500);
-Here we see a new tree node type -- *comment node*, labeled as `#comment`.
+We can see here a new tree node type -- *comment node*, labeled as `#comment`, between two text nodes.
We may think -- why is a comment added to the DOM? It doesn't affect the visual representation in any way. But there's a rule -- if something's in HTML, then it also must be in the DOM tree.
@@ -195,8 +208,6 @@ There are [12 node types](https://dom.spec.whatwg.org/#node). In practice we usu
To see the DOM structure in real-time, try [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up DOM at an instant.
-## In the browser inspector
-
Another way to explore the DOM is to use the browser developer tools. Actually, that's what we use when developing.
To do so, open the web-page [elks.html](elks.html), turn on the browser developer tools and switch to the Elements tab.
@@ -225,10 +236,12 @@ The best way to study them is to click around. Most values are editable in-place
## Interaction with console
-As we explore the DOM, we also may want to apply JavaScript to it. Like: get a node and run some code to modify it, to see the result. Here are few tips to travel between the Elements tab and the console.
+As we work the DOM, we also may want to apply JavaScript to it. Like: get a node and run some code to modify it, to see the result. Here are few tips to travel between the Elements tab and the console.
-- Select the first `` in the Elements tab.
-- Press `key:Esc` -- it will open console right below the Elements tab.
+For the start:
+
+1. Select the first `` in the Elements tab.
+2. Press `key:Esc` -- it will open console right below the Elements tab.
Now the last selected element is available as `$0`, the previously selected is `$1` etc.
@@ -236,9 +249,11 @@ We can run commands on them. For instance, `$0.style.background = 'red'` makes t

-From the other side, if we're in console and have a variable referencing a DOM node, then we can use the command `inspect(node)` to see it in the Elements pane.
+That's how to get a node from Elements in Console.
-Or we can just output it in the console and explore "at-place", like `document.body` below:
+There's also a road back. If there's a variable referencing a DOM node, then we can use the command `inspect(node)` in Console to see it in the Elements pane.
+
+Or we can just output DOM-node in the console and explore "at-place", like `document.body` below:

diff --git a/2-ui/1-document/03-dom-navigation/article.md b/2-ui/1-document/03-dom-navigation/article.md
index 645d0ab6..7a950e97 100644
--- a/2-ui/1-document/03-dom-navigation/article.md
+++ b/2-ui/1-document/03-dom-navigation/article.md
@@ -9,7 +9,7 @@ libs:
The DOM allows us to do anything with elements and their contents, but first we need to reach the corresponding DOM object.
-All operations on the DOM start with the `document` object. From it we can access any node.
+All operations on the DOM start with the `document` object. That's the main "entry point" to DOM. From it we can access any node.
Here's a picture of links that allow for travel between DOM nodes:
@@ -86,9 +86,9 @@ For instance, here `` has children `` and `
` (and few blank text
```
-...And all descendants of `` are not only direct children ``, `
` but also more deeply nested elements, such as `- ` (a child of `
`) and `` (a child of `- `) -- the entire subtree.
+...And descendants of `` are not only direct children `
`, `
` but also more deeply nested elements, such as `- ` (a child of `
`) and `` (a child of `- `) -- the entire subtree.
-**The `childNodes` collection provides access to all child nodes, including text nodes.**
+**The `childNodes` collection lists all child nodes, including text nodes.**
The example below shows children of `document.body`:
@@ -182,30 +182,34 @@ Please, don't. The `for..in` loop iterates over all enumerable properties. And c
## Siblings and the parent
-*Siblings* are nodes that are children of the same parent. For instance, `` and `` are siblings:
+*Siblings* are nodes that are children of the same parent.
+
+For instance, here `` and `` are siblings:
+
+```html
+
+ ......
+
+```
- `` is said to be the "next" or "right" sibling of ``,
- `` is said to be the "previous" or "left" sibling of ``.
+The next sibling is is `nextSibling`, and the previous one is `previousSibling`.
+
The parent is available as `parentNode`.
-The next node in the same parent (next sibling) is `nextSibling`, and the previous one is `previousSibling`.
+So all these tests are truthy:
-For instance:
+```js
+// parent of is
+alert( document.body.parentNode === document.documentElement ); // true
-```html run
-
+// before goes
+alert( document.body.previousSibling ); // HTMLHeadElement
```
## Element-only navigation
@@ -235,12 +239,12 @@ alert( document.documentElement.parentNode ); // document
alert( document.documentElement.parentElement ); // null
```
-In other words, the `documentElement` (``) is the root node. Formally, it has `document` as its parent. But `document` is not an element node, so `parentNode` returns it and `parentElement` does not.
+The reason is that root node `document.documentElement` (``) has `document` as its parent. But `document` is not an element node, so `parentNode` returns it and `parentElement` does not.
-This loop travels up from an arbitrary element `elem` to ``, but not to the `document`:
+This detail may be useful when we want to travel up from an arbitrary element `elem` to ``, but not to the `document`:
```js
-while(elem = elem.parentElement) {
- alert( elem ); // parent chain till
+while(elem = elem.parentElement) { // go up till
+ alert( elem );
}
```
````
diff --git a/2-ui/1-document/04-searching-elements-dom/1-find-elements/solution.md b/2-ui/1-document/04-searching-elements-dom/1-find-elements/solution.md
index c7080388..c73aecd9 100644
--- a/2-ui/1-document/04-searching-elements-dom/1-find-elements/solution.md
+++ b/2-ui/1-document/04-searching-elements-dom/1-find-elements/solution.md
@@ -11,15 +11,15 @@ table.getElementsByTagName('label')
// or
document.querySelectorAll('#age-table label')
-// 3. The first td in that table (with the word "Age").
+// 3. The first td in that table (with the word "Age")
table.rows[0].cells[0]
// or
table.getElementsByTagName('td')[0]
// or
table.querySelector('td')
-// 4. The form with the name "search".
-// assuming there's only one element with name="search"
+// 4. The form with the name "search"
+// assuming there's only one element with name="search" in the document
let form = document.getElementsByName('search')[0]
// or, form specifically
document.querySelector('form[name="search"]')
@@ -29,8 +29,7 @@ form.getElementsByTagName('input')[0]
// or
form.querySelector('input')
-// 6. The last input in that form.
-// there's no direct query for that
-let inputs = form.querySelectorAll('input') // search all
-inputs[inputs.length-1] // take last
+// 6. The last input in that form
+let inputs = form.querySelectorAll('input') // find all inputs
+inputs[inputs.length-1] // take the last one
```
diff --git a/2-ui/1-document/04-searching-elements-dom/1-find-elements/task.md b/2-ui/1-document/04-searching-elements-dom/1-find-elements/task.md
index 4d4faeb2..f0b54bea 100644
--- a/2-ui/1-document/04-searching-elements-dom/1-find-elements/task.md
+++ b/2-ui/1-document/04-searching-elements-dom/1-find-elements/task.md
@@ -6,12 +6,12 @@ importance: 4
Here's the document with the table and form.
-How to find?
+How to find?...
1. The table with `id="age-table"`.
2. All `label` elements inside that table (there should be 3 of them).
3. The first `td` in that table (with the word "Age").
-4. The `form` with the name `search`.
+4. The `form` with `name="search"`.
5. The first `input` in that form.
6. The last `input` in that form.
diff --git a/2-ui/1-document/04-searching-elements-dom/article.md b/2-ui/1-document/04-searching-elements-dom/article.md
index 68141710..cd988f73 100644
--- a/2-ui/1-document/04-searching-elements-dom/article.md
+++ b/2-ui/1-document/04-searching-elements-dom/article.md
@@ -105,7 +105,7 @@ Pseudo-classes in the CSS selector like `:hover` and `:active` are also supporte
The call to `elem.querySelector(css)` returns the first element for the given CSS selector.
-In other words, the result is the same as `elem.querySelectorAll(css)[0]`, but the latter is looking for *all* elements and picking one, while `elem.querySelector` just looks for one. So it's faster and shorter to write.
+In other words, the result is the same as `elem.querySelectorAll(css)[0]`, but the latter is looking for *all* elements and picking one, while `elem.querySelector` just looks for one. So it's faster and also shorter to write.
## matches
diff --git a/figures.sketch b/figures.sketch
index 3d452349..7034ba31 100644
Binary files a/figures.sketch and b/figures.sketch differ