` the number of its descendants. Skip leaves (nodes without children).
+
+The result:
+
+[iframe border=1 src="solution"]
diff --git a/2-ui/1-document/11-modifying-document/9-calendar-table/solution.md b/2-ui/1-document/11-modifying-document/9-calendar-table/solution.md
new file mode 100644
index 00000000..67bb5e13
--- /dev/null
+++ b/2-ui/1-document/11-modifying-document/9-calendar-table/solution.md
@@ -0,0 +1,9 @@
+We'll create the table as a string: `""`, and then assign it to `innerHTML`.
+
+The algorithm:
+
+1. Create the table header with `` and weekday names.
+1. Create the date object `d = new Date(year, month-1)`. That's the first day of `month` (taking into account that months in JavaScript start from `0`, not `1`).
+2. First few cells till the first day of the month `d.getDay()` may be empty. Let's fill them in with ` | | `.
+3. Increase the day in `d`: `d.setDate(d.getDate()+1)`. If `d.getMonth()` is not yet the next month, then add the new cell `` to the calendar. If that's a Sunday, then add a newline "</tr><tr>" .
+4. If the month has finished, but the table row is not yet full, add empty ` | ` into it, to make it square.
diff --git a/2-ui/1-document/11-modifying-document/9-calendar-table/solution.view/index.html b/2-ui/1-document/11-modifying-document/9-calendar-table/solution.view/index.html
new file mode 100644
index 00000000..7e211abc
--- /dev/null
+++ b/2-ui/1-document/11-modifying-document/9-calendar-table/solution.view/index.html
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2-ui/1-document/11-modifying-document/9-calendar-table/source.view/index.html b/2-ui/1-document/11-modifying-document/9-calendar-table/source.view/index.html
new file mode 100644
index 00000000..e1f4cd6b
--- /dev/null
+++ b/2-ui/1-document/11-modifying-document/9-calendar-table/source.view/index.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/2-ui/1-document/11-modifying-document/9-calendar-table/task.md b/2-ui/1-document/11-modifying-document/9-calendar-table/task.md
new file mode 100644
index 00000000..5dbb0ab8
--- /dev/null
+++ b/2-ui/1-document/11-modifying-document/9-calendar-table/task.md
@@ -0,0 +1,17 @@
+importance: 4
+
+---
+
+# Create a calendar
+
+Write a function `createCalendar(elem, year, month)`.
+
+The call should create a calendar for the given year/month and put it inside `elem`.
+
+The calendar should be a table, where a week is ` | `, and a day is ``. The table top should be ` | ` with weekday names: the first day should be Monday, and so on till Sunday.
+
+For instance, `createCalendar(cal, 2012, 9)` should generate in <div id='cal'></div> the following calendar:
+
+[iframe height=210 src="solution"]
+
+P.S. For this task it's enough to generate the calendar, should not yet be clickable.
diff --git a/2-ui/1-document/11-modifying-document/article.md b/2-ui/1-document/11-modifying-document/article.md
new file mode 100644
index 00000000..772ccefa
--- /dev/null
+++ b/2-ui/1-document/11-modifying-document/article.md
@@ -0,0 +1,431 @@
+# Modifying DOM
+
+Modifying DOM is the key to create "live" pages.
+
+Here we'll see how to create new elements "on the fly" and modify the existing page content.
+
+There are many methods for that. First we'll see a simple example and then explain them.
+
+[cut]
+
+## Example: show a message
+
+For the start, let's see how to add a message on the page, that looks nicer than `alert`.
+
+Here's how it will look:
+
+```html autorun height="80"
+
+
+*!*
+
+ Hi there! You've read an important message.
+
+*/!*
+```
+
+Now let's create the same `div` with Javascript.
+
+## Creating an element
+
+
+To create DOM nodes, there are two methods:
+
+`document.createElement(tag)`
+: Creates a new element with the given tag:
+
+ ```js
+ let div = document.createElement('div');
+ ```
+
+`document.createTextNode(text)`
+: Creates a new *text node* with the given text:
+
+ ```js
+ let textNode = document.createTextNode('Here I am');
+ ```
+
+### Creating the message
+
+In our case we want to make a `div`, add classes and the message into it:
+
+```js
+let div = document.createElement('div');
+div.className = "alert alert-success";
+div.innerHTML = "Hi there! You've read an important message.";
+```
+
+After that, we have a ready DOM element. Right now it's in the variable `div`, but not yet seen, because not inserted into the page.
+
+## Insertion methods
+
+To make the `div` show up, we need to insert it somewhere into `document`.
+
+Let's say we want to insert it into `parentElem`, like `let parentElem=document.body`.
+
+There exist following methods to insert a node:
+
+`parentElem.appendChild(elem)`
+: Appends `elem` as the last child of `parentElem`.
+
+ The following example adds a new `` to the end of ``:
+
+ ```html run height=100
+
+ - 0
+ - 1
+ - 2
+
+
+
+ ```
+
+`parentElem.insertBefore(elem, nextSibling)`
+: Inserts `elem` before `nextSibling` into `parentElem`.
+
+ The following code inserts a new list item before the second `- `:
+
+ ```html run height=100
+
+ - 0
+ - 1
+ - 2
+
+
+ ```
+
+ To insert as the first element, we can do like this:
+
+ ```js
+ list.insertBefore(newLi, list.firstChild);
+ ```
+
+`parentElem.replaceChild(elem, oldChild)`
+: Replaces `oldChild` with `elem` among children of `parentElem`.
+
+All these methods return the inserted node. In other words, `parentElem.appendChild(elem)` returns `elem`. But usually the returned value is not used, we just run the method.
+
+For our example, it would be like this:
+
+```html run height="80"
+
+
+
+```
+
+These methods are "old school": they exist from the ancient times and we can meet them in many old scripts.
+
+Unfortunately, there are some tasks that are hard to solve with them.
+
+For instance, how to insert *html* if we have it as a string? Or, given a node, how to insert something not into it, but *before* it?
+
+Of course, all that is solvable, but not in an elegant way.
+
+So there exist two other sets of insertion methods to handle all cases easily.
+
+### prepend/append/before/after
+
+This set of methods provides more flexible insertions:
+
+- `node.append(...nodes or strings)` -- append nodes or strings at the end of `node`,
+- `node.prepend(...nodes or strings)` -- insert nodes or strings into the beginning of `node`,
+- `node.before(...nodes or strings)` –- insert nodes or strings before the `node`,
+- `node.after(...nodes or strings)` –- insert nodes or strings after the `node`,
+- `node.replaceWith(...nodes or strings)` –- replaces `node` with the given nodes or strings.
+
+Let's say we have a list, like this:
+
+```html autorun
+
+ - 0
+ - 1
+ - 2
+
+
+
+```
+
+Here's where the insertions will go:
+
+
+
+So the final list will be:
+
+```html
+before
+
+ - prepend
+ - 0
+ - 1
+ - 2
+ - append
+
+after
+```
+
+These methods can insert a list of nodes and text pieces. But please note: all text is inserted *as text*.
+
+For instance, here a string and an element are inserted:
+
+```html run
+
+
+```
+
+The final HTML would be:
+
+```html run
+*!*
+<p>Hello</p>
+*/!*
+
+
+```
+
+In other words, strings are inserted exactly "as text", in a safe way, like `elem.textContent` does it.
+
+So, these methods allow to insert DOM nodes or text pieces at given places.
+
+But what if we want to insert HTML "as html", with all tags and stuff working, like `elem.innerHTML` does it?
+
+### insertAdjacentHTML/Text/Element
+
+There's a versatile method `elem.insertAdjacentHTML(where, html)`.
+
+The first parameter is a string, specifying where to insert, must be one of the following:
+
+- `"beforebegin"` -- insert `html` before `elem`,
+- `"afterbegin"` -- insert `html` into `elem`, at the beginning,
+- `"beforeend"` -- insert `html` into `elem`, at the end,
+- `"afterend"` -- insert `html` after `elem`.
+
+The second parameter `html` is a HTML string, inserted "as is".
+
+For instance:
+
+```html run
+
+
+```
+
+...Would lead to:
+
+```html run
+Hello
+
+```
+
+That's how we can append an arbitrary HTML to our page.
+
+Here's the picture of insertion variants:
+
+
+
+We definitely can notice similarities between this and the previous picture. The insertion points are actually the same, but here we can insert HTML.
+
+The method has two brothers:
+
+- `elem.insertAdjacentText(where, text)` -- the same syntax, but a string of `text` in inserted "as text" instead of HTML,
+- `elem.insertAdjacentElement(where, elem)` -- the same syntax, but inserts an element.
+
+They exist mainly to make the syntax "uniform". In practice, most of time only `insertAdjacentHTML` is used, because for elements and text we have methods `append/prepend/before/after` -- they are just shorter to write.
+
+So here's an alternative variant of showing a message:
+
+```html run
+
+
+
+```
+
+## Cloning nodes: cloneNode
+
+How to insert one more similar message?
+
+We could do a message-generating function and put the code there. But the alternative way would be to *clone* the existing `div` and modify the text inside it.
+
+Sometimes when we have a big element, that may be faster and simpler.
+
+The call `elem.cloneNode(true)` creates a "deep" clone of the element -- with all attributes and subelements. If we call it with `false`, then there would be no child elements.
+
+An example of copying the message:
+
+```html run height="120"
+
+
+
+ Hi there! You've read an important message.
+
+
+
+```
+
+## Removal methods
+
+To remove nodes, there are following methods:
+
+
+`parentElem.removeChild(node)`
+: Removes `elem` from `parentElem` (assuming it's a child).
+
+`node.remove()`
+: Removes the `node` from its place.
+
+We can easily see that the second method is much shorter. The first one exists for historical reasons.
+
+````smart
+If we want to *move* an element to another place -- there's no need to remove it from the old one.
+
+**All insertion methods automatically remove the node from the old place.**
+
+For instance, let's swap elements:
+
+```html run height=50
+First
+Second
+
+```
+````
+
+Let's make our message to disappear after a second:
+
+```html run untrusted
+
+
+
+```
+
+## Summary
+
+Methods to create new nodes:
+
+- `document.createElement(tag)` -- creates an element with the given tag,
+- `document.createTextNode(value)` -- creates a text node (rarely used),
+- `elem.cloneNode(deep)` -- clones the element, if `deep==true` then with all descendants.
+
+Insertion and removal of nodes:
+
+- From the parent:
+ - `parent.appendChild(elem)`
+ - `parent.insertBefore(elem, nextSibling)`
+ - `parent.removeChild(elem)`
+ - `parent.replaceChild(newElem, elem)`
+
+ all thes methods return `elem`.
+
+- Given a node:
+ - `node.append(...nodes or strings)` -- insert into `node`, at the end,
+ - `node.prepend(...nodes or strings)` -- insert into `node`, at the beginning,
+ - `node.before(...nodes or strings)` –- insert right before `node`,
+ - `node.after(...nodes or strings)` –- insert right after `node`,
+ - `node.replaceWith(...nodes or strings)` –- replace `node`.
+ - `node.remove()` –- remove the `node`.
+
+ All these methods accept a list of DOM nodes or text strings. Text strings are inserted "as text".
+
+- To insert HTML: `elem.insertAdjacentHTML(where, html)`, inserts depending on where:
+ - `"beforebegin"` -- insert `html` right before `elem`,
+ - `"afterbegin"` -- insert `html` into `elem`, at the beginning,
+ - `"beforeend"` -- insert `html` into `elem`, at the end,
+ - `"afterend"` -- insert `html` right after `elem`.
+
+ Also there are similar methods `elem.insertAdjacentText` and `elem.insertAdjacentElement`, they insert text strings and elements, but they are rarely used.
diff --git a/2-ui/1-document/11-modifying-document/before-prepend-append-after.png b/2-ui/1-document/11-modifying-document/before-prepend-append-after.png
new file mode 100644
index 00000000..5bff84d8
Binary files /dev/null and b/2-ui/1-document/11-modifying-document/before-prepend-append-after.png differ
diff --git a/2-ui/1-document/11-modifying-document/before-prepend-append-after@2x.png b/2-ui/1-document/11-modifying-document/before-prepend-append-after@2x.png
new file mode 100644
index 00000000..44c369ee
Binary files /dev/null and b/2-ui/1-document/11-modifying-document/before-prepend-append-after@2x.png differ
diff --git a/2-ui/1-document/11-modifying-document/insert-adjacent.png b/2-ui/1-document/11-modifying-document/insert-adjacent.png
new file mode 100644
index 00000000..08063bc5
Binary files /dev/null and b/2-ui/1-document/11-modifying-document/insert-adjacent.png differ
diff --git a/2-ui/1-document/11-modifying-document/insert-adjacent@2x.png b/2-ui/1-document/11-modifying-document/insert-adjacent@2x.png
new file mode 100644
index 00000000..60333ad1
Binary files /dev/null and b/2-ui/1-document/11-modifying-document/insert-adjacent@2x.png differ
diff --git a/2-ui/1-document/3-dom-navigation/article.md b/2-ui/1-document/3-dom-navigation/article.md
index c4dc022c..e7c6542d 100644
--- a/2-ui/1-document/3-dom-navigation/article.md
+++ b/2-ui/1-document/3-dom-navigation/article.md
@@ -179,13 +179,13 @@ alert( document.body.previousSibling ); // HTMLHeadElement
Navigation properties listed above refer to *all* nodes. For instance, in `childNodes` we can see both text nodes, element nodes, and even comment nodes if there exist.
-But for many tasks we don't want text or comment nodes. We want to manipulate on element nodes that represent tags.
+But for many tasks we don't want text or comment nodes. We want to manipulate element nodes that represent tags and structure of the page.
-So let's check out more navigation links that only take *element nodes* into account:
+So let's see more navigation links that only take *element nodes* into account:

-The links look like those given above, just with `Element` word inside:
+The links are similar to those given above, just with `Element` word inside:
- `children` -- only those children that are element nodes.
- `firstElementChild`, `lastElementChild` -- first and last element children.
@@ -230,26 +230,26 @@ Let's modify one of examples above: replace `childNodes` with `children`. Now it
|