[IFT] Bundle cleanup, adjust style and fixes
authorAlexey Merkulov <alexey.merkulov@jetbrains.com>
Wed, 23 Sep 2020 14:54:48 +0000 (17:54 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Thu, 24 Sep 2020 11:08:06 +0000 (11:08 +0000)
GitOrigin-RevId: a625bc76945c631c9c83c490aa0baefdabca3e71

33 files changed:
ide-features-trainer/res/messages/LessonsBundle.properties
ide-features-trainer/src/training/learn/lesson/general/GotoActionLesson.kt
ide-features-trainer/src/training/learn/lesson/general/MoveLesson.kt
ide-features-trainer/src/training/learn/lesson/general/SurroundAndUnwrapLesson.kt
ide-features-trainer/src/training/learn/lesson/general/assistance/CodeFormatLesson.kt
ide-features-trainer/src/training/learn/lesson/general/assistance/EditorCodingAssistanceLesson.kt
ide-features-trainer/src/training/learn/lesson/general/assistance/ParameterInfoLesson.kt
ide-features-trainer/src/training/learn/lesson/general/assistance/QuickPopupsLesson.kt
ide-features-trainer/src/training/learn/lesson/general/completion/BasicCompletionLessonBase.kt
ide-features-trainer/src/training/learn/lesson/general/navigation/FileStructureLesson.kt
ide-features-trainer/src/training/learn/lesson/general/refactorings/RefactoringMenuLessonBase.kt
ide-features-trainer/src/training/learn/lesson/general/run/CommonDebugLesson.kt
ide-features-trainer/src/training/learn/lesson/general/run/CommonRunConfigurationLesson.kt
ide-features-trainer/src/training/learn/lesson/java/completion/BasicCompletionLesson.kt
ide-features-trainer/src/training/learn/lesson/java/refactorings/JavaRenameLesson.kt
ide-features-trainer/src/training/learn/lesson/javascript/debugger/BeforeDebuggingLesson.kt
ide-features-trainer/src/training/learn/lesson/javascript/debugger/DebuggingFirstPartLesson.kt
ide-features-trainer/src/training/learn/lesson/javascript/debugger/DebuggingSecondPartLesson.kt
ide-features-trainer/src/training/learn/lesson/javascript/editor/BasicCompletionLesson.kt
ide-features-trainer/src/training/learn/lesson/javascript/editor/CodeEditingLesson.kt
ide-features-trainer/src/training/learn/lesson/javascript/editor/CodeInspectionLesson.kt
ide-features-trainer/src/training/learn/lesson/javascript/editor/NavigationLesson.kt
ide-features-trainer/src/training/learn/lesson/javascript/editor/RefactoringLesson.kt
ide-features-trainer/src/training/learn/lesson/javascript/testing/JestLesson.kt
ide-features-trainer/src/training/learn/lesson/python/completion/FStringCompletionLesson.kt
ide-features-trainer/src/training/learn/lesson/python/completion/PythonPostfixCompletionLesson.kt
ide-features-trainer/src/training/learn/lesson/python/completion/PythonSmartCompletionLesson.kt
ide-features-trainer/src/training/learn/lesson/python/navigation/PythonSearchEverywhereLesson.kt
ide-features-trainer/src/training/learn/lesson/python/refactorings/PythonInPlaceRefactoringLesson.kt
ide-features-trainer/src/training/learn/lesson/python/refactorings/PythonQuickFixesRefactoringLesson.kt
ide-features-trainer/src/training/learn/lesson/python/refactorings/PythonRenameLesson.kt
ide-features-trainer/src/training/learn/lesson/ruby/refactorings/RubyRefactorMenuLesson.kt
ide-features-trainer/src/training/learn/lesson/ruby/refactorings/RubyRenameLesson.kt

index abb8670dad5d255d8cc3931d34ef0474577ca1f5..b9f1be81fef03eb9f71838ab5da6869dd1221006 100644 (file)
@@ -10,7 +10,7 @@ goto.action.lesson.name=Search for actions
 goto.action.mac.workaround=\nIf <strong>Terminal</strong> search opens instead of {0}, refer to <a href="{1}">this article</a>.
 goto.action.use.find.action=One of the most useful shortcuts is {0}. It lets you search through all available \
   actions without having to know their individual shortcuts. Try it now with {1}.
-goto.action.invoke.about.action=Let''s say you want to learn about {0}, type {1} and press {2}.
+goto.action.invoke.about.action=Let''s say you want to learn about <ide/>, type {0} and press {1}.
 goto.action.to.return.to.the.editor=Press {0} to return to the editor.
 goto.action.invoke.again= You can also use {0} to change the settings, invoke it again now.
 goto.action.show.line.numbers.request=Type {0} to see {1} selector.
@@ -32,7 +32,7 @@ duplicate.and.delete.lines.delete.line=To delete the current line you can use ac
 
 move.lesson.name=Move
 move.pull.down=Rearranging lines usually involves two actions: cut and paste. \
-  With {0}, you can do it with just one. Press {1} to pull down the current line.
+  With <ide/>, you can do it with just one. Press {0} to pull down the current line.
 move.pull.up=Similarly, to pull a line up, press {0}.
 move.whole.method.up=Now try to move the whole method up with {0}.
 move.whole.method.down=Now move it down with {0}.
@@ -64,8 +64,8 @@ surround.and.unwrap.choose.unwrap.item=Choose {0} item.
 ## Completion module
 
 basic.completion.lesson.name=Basic completion
-basic.completion.start.typing=By default, {0} proposes completion for your code instantly. \
-  Start typing {1} right where the caret is, and you will see the Lookup Menu with matching suggestions.
+basic.completion.start.typing=By default, <ide/> proposes completion for your code instantly. \
+  Start typing {0} right where the caret is, and you will see the Lookup Menu with matching suggestions.
 basic.completion.continue.typing=Continue typing {0} unless it becomes the first item.
 basic.completion.just.press.to.complete=Now just press {0} to complete this statement.
 basic.completion.activate.explicitly=To activate Basic Completion explicitly, press {0}.
@@ -77,13 +77,13 @@ completion.with.tab.finish.with.tab=Choose {0}, for example, and press {1}. \
   This replaces the word at the caret rather than simply inserts it.
 
 postfix.completion.lesson.name=Postfix completion
-postfix.completion.type.template={0} can offer postfix shortcuts. Type {1}.
+postfix.completion.type.template=<ide/> can offer postfix shortcuts. Type {0}.
 
 rename.lesson.name=Rename
 
 refactoring.menu.lesson.name=Refactoring menu
-refactoring.menu.show.refactoring.list={0} supports a variety of refactorings. Many of them have own shortcuts. \
-  But for rare refactorings you can press {1} and preview a partial list of them.
+refactoring.menu.show.refactoring.list=<ide/> supports a variety of refactorings. Many of them have own shortcuts. \
+  But for rare refactorings you can press {0} and preview a partial list of them.
 refactoring.menu.introduce.parameter=Suppose we want to replace this expression with a parameter. So we need to choose {0}. \
   Now simply type <strong>pa</strong> (introduce <strong>pa</strong>rameter) or \
   <strong>ip</strong> (<strong>i</strong>ntroduce <strong>p</strong>arameter) to reduce the proposed list.
@@ -102,7 +102,7 @@ code.format.optimize.imports=Here you can configure reformat options. For exampl
 
 parameter.info.lesson.name=Parameter Info
 parameter.info.use.action=Press {0} to see the method signature.
-parameter.info.add.parameters=Use a width of <strong>175</strong> and a height of <strong>100</strong>.
+parameter.info.add.parameters=Use a width of {0} and a height of {1}.
 
 quick.popups.lesson.name=Quick Popups
 quick.popups.show.documentation=Press {0} to see documentation for the symbol at the caret.
@@ -113,7 +113,8 @@ editor.coding.assistance.lesson.name=Editor Coding Assistance
 editor.coding.assistance.goto.next.error=Press {0} to go to the next highlighted error in the file.
 editor.coding.assistance.show.error.description=Also, you can show error description of the item at the caret using {0}.
 editor.coding.assistance.show.intention=Lets fix this error! Press {0} and select {1}.
-editor.coding.assistance.highlight.usages=Another useful tool is usages highlighting. Press {0} to highlight all usages of the symbol at the caret within the file.
+editor.coding.assistance.highlight.usages=Another useful tool is usages highlighting. \
+  Press {0} to highlight all usages of the symbol at the caret within the file.
 
 ## Navigation module
 
@@ -135,7 +136,7 @@ file.structure.open.popup=A large source file can be difficult to read and navig
 file.structure.request.prefixes=Suppose you want to find some method with {0} and {1} words in its name. \
   Type {2} (prefixes of the required words) to filter file structure.
 file.structure.navigate=Only one item remains. Now press {0} to jump to the selected item.
-file.structure.toolwindow={0} can also show you the file structure as a tool window. Open it with {1}.
+file.structure.toolwindow=<ide/> can also show you the file structure as a tool window. Open it with {0}.
 
 extract.method.lesson.name=Extract method
 extract.method.invoke.action=Press {0} to extract the selected code block into a method.
@@ -153,9 +154,9 @@ extract.variable.choose.name=Choose a name for the new variable or leave it as i
 ## Run/Debug module
 
 run.configuration.lesson.name=Run configuration
-run.configuration.hide.toolwindow={0} automatically opened the {1} tool window. \
-  Tip: at the top of the {1} tool window you can see the full run command. Now let''s hide the tool window with {2}.
-run.configuration.temporary.to.permanent=For each new run {0} create temporary run configuration. \
+run.configuration.hide.toolwindow=<ide/> automatically opened the {0} tool window. \
+  Tip: at the top of the {0} tool window you can see the full run command. Now let''s hide the tool window with {1}.
+run.configuration.temporary.to.permanent=For each new run <ide/> create temporary run configuration. \
   Temporary configurations are automatically deleted if the default limit of five is reached. \
   Let''s convert the temporary configuration into a permanent one. Open the drop-down menu with run configurations.
 run.configuration.select.save.configuration=Select {0}.
@@ -174,9 +175,9 @@ debug.workflow.toggle.breakpoint=So, there is a problem. Let''s start investigat
   To toggle a breakpoint you should click left editor gutter or just press {0}.
 debug.workflow.start.debug=To start debug selected run configuration, click {0} or press {1}.
 debug.workflow.return.to.editor=Many trace actions will focus debug toolwindow. Let''s return to the editor with {0}.
-debug.workflow.use.watches={0} has several ways to show variable values. For this step, we selected the call. Let''s add it to {1}. \
-  You can copy the expression into the clipboard, click {2} button on the debug panel and paste the copied text. \
-  Alternatively, you can just use action {3} {4}.
+debug.workflow.use.watches=<ide/> has several ways to show variable values. For this step, we selected the call. Let''s add it to {0}. \
+  You can copy the expression into the clipboard, click {1} button on the debug panel and paste the copied text. \
+  Alternatively, you can just use action {2} {3}.
 debug.workflow.consider.to.add.a.shortcut=(consider to assign a shortcut for it later)
 debug.workflow.step.into=Lets step into. You can use action {0} or the button {1} at the debug panel.
 debug.workflow.choose.method.to.step.in=In most cases you will want to skip argument calculating so Smart Step Into feature suggest by \
@@ -229,12 +230,15 @@ java.statement.completion.complete.finish.body=Type on one line: {0} and then pr
 
 java.rename.press.rename=Press {0} to rename field {1}.
 java.rename.type.new.name=Type the new name for this field (e.g., {0}) and press {1}.
-java.rename.confirm.accessors.rename={0} is detecting corresponding getters/setters and proposes to rename them accordingly.\
-  Now just press {1} or click {2}
+java.rename.confirm.accessors.rename=<ide/> is detecting corresponding getters/setters and proposes to rename them accordingly.\
+  Now just press {0} or click {1}
 
-java.refactoring.menu.inline.variable=Now let''s inline variable {0} into the only use. You can press {1} and filter by <strong>iv</strong> (<strong>i</strong>nline <strong>v</strong>ariable). Or just press {2}.
-java.refactoring.menu.introduce.constant=In the end, let''s extract extension from file name. Again, you can press {0} and filter by <strong>ic</strong> (<strong>i</strong>ntroduce <strong>c</strong>onstant). Or just press {1}.
-java.refactoring.menu.confirm.constant=In this dialog you can choose the name, the parent and visibility for the new constant. You can leave proposed defaults and press {0} or click {1}.
+java.refactoring.menu.inline.variable=Now let''s inline variable {0} into the only use. \
+  You can press {1} and filter by <strong>iv</strong> (<strong>i</strong>nline <strong>v</strong>ariable). Or just press {2}.
+java.refactoring.menu.introduce.constant=In the end, let''s extract extension from file name. \
+  Again, you can press {0} and filter by <strong>ic</strong> (<strong>i</strong>ntroduce <strong>c</strong>onstant). Or just press {1}.
+java.refactoring.menu.confirm.constant=In this dialog you can choose the name, the parent and visibility for the new constant. \
+  You can leave proposed defaults and press {0} or click {1}.
 
 java.inheritance.hierarchy.lesson.name=Inheritance hierarchy
 java.inheritance.hierarchy.goto.implementation=Press {0} to look for implementations of {1}.
@@ -274,7 +278,7 @@ java.debug.workflow.drop.frame=We patched our method, but right now we are still
 ###############################################################################
 
 python.f.string.completion.lesson.name=F-string completion
-python.f.string.completion.type.prefix={0} supports automatic f-string conversion. Just start to type {1}.
+python.f.string.completion.type.prefix=<ide/> supports automatic f-string conversion. Just start to type {0}.
 python.f.string.completion.invoke.manually=You can invoke completion manually with {0}.
 python.f.string.completion.complete.it=Complete the statement with {0}. Just press {1} to apply the first item.
 python.f.string.completion.result.message=You may see that a simple Python string was replaced by f-string after the completion.
@@ -283,8 +287,8 @@ python.postfix.completion.select.item=Select {0} item from completion list.
 
 python.smart.completion.lesson.name=Smart completion
 python.smart.completion.try.basic.completion=Try to use Basic Completion by pressing {0}.
-python.smart.completion.use.smart.completion=Unfortunately {0} has no direct information about {1} type. \
-  But sometimes it can guess completion by the context! Use {2} to invoke Smart Completion.
+python.smart.completion.use.smart.completion=Unfortunately <ide/> has no direct information about {0} type. \
+  But sometimes it can guess completion by the context! Use {1} to invoke Smart Completion.
 python.smart.completion.finish.completion=Now just choose {0} item to finish this lesson.
 
 python.tab.completion.lesson.name=Tab completion
@@ -309,15 +313,15 @@ python.search.everywhere.finish=<strong>Done!</strong> In the same way you can u
 python.in.place.refactoring.lesson.name=In-place refactoring
 python.in.place.refactoring.start.type.new.name=Let''s consider an alternative approach to performing refactorings. \
   Suppose we want to rename local variable {0} to {1}. Just start typing the new name.
-python.in.place.refactoring.invoke.intentions={0} is guessing that you are going to rename the variable. \
-  You can notice it by the icon {1} in the left editor gutter. Invoke intentions by {2} when you finish typing the new name.
+python.in.place.refactoring.invoke.intentions=<ide/> is guessing that you are going to rename the variable. \
+  You can notice it by the icon {0} in the left editor gutter. Invoke intentions by {1} when you finish typing the new name.
 python.in.place.refactoring.finish.rename=Press {0} to finish rename.
 python.in.place.refactoring.add.parameter=Let''s add an argument to this method. We place the editor caret just after the first parameter. \
   Now type comma and parameter''s name: {0}.
-python.in.place.refactoring.invoke.intention.for.parameter={0} is guessing that you are going to change the method signature. \
-  You can notice it by the same icon {1} at the left editor gutter. Invoke intentions by {2} when you finish typing the new parameter.
+python.in.place.refactoring.invoke.intention.for.parameter=<ide/> is guessing that you are going to change the method signature. \
+  You can notice it by the same icon {0} at the left editor gutter. Invoke intentions by {1} when you finish typing the new parameter.
 python.in.place.refactoring.update.callers=Press {0} to update the callers.
-python.in.place.refactoring.signature.preview={0} is showing you the short signature preview. Press {1} to continue.
+python.in.place.refactoring.signature.preview=<ide/> is showing you the short signature preview. Press {0} to continue.
 python.in.place.refactoring.set.default.value=Now you need to type the value which will be inserted as an argument into each call. \
   You can choose {0} for this sample. Then press {1} to continue.
 python.in.place.refactoring.remark.about.application.scope=Note: In-place refactoring may be applied only in the \
@@ -328,18 +332,18 @@ python.quick.fix.refactoring.type.new.argument=Several refactorings can be perfo
   Suppose we want to add a parameter to the method {0} and pass the variable {1} to it. Let''s type {2} after the first argument.
 python.quick.fix.refactoring.wait.completion.showed=Wait a little bit for the completion list...
 python.quick.fix.refactoring.close.completion.list=For now, we don''t want to apply any completion. Close the list ({0}).
-python.quick.fix.refactoring.invoke.intentions=As you may notice, {0} is showing you a warning here. Let''s invoke intentions by {1}.
+python.quick.fix.refactoring.invoke.intentions=As you may notice, <ide/> is showing you a warning here. Let''s invoke intentions by {0}.
 python.quick.fix.refactoring.choose.change.signature=Choose {0} quick fix.
 python.quick.fix.refactoring.select.new.parameter=Let''s set the default value for the new parameter. Click the new parameter line. \
   Alternatively, you can set focus to the parameter without a mouse by {0} and then {1}.
 python.quick.fix.refactoring.set.default.value=You may navigate through the fields (and the checkbox) by using {0}. \
-  With the checkbox, you can let {1} inline the default value to the other callers or set it as the default value for the new parameter. \
+  With the checkbox, you can let <ide/> inline the default value to the other callers or set it as the default value for the new parameter. \
   The Signature Preview will help you understand the difference. Now set the default value as 0.
 python.quick.fix.refactoring.finish.refactoring=Press {0} (or click {1}) to finish the refactoring.
 
 python.rename.press.rename=Press {0} to rename field {1} (e.g., to {2}).
 python.rename.expand.dynamic.references=In simple cases {0} will just rename without confirmation. \
-  But in this sample, {0} detects two calls of {1} method for objects with unknown types. Expand {2} item.
+  But in this sample, <ide/> detects two calls of {0} method for objects with unknown types. Expand {1} item.
 python.rename.exclude.item=It seems {0} should be excluded from rename. Select it and press {1}.
 python.rename.finish.refactoring=Now just finish the rename with the {0} button.
 
@@ -368,13 +372,13 @@ ruby.class.search.type.second.prefix=You can search for a class by part of its n
 ruby.class.search.preview=To check the selected class before navigating to it, you can use {0} to see its quick definition.
 ruby.class.search.navigate.to.target=Suppose you are looking for {0}. Choose it and then press {1} to navigate.
 
-ruby.refactoring.menu.invoke.refactoring.list={0} supports a variety of refactorings. Press {1} to see a partial list of them.
+ruby.refactoring.menu.invoke.refactoring.list=<ide/> supports a variety of refactorings. Press {0} to see a partial list of them.
 ruby.refactoring.menu.use.push.method.down=Some refactorings are seldom used and have no shortcuts, but you can find them here. \
   Choose {0} now and complete the refactoring on {1}.
 
 ruby.rename.start.refactoring=Press {0} to rename the attribute accessor {1} (for example, to {2}).
-ruby.rename.confirm=In order to be confident about the refactoring, {0} lets you preview it before confirming. \
-  Click {1} to complete the refactoring.
+ruby.rename.confirm=In order to be confident about the refactoring, <ide/> lets you preview it before confirming. \
+  Click {0} to complete the refactoring.
 
 ###############################################################################
 ## JS lessons
@@ -383,82 +387,167 @@ ruby.rename.confirm=In order to be confident about the refactoring, {0} lets you
 js.editor.module.title=Editor Basics
 
 js.editor.completion.title=The Nuts and Bolts of Code Completion
-js.editor.completion.choose.lookup={0} is full of features that help you write better code and increase your productivity. Let\u2019s start with code completion. It enables you to code faster by completing keywords and symbols from language APIs and project dependencies. Type {1} and hit {2} to autocomplete {3}.
-js.editor.completion.choose.method=So, code completion shows context-aware suggestions as you type. To add one of these suggestions, you can use {0} like we just did, or press {1} to replace an existing item. Now add a {2} after {3}, then type {4} and autocomplete the {5} method with {0}.
-js.editor.completion.parameter.info=The tooltip ({0}) we\u2019ve got after placing the caret inside {1} lets you quickly look up the names of parameters in methods and functions. In some situations, you may want to review more detailed documentation. Let\u2019s do it now by pressing {2}.
-js.editor.completion.add.parameter=This is how you can look up JavaScript documentation right in WebStorm. Now add {0} inside {1} to continue.
-js.editor.completion.console.log.argument=Finally, let\u2019s complete the {0} statement. Place the caret inside {1} on the line 8 and add {2} using code completion.
+js.editor.completion.choose.lookup=<ide/> is full of features that help you write better code and increase your productivity.\
+  Let\u2019s start with code completion. It enables you to code faster by completing keywords and symbols from language APIs and project \
+  dependencies. Type {0} and hit {1} to autocomplete {2}.
+js.editor.completion.choose.method=So, code completion shows context-aware suggestions as you type. \
+  To add one of these suggestions, you can use {0} like we just did, or press {1} to replace an existing item. \
+  Now add a {2} after {3}, then type {4} and autocomplete the {5} method with {0}.
+js.editor.completion.parameter.info=The tooltip ({0}) we\u2019ve got after placing the caret inside {1} lets you quickly look up the names of \
+  parameters in methods and functions. In some situations, you may want to review more detailed documentation. Let\u2019s do it now by pressing {2}.
+js.editor.completion.add.parameter=This is how you can look up JavaScript documentation right in <ide/>. Now add {0} inside {1} to continue.
+js.editor.completion.console.log.argument=Finally, let\u2019s complete the {0} statement. \
+  Place the caret inside {1} on the line 8 and add {2} using code completion.
 js.editor.completion.next=That\u2019s it for this lesson. To start the next one, click the button below or use {0}.
 
 js.editor.code.editing.tips.and.tricks.title=Code Editing Tips and Tricks
-js.editor.code.editing.reformat.start=Let''s go over some tips and tricks that can help you edit code a lot faster. For starters, there''s no need to manually fix code formatting with {0}. Reformat the code with {1}.
-js.editor.code.editing.select.word=That\u2019s it! Now let\u2019s see how to quickly select pieces of code in a file. Press {0} a few times to fully select the second tr element (lines 14-18).
-js.editor.code.editing.comment.delete.unselect.move.up=Now that you''ve selected the code, you can (un)comment it out ({0}), delete it ({1}), or shrink the selection ({2}).\nAnother thing you can do is move this code up or down the file. Let\u2019s move it up with {3}
-js.editor.code.editing.multi.caret=Next up is multi-caret editing. Use it to save a bunch of time as you modify code in several spots at once. Place the caret inside the first {0} tag (line 10). Then select all {1} tags inside the same tr element (lines 10-12): press {2} six times until all the necessary tags are selected. \nLet''s replace {3} with {4} and hit {5} to exit the multi-caret mode.
-js.editor.code.editing.duplicate.delete.comment=Finally, let\u2019s quickly try the most popular line actions, such as duplicate line ({0}), delete line ({1}), or comment it out ({2}). Use {0} to duplicate the selected line now. Then hit {1} and {2} to try the other line actions.
+js.editor.code.editing.reformat.start=Let''s go over some tips and tricks that can help you edit code a lot faster. \
+  For starters, there''s no need to manually fix code formatting with <ide/>. Reformat the code with {0}.
+js.editor.code.editing.select.word=That\u2019s it! Now let\u2019s see how to quickly select pieces of code in a file. \
+  Press {0} a few times to fully select the second tr element (lines 14-18).
+js.editor.code.editing.comment.delete.unselect.move.up=Now that you''ve selected the code, you can (un)comment it out ({0}), delete it \
+  ({1}), or shrink the selection ({2}).\nAnother thing you can do is move this code up or down the file. Let\u2019s move it up with {3}.
+js.editor.code.editing.multi.caret=Next up is multi-caret editing. Use it to save a bunch of time as you modify code in several spots at once. \
+  Place the caret inside the first {0} tag (line 10). Then select all {1} tags inside the same tr element (lines 10-12): press {2} six \
+  times until all the necessary tags are selected. \nLet''s replace {3} with {4} and hit {5} to exit the multi-caret mode.
+js.editor.code.editing.duplicate.delete.comment=Finally, let\u2019s quickly try the most popular line actions, such as duplicate line ({0}), \
+  delete line ({1}), or comment it out ({2}). Use {0} to duplicate the selected line now. Then hit {1} and {2} to try the other line actions.
 js.editor.code.editing.next=That''s it for this lesson. Click the button below to start the next one or use  {0}.
 
 js.editor.code.inspection.title=The Power of Code Inspections
-js.editor.code.inspection.intro=As you work in the editor, {0} constantly analyzes your code, detects various problems in it, and suggests how it can be improved. The opened file has two highlighted problems on lines 4 and 5. Let\u2019s check what they are by pressing {1}.
-js.editor.code.inspection.show.intentions=You can also use {0} to jump from one error to another. Or, you can explore the found problems by hovering over them.\nIn this file, the IDE has located an unresolved variable \u2013 one that wasn''t defined anywhere in the code. It suggests creating a new one, {1}, as one of the possible fixes, but we need to add a parameter book instead. Place the caret on {2} and hit {3} to see the full list of fixes.
+js.editor.code.inspection.intro=As you work in the editor, <ide/> constantly analyzes your code, detects various problems in it, and suggests \
+  how it can be improved. The opened file has two highlighted problems on lines 4 and 5. Let\u2019s check what they are by pressing {0}.
+js.editor.code.inspection.show.intentions=You can also use {0} to jump from one error to another. \
+  Or, you can explore the found problems by hovering over them.\n\
+  In this file, the IDE has located an unresolved variable \u2013 one that wasn''t defined anywhere in the code. \
+  It suggests creating a new one, {1}, as one of the possible fixes, but we need to add a parameter book instead. \
+  Place the caret on {2} and hit {3} to see the full list of fixes.
 js.editor.code.inspection.run.intention=Let\u2019s select {0} and press {1}.
-js.editor.code.inspection.checkmark=If you now look at the top right-hand corner of the editor, you\u2019ll see a green checkmark ({0}) confirming the file has no more problems. However, there\u2019s still a minor detail that can be optimized to make the code shorter. Place the caret on {1} (line 3) and press {2}.
+js.editor.code.inspection.checkmark=If you now look at the top right-hand corner of the editor, you\u2019ll see a green checkmark ({0}) \
+  confirming the file has no more problems. However, there\u2019s still a minor detail that can be optimized to make the code shorter. \
+  Place the caret on {1} (line 3) and press {2}.
 js.editor.code.inspection.make.shorter=Now let\u2019s make our function expression shorter. Select the {0} quick-fix and hit {1}.
 js.editor.code.inspection.next=That\u2019s it for this lesson. Click the button below to start the next one or use  {0}.
 
 js.editor.navigation.title=Secrets of Efficient Navigation
 js.editor.navigation.recent.files=Let\u2019s start with navigating around a project. Press {0} to call up the {1} popup.
-js.editor.navigation.choose.structure=With this popup, you can quickly jump between recent files and IDE tool windows. One of those tool windows can assist you with navigating around a smaller piece of a project, a single file. Click the {0} tab to learn more about it.
-js.editor.navigation.activate.structure=So, the {0} tool window can help you examine a file faster. It provides an overview of its structure and lets you jump to a specific item simply by typing its name. Start typing {1} anywhere in the tool window area, hit {2}, and then hit {3} to close the panel and jump to the code. 
-js.editor.navigation.find.usages=As a result of our actions, the caret has moved to {0} (line 9). Let\u2019s leave it there and press {1} to open another tool window that can help you quickly find usages of any item. 
-js.editor.navigation.hide.tool.window=Great! Now you can see the usages of giveTreat across the whole project and the libraries. Let\u2019s close the tool window with {0}.
+js.editor.navigation.choose.structure=With this popup, you can quickly jump between recent files and IDE tool windows. One of those tool \
+  windows can assist you with navigating around a smaller piece of a project, a single file. Click the {0} tab to learn more about it.
+js.editor.navigation.activate.structure=So, the {0} tool window can help you examine a file faster. It provides an overview of its \
+  structure and lets you jump to a specific item simply by typing its name. Start typing {1} anywhere in the tool window area, hit {2}, \
+  and then hit {3} to close the panel and jump to the code.
+js.editor.navigation.find.usages=As a result of our actions, the caret has moved to {0} (line 9). \
+  Let\u2019s leave it there and press {1} to open another tool window that can help you quickly find usages of any item.
+js.editor.navigation.hide.tool.window=Great! Now you can see the usages of giveTreat across the whole project and the libraries. \
+  Let\u2019s close the tool window with {0}.
 js.editor.navigation.search.everywhere=Now press {0} twice to meet another feature that can help you search faster.
-js.editor.navigation.search.everywhere.tabs=This is the {0} popup. It lets you instantly find any action, file, class or symbol, and shows all the matches in one place. If you want to run a more specific search, you can hit {1} to switch from {2} to any other tab, such as {3} or {4}. Or you can use a shortcut to open a specific tab that you need. Let\u2019s try the latter with {5}.
-js.editor.navigation.search.action=Now that we\u2019re on the {0} tab, let\u2019s start typing {1} in the search bar to look up a shortcut for another useful navigation feature.
-js.editor.navigation.go.to.declaration=Notice the {0} next to <strong>Go to Declaration or Usages</strong> \u2013 it shows you usages for the definition and vice versa. Let\u2019s close the popup, place the caret on <strong>snoopy</strong> (line 16), and hit {1} to look for its declaration.
-js.editor.navigation.keymap.reference=Congratulations! You\u2019ve made it to the end of {0}. Print out the <a href="https://resources.jetbrains.com/storage/products/webstorm/docs/WebStorm_ReferenceCard.pdf">keymap reference</a> to have all the shortcuts handy as you make yourself at home in WebStorm. Click the button below to move to the next module.
+js.editor.navigation.search.everywhere.tabs=This is the {0} popup. It lets you instantly find any action, file, class or symbol, and shows \
+  all the matches in one place. If you want to run a more specific search, you can hit {1} to switch from {2} to any other tab, such as \
+  {3} or {4}. Or you can use a shortcut to open a specific tab that you need. Let\u2019s try the latter with {5}.
+js.editor.navigation.search.action=Now that we\u2019re on the {0} tab, let\u2019s start typing {1} in the search bar to look up a shortcut for \
+  another useful navigation feature.
+js.editor.navigation.go.to.declaration=Notice the {0} next to <strong>Go to Declaration or Usages</strong> \u2013 it shows you usages for the \
+  definition and vice versa. Let\u2019s close the popup, place the caret on {1} (line 16), and hit {0} to look for its declaration.
+js.editor.navigation.keymap.reference=Congratulations! You\u2019ve made it to the end of {0}. Print out the <a href="{1}">keymap reference</a> \
+  to have all the shortcuts handy as you make yourself at home in <ide/>. Click the button below to move to the next module.
 
 js.editor.refactorings.title=Refactorings in a Nutshell
-js.editor.refactorings.this={0} has a <a href=''https://www.jetbrains.com/help/webstorm/refactoring-source-code.html#ws_supported_refactorings''>number of refactorings</a> that can automatically restructure existing code without changing its behavior across the entire project. Let''s look up the list of refactorings available for the {1} parameter. To do this, press {2} or go to {3} from the main menu.
-js.editor.refactorings.rename=With {0}, you don''t need to memorize all the refactorings the IDE has, or their shortcuts. Let''s click {1} to see one of the most popular refactorings in action.
+js.editor.refactorings.this=<ide/> has a <a href=''{0}''>number of refactorings</a> that can automatically restructure existing code without \
+  changing its behavior across the entire project. Let''s look up the list of refactorings available for the {1} parameter. \
+  To do this, press {2} or go to {3} from the main menu.
+js.editor.refactorings.rename=With {0}, you don''t need to memorize all the refactorings the IDE has, or their shortcuts. \
+  Let''s click {1} to see one of the most popular refactorings in action.
 js.editor.refactorings.rename.apply=Rename the {0} parameter to {1} and hit {2}. This will apply the changes across all files in the project.
-js.editor.refactorings.shortcut=Well done! Let''s try refactoring code the other way \u2013 by using a shortcut. Place the caret on the {0} property (line 4) and press {1}.
+js.editor.refactorings.shortcut=Well done! Let''s try refactoring code the other way \u2013 by using a shortcut. \
+  Place the caret on the {0} property (line 4) and press {1}.
 js.editor.refactoring.replace=Now replace all 2 occurrences with the {0} variable named {1}.
-js.editor.refactoring.select.expression=Let''s create a new variable, {0}, which will contain {1}. Select the {1} expression from the list and hit {2}.
-js.editor.refactorings.next=We''ve just explored two ways to refactor code in {0}. Print out the <a href="https://resources.jetbrains.com/storage/products/webstorm/docs/WebStorm_ReferenceCard.pdf">keymap reference</a> if you prefer using shortcuts, or simply keep using the {1} menu. Click the button below to start the next lesson or use {2}.
+js.editor.refactoring.select.expression=Let''s create a new variable, {0}, which will contain {1}. \
+  Select the {1} expression from the list and hit {2}.
+js.editor.refactorings.next=We''ve just explored two ways to refactor code in <ide/>. Print out the <a href="{0}">keymap reference</a> \
+  if you prefer using shortcuts, or simply keep using the {1} menu. Click the button below to start the next lesson or use {2}.
 
 js.testing.jest.title=Fundamentals of Testing in {0}
-js.testing.jest.prepare=With WebStorm, all testing workflows become easier. Let\u2019s see how. For this module, we\u2019ll use <a href="https://jestjs.io/en/">Jest</a> and one of <a href="https://github.com/facebook/jest/tree/master/examples/getting-started">its sample projects</a> as an example, so please make sure you have Jest and npm/Yarn installed on your machine (see <a href="https://jestjs.io/docs/en/getting-started">this</a> webpage for more information). We\u2019ll start by creating a run/debug configuration, which is going to be Jest-specific. On the main menu, select {0} > {1}. Then click {4}, add the {2} configuration with the default parameters, and hit {3} to save it.
+js.testing.jest.prepare=With <ide/>, all testing workflows become easier. Let\u2019s see how. For this module, we\u2019ll use \
+  <a href="{0}">Jest</a> and one of <a href="{1}">its sample projects</a> as an example, so please make sure you have Jest and npm/Yarn \
+  installed on your machine (see <a href="{2}">this</a> webpage for more information). We\u2019ll start by creating a run/debug configuration, \
+  which is going to be Jest-specific. On the main menu, select {3} > {4}. Then click {5}, add the {6} configuration with the default \
+  parameters, and hit {7} to save it.
 js.testing.jest.run=So, now the new {0} configuration is selected by default. Let\u2019s click the {1} ({2}) button right next to it.
-js.testing.jest.navigate=Now we can see the {0} tool window with the test results and a stack trace for the failed tests coming from a test runner in it. Apart from simply tracking the test progress, you can do a lot of other things here. You can rerun all ({1}) or only failed ({2}) tests, view passed tests ({3}), or enable the <a href="https://blog.jetbrains.com/webstorm/2018/10/testing-with-jest-in-webstorm/#run_tests_in_watch_mode">watch mode</a> to automatically rerun tests on changes. \nYou can also quickly find a specific test in {4}. Let\u2019s try it now: place the caret anywhere in the {4} area, type {5}, and press {6} to jump to our test.
-js.testing.jest.double.click=That\u2019s it! Use this feature whenever you need to quickly find your way through a lot of tests. Let\u2019s now double-click {0} that we\u2019ve found.
-js.testing.jest.fix.test=By double-clicking a test in {0}, we\u2019ve jumped straight to its location in the code. If you now hover over {1}, you\u2019ll see a popup explaining why the test failed. From there, you can also debug a test if needed. \nLet\u2019s now replace the incorrect value used for {2}: on line 6, replace {3} with {4}.
-js.testing.jest.re.run.test=Now that we have the right value for the expected result, we can rerun our test. Let\u2019s do it in a different way this time. See the {0} icon on the left of the test in the editor? This icon not only shows you the test status for the tests you\u2019ve run recently, but also lets you quickly run and debug a specific test.\n  Let\u2019s click it and select {1}.
-js.testing.jest.success.run.coverage=Great job! Our test has successfully passed. \nLet\u2019s take a look at another handy tool. Click the {0} icon located next to the run/debug configurations menu.
-js.testing.jest.coverage.result=This is how you can quickly build a code coverage report showing how many files were covered with tests, including the percentage of lines that were covered in those files. Now let\u2019s close the coverage report with {0}.
-js.testing.jest.end=Congratulations! You\u2019ve made it to the end of this module. Most of what we\u2019ve learned also applies to the other test runners that {0} supports (except for code coverage and the watch mode). For more tips and tricks about testing apps with Jest, please take a look at <a href="https://blog.jetbrains.com/webstorm/2018/10/testing-with-jest-in-webstorm/">this</a> blog post. If you use other test runners, you may want to explore our <a href="https://www.jetbrains.com/help/webstorm/unit-testing-javascript.html">web help</a>.
+js.testing.jest.navigate=Now we can see the {0} tool window with the test results and a stack trace for the failed tests coming from a \
+  test runner in it. Apart from simply tracking the test progress, you can do a lot of other things here. You can rerun all ({1}) or only \
+  failed ({2}) tests, view passed tests ({3}), or enable the <a href="{4}">watch mode</a> to automatically rerun tests on changes.\n\
+  You can also quickly find a specific test in {5}. Let\u2019s try it now: place the caret anywhere in the {5} area, type {6}, and press {7} \
+  to jump to our test.
+js.testing.jest.double.click=That\u2019s it! Use this feature whenever you need to quickly find your way through a lot of tests. \
+  Let\u2019s now double-click {0} that we\u2019ve found.
+js.testing.jest.fix.test=By double-clicking a test in {0}, we\u2019ve jumped straight to its location in the code. If you now hover over {1}, \
+  you\u2019ll see a popup explaining why the test failed. From there, you can also debug a test if needed.\n\
+  Let\u2019s now replace the incorrect value used for {2}: on line 6, replace {3} with {4}.
+js.testing.jest.re.run.test=Now that we have the right value for the expected result, we can rerun our test. Let\u2019s do it in a different \
+  way this time. See the {0} icon on the left of the test in the editor? This icon not only shows you the test status for the tests you\u2019ve \
+  run recently, but also lets you quickly run and debug a specific test.\nLet\u2019s click it and select {1}.
+js.testing.jest.success.run.coverage=Great job! Our test has successfully passed.\nLet\u2019s take a look at another handy tool. \
+  Click the {0} icon located next to the run/debug configurations menu.
+js.testing.jest.coverage.result=This is how you can quickly build a code coverage report showing how many files were covered with tests, \
+  including the percentage of lines that were covered in those files. Now let\u2019s close the coverage report with {0}.
+js.testing.jest.end=Congratulations! You\u2019ve made it to the end of this module. Most of what we\u2019ve learned also applies to the other test \
+  runners that <ide/> supports (except for code coverage and the watch mode). For more tips and tricks about testing apps with Jest, please \
+  take a look at <a href="{0}">this</a> blog post. If you use other test runners, you may want to explore our <a href="{1}">web help</a>.
 
 js.debugger.module.title={0} Debugger 101
 
 js.debugger.before.title=Before Debugging: Run/Debug Configurations
-js.debugger.before.intro=With {0}, you can run and debug all kinds of JavaScript apps right where you write your code.\nIn this module, we\u2019ll go over some steps that will be helpful no matter what kind of code you debug. In our case, it will be a very basic <a href=''https://nodejs.org/en/''>Node.js</a> app that should compare two numbers and return {1} or {2} Please make sure Node.js is <a href=''https://nodejs.org/en/download/''>installed</a> on your machine before moving forward (for a fresh install, you\u2019ll need to restart {0}). Hit {3} if you\u2019re ready to continue.
-js.debugger.before.describe.tool.window=Two things happened as we hit {0}. First, we ran a file using Node.js and opened the {1} tool window, which shows the results of running the code. Second, {2} created a temporary run/debug configuration so we could run a file like that. Let\u2019s hide the tool window with {3} for now and get to know run/debug configurations better.
-js.debugger.before.save=So, these configurations serve as an entry point to running/debugging apps. They can be temporary or permanent. The main difference is that temporary ones are automatically deleted if the default limit of 5 configurations is reached. \nLet\u2019s see how you can turn a temporary configuration into a permanent one. Open the {0} drop-down menu located in the top right-hand corner and select {1}. 
-js.debugger.before.edit=That\u2019s it! Now, what if you want to adjust the settings of this new run/debug configuration or use another one? Open the {0} menu again and click {1}.
-js.debugger.before.manage=This is a place for managing run/debug configurations. To add a new one, hit {0}, select the desired configuration type, and specify the settings based on your project/configuration type. To fine-tune an existing one, you can click its name and update what\u2019s needed.\nTake some time to explore what can be found here and close the window once you\u2019re ready to move next.
+js.debugger.before.intro=With <ide/>, you can run and debug all kinds of JavaScript apps right where you write your code.\nIn this module, \
+  we\u2019ll go over some steps that will be helpful no matter what kind of code you debug. In our case, it will be a very basic \
+  <a href=''{0}''>Node.js</a> app that should compare two numbers and return {1} or {2}. Please make sure Node.js is \
+  <a href=''{3}''>installed</a> on your machine before moving forward (for a fresh install, you\u2019ll need to restart <ide/>). \
+  Hit {4} if you\u2019re ready to continue.
+js.debugger.before.describe.tool.window=Two things happened as we hit {0}. First, we ran a file using Node.js and opened the {1} \
+  tool window, which shows the results of running the code. Second, <ide/> created a temporary run/debug configuration so we could run a file \
+  like that. Let\u2019s hide the tool window with {2} for now and get to know run/debug configurations better.
+js.debugger.before.save=So, these configurations serve as an entry point to running/debugging apps. They can be temporary or permanent. \
+  The main difference is that temporary ones are automatically deleted if the default limit of 5 configurations is reached.\nLet\u2019s see how \
+  you can turn a temporary configuration into a permanent one. Open the {0} drop-down menu located in the top right-hand corner and select {1}.
+js.debugger.before.edit=That\u2019s it! Now, what if you want to adjust the settings of this new run/debug configuration or use another one? \
+  Open the {0} menu again and click {1}.
+js.debugger.before.manage=This is a place for managing run/debug configurations. To add a new one, hit {0}, select the desired \
+  configuration type, and specify the settings based on your project/configuration type. To fine-tune an existing one, you can click its \
+  name and update what\u2019s needed.\nTake some time to explore what can be found here and close the window once you\u2019re ready to move next.
 js.debugger.before.next=That\u2019s it for this lesson. To start the next one, click the button below or use {0}.
 
 js.debugger.part.1.title=Debugging Code. Part I
-js.debugger.part.1.start=Now that we have a run/debug configuration in place, let\u2019s see how to work with the built-in debugger. \nFirst, let\u2019s run our code one more time to examine what it returns as we didn''t focus on this in the previous lesson. Click the {0} button located next to the drop-down with configurations to run the currently selected one.
-js.debugger.part.1.gutter=The numbers we\u2019re comparing, {0} and {1}, are not equal, so we should\u2019ve got {2} when running the code. Let\u2019s find out why we got {3} instead. On line 1, click the left editor gutter (empty space) between #1 and the code to put a breakpoint.
-js.debugger.part.1.set.breakpoint=So, we can use breakpoints to pause the execution of the app. The red circle you see on the left-hand editor gutter is what a breakpoint looks like in WebStorm. If you click on it again, it will be removed. You can also right-click on it to customize its behavior, e.g. set a condition for it. Let\u2019s hit the {0} button located at the top right-hand corner (or press {1}) to move next.
-js.debugger.part.1.tool.window=Meet the {0} tool window. On its left side, you can find icons for stopping/rerunning configurations, and managing breakpoints. At its top, you can see a few tabs and a bunch of icons for stepping through the code. \nThe {1} tab we''re on is where most of the work is done. On the right, you can see all the {2} grouped by scopes, along with their values. The {3} view shows the call stack. If you go through it, you\u2019ll see the app state at every point of the execution path. Now switch to the {4} tab.
-js.debugger.part.1.scripts.tab=The {0} tab shows the messages logged by an app, including errors. When debugging Node.js apps, WebStorm also shows the {1} tab, where you can run JavaScript code snippets and view the console messages. Switch to the {2} tab to continue.
-js.debugger.part.1.next=The {0} tab lists all the files loaded into the currently running process. You can see the content of any file by double-clicking on it. To move to the second part of this lesson, click the button below or use {1}.
+js.debugger.part.1.start=Now that we have a run/debug configuration in place, let\u2019s see how to work with the built-in debugger.\n\
+  First, let\u2019s run our code one more time to examine what it returns as we didn''t focus on this in the previous lesson. \
+  Click the {0} button located next to the drop-down with configurations to run the currently selected one.
+js.debugger.part.1.gutter=The numbers we\u2019re comparing, {0} and {1}, are not equal, so we should\u2019ve got {2} when running the code. \
+  Let\u2019s find out why we got {3} instead. On line 1, click the left editor gutter (empty space) between #1 and the code to put a breakpoint.
+js.debugger.part.1.set.breakpoint=So, we can use breakpoints to pause the execution of the app. The red circle you see on the left-hand \
+  editor gutter is what a breakpoint looks like in <ide/>. If you click on it again, it will be removed. You can also right-click on it \
+  to customize its behavior, e.g. set a condition for it. Let\u2019s hit the {0} button located at the top right-hand corner (or press {1}) to move next.
+js.debugger.part.1.tool.window=Meet the {0} tool window. On its left side, you can find icons for stopping/rerunning configurations, and \
+  managing breakpoints. At its top, you can see a few tabs and a bunch of icons for stepping through the code.\nThe {1} tab we''re on is \
+  where most of the work is done. On the right, you can see all the {2} grouped by scopes, along with their values. The {3} view shows the \
+  call stack. If you go through it, you\u2019ll see the app state at every point of the execution path. Now switch to the {4} tab.
+js.debugger.part.1.scripts.tab=The {0} tab shows the messages logged by an app, including errors. When debugging Node.js apps, <ide/> \
+  also shows the {1} tab, where you can run JavaScript code snippets and view the console messages. Switch to the {2} tab to continue.
+js.debugger.part.1.next=The {0} tab lists all the files loaded into the currently running process. You can see the content of any file by \
+  double-clicking on it. To move to the second part of this lesson, click the button below or use {1}.
 
 js.debugger.part.2.title=Debugging Code. Part II
-js.debugger.part.2.step.into=<strong>Important</strong>: Please make sure that there\u2019s a breakpoint on line 1 and that the debugger is launched ({0}) and opened on the {1} tab before moving forward.\nLet''s continue with locating a bug in our code and learn a few more things that come in handy when debugging in {2}.To better understand how our code is executed, we could put a few more breakpoints in it and then move from one to another using {3} button ({4}), but there\u2019s a faster way. Let\u2019s step to the next executed line by pressing {5} and using {6} ({7}).
-js.debugger.part.2.buttons=Depending on the situation, you may also like {0} ({1}), which moves the execution in the current file, line by line, without stepping into any function calls. {2} ({3}) lets you select the chained or nested call to step into. Finally, {4} ({5}) finishes the execution of the current function and stops at the next statement after the call. \nNow, what if we want to check the value of an expression? {6} lets you do it quickly with the {7} popup. Press {8} to call it.
-js.debugger.part.2.evaluate=Let''s add {0} as an expression and hit {1}. Look at the result: it equals {2}. This is where the problem lies. In order for the function to catch different numbers, we need to slightly change the expression so that its result would equal {3}.\nNow let''s close the popup and fix the problem we''ve found in the code. Inside {4} on line 2, replace {5} with {6}.
-js.debugger.part.2.stop=Finally, let\u2019s learn how to stop the debugger when you no longer need it. First, click the breakpoint we added to remove it. Then, stop the debugger with {0} ({1}) and close its tool window by pressing {2}.
-js.debugger.part.2.end=Congratulations! You\u2019ve made it to the end of {0} and learned some basic ways to debug all kinds of apps. If you\u2019d like, you can run the code one more time to confirm that everything works fine now. To dive deeper into debugging specific types of apps, take a look at our <a href=''https://www.jetbrains.com/help/webstorm/2019.2/debugging-code.html''>web help</a> and <a href=''https://blog.jetbrains.com/webstorm/tag/debug/''>blog posts</a>. Click the button below to move to the next module.
+js.debugger.part.2.step.into=<strong>Important</strong>: Please make sure that there\u2019s a breakpoint on line 1 and that the debugger is \
+  launched ({0}) and opened on the {1} tab before moving forward.\nLet''s continue with locating a bug in our code and learn a few more \
+  things that come in handy when debugging in <ide/>.To better understand how our code is executed, we could put a few more breakpoints in it \
+  and then move from one to another using {2} button ({3}), but there\u2019s a faster way. Let\u2019s step to the next executed line by pressing {4} \
+  and using {5} ({6}).
+js.debugger.part.2.buttons=Depending on the situation, you may also like {0} ({1}), which moves the execution in the current file, line by \
+  line, without stepping into any function calls. {2} ({3}) lets you select the chained or nested call to step into. \
+  Finally, {4} ({5}) finishes the execution of the current function and stops at the next statement after the call.\n\
+  Now, what if we want to check the value of an expression? <ide/> lets you do it quickly with the {6} popup. Press {7} to call it.
+js.debugger.part.2.evaluate=Let''s add {0} as an expression and hit {1}. Look at the result: it equals {2}. This is where the problem lies. \
+  In order for the function to catch different numbers, we need to slightly change the expression so that its result would equal {3}.\n\
+  Now let''s close the popup and fix the problem we''ve found in the code. Inside {4} on line 2, replace {5} with {6}.
+js.debugger.part.2.stop=Finally, let\u2019s learn how to stop the debugger when you no longer need it. First, click the breakpoint we added to \
+  remove it. Then, stop the debugger with {0} ({1}) and close its tool window by pressing {2}.
+js.debugger.part.2.end=Congratulations! You\u2019ve made it to the end of {0} and learned some basic ways to debug all kinds of apps. If you\u2019d \
+  like, you can run the code one more time to confirm that everything works fine now. To dive deeper into debugging specific types of apps, \
+  take a look at our <a href=''{1}''>web help</a> and <a href=''{2}''>blog posts</a>. Click the button below to move to the next module.
index 66d067a452d37b3d1fd0155b93aa9c26b72e55a3..3058280b4b16fd1fb0ad415cfdc4c7d5ff967fba 100644 (file)
@@ -4,7 +4,6 @@ package training.learn.lesson.general
 import com.intellij.ide.IdeBundle
 import com.intellij.ide.actions.AboutPopup
 import com.intellij.ide.actions.searcheverywhere.SearchEverywhereUIBase
-import com.intellij.openapi.application.ApplicationNamesInfo
 import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
 import com.intellij.openapi.editor.impl.EditorComponentImpl
 import com.intellij.openapi.util.SystemInfo
@@ -37,7 +36,7 @@ class GotoActionLesson(module: Module, lang: String, private val sample: LessonS
         LessonsBundle.message("goto.action.use.find.action", LessonUtil.actionName(it), action(it)) + macOsWorkaround
       }
       actionTask("About") {
-        LessonsBundle.message("goto.action.invoke.about.action", LessonUtil.productName,
+        LessonsBundle.message("goto.action.invoke.about.action",
                               LessonUtil.actionName(it).toLowerCase(), LessonUtil.rawEnter())
       }
       task {
index c63fb50d497045bda9c5ec7f9368ed0fe20efbe8..06cc7b1c7bf85def044c420cd4d77a3d8ec9c025 100644 (file)
@@ -1,14 +1,12 @@
 // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package training.learn.lesson.general
 
-import com.intellij.openapi.application.ApplicationNamesInfo
 import training.lang.JavaLangSupport
 import training.learn.LessonsBundle
 import training.learn.interfaces.Module
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
 import training.learn.lesson.kimpl.LessonSample
-import training.learn.lesson.kimpl.LessonUtil
 
 class MoveLesson(module: Module, lang: String, private val sample: LessonSample)
   : KLesson("Move", LessonsBundle.message("move.lesson.name"), module, lang) {
@@ -17,7 +15,7 @@ class MoveLesson(module: Module, lang: String, private val sample: LessonSample)
       prepareSample(sample)
 
       actionTask("MoveLineDown") {
-        LessonsBundle.message("move.pull.down", LessonUtil.productName, action(it))
+        LessonsBundle.message("move.pull.down", action(it))
       }
       actionTask("MoveLineUp") {
         LessonsBundle.message("move.pull.up", action(it))
index 79e595023af3f1694c3ab5e722750c0c83a194d5..38f985e7eff15416c0ee2eb9689928d80009d424 100644 (file)
@@ -39,7 +39,7 @@ abstract class SurroundAndUnwrapLesson(module: Module, lang: String)
       }
 
       task {
-        text(LessonsBundle.message("surround.and.unwrap.choose.surround.item", code(surroundItemName)))
+        text(LessonsBundle.message("surround.and.unwrap.choose.surround.item", strong(surroundItemName)))
         stateCheck {
           editor.document.charsSequence.let { sequence ->
             surroundItems.all { sequence.contains(it) }
index 435936cdb1ef4190c7ff637d2bf18304f905eab5..990691e98cd87a48bb4b4d7df7ad437feb445deb 100644 (file)
@@ -14,7 +14,7 @@ import training.learn.lesson.kimpl.LessonContext
 import training.learn.lesson.kimpl.LessonSample
 
 class CodeFormatLesson(module: Module, override val lang: String, private val sample: LessonSample) :
-  KLesson("Code Format", LessonsBundle.message("code.format.lesson.name"), module, lang) {
+  KLesson("CodeAssistance.CodeFormatting", LessonsBundle.message("code.format.lesson.name"), module, lang) {
 
   override val lessonContent: LessonContext.() -> Unit = {
     prepareSample(sample)
index 6daef2c4ee9b439fc1a4ed04d21c4b9a7ca7a08a..8b44963da7c0732d6b539845d05fa59b38653be0 100644 (file)
@@ -10,7 +10,7 @@ import training.learn.lesson.kimpl.LessonContext
 import training.learn.lesson.kimpl.LessonSample
 
 abstract class EditorCodingAssistanceLesson(module: Module, lang: String, private val sample: LessonSample) :
-  KLesson("Editor Coding Assistance", LessonsBundle.message("editor.coding.assistance.lesson.name"), module, lang) {
+  KLesson("CodeAssistance.EditorCodingAssistance", LessonsBundle.message("editor.coding.assistance.lesson.name"), module, lang) {
 
   protected abstract fun TaskRuntimeContext.checkErrorFixed(): Boolean
 
index a6a5caf6156d4d7c84453d83bfa720714f3d6573..1051225c5ac88c758b36a6e6d2301f9ea246636b 100644 (file)
@@ -10,7 +10,7 @@ import training.learn.lesson.kimpl.LessonSample
 import kotlin.math.min
 
 class ParameterInfoLesson(module: Module, lang: String, private val sample: LessonSample) :
-  KLesson("Parameter Info", LessonsBundle.message("parameter.info.lesson.name"), module, lang) {
+  KLesson("CodeAssistance.ParameterInfo", LessonsBundle.message("parameter.info.lesson.name"), module, lang) {
 
   override val lessonContent: LessonContext.() -> Unit = {
     prepareSample(sample)
@@ -25,7 +25,7 @@ class ParameterInfoLesson(module: Module, lang: String, private val sample: Less
     }
 
     task {
-      text(LessonsBundle.message("parameter.info.add.parameters"))
+      text(LessonsBundle.message("parameter.info.add.parameters", code("175"), code("100")))
       stateCheck { checkParametersAdded(caretOffset) }
       test {
         type("175, 100")
index 88aadda0d45b243b2c5e9a0efe84429431b649ab..8cf77f07970c6de9348b7cce85c3af9e30fa06d8 100644 (file)
@@ -14,7 +14,7 @@ import training.learn.lesson.kimpl.LessonContext
 import training.learn.lesson.kimpl.LessonSample
 
 class QuickPopupsLesson(module: Module, lang: String, private val sample: LessonSample) :
-  KLesson("Quick Popups", LessonsBundle.message("quick.popups.lesson.name"), module, lang) {
+  KLesson("CodeAssistance.QuickPopups", LessonsBundle.message("quick.popups.lesson.name"), module, lang) {
 
   override val lessonContent: LessonContext.() -> Unit = {
     prepareSample(sample)
index 1eae6982d2662fc8f3336af5f487bfd51a7b47f3..f8ad00e86fbcb172fc0bc05daa01dffe5088e505 100644 (file)
@@ -1,7 +1,6 @@
 // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package training.learn.lesson.general.completion
 
-import com.intellij.openapi.application.ApplicationNamesInfo
 import com.intellij.testGuiFramework.framework.GuiTestUtil
 import com.intellij.testGuiFramework.util.Key
 import training.learn.LessonsBundle
@@ -37,7 +36,7 @@ abstract class BasicCompletionLessonBase(module: Module, lang: String)
       prepareSample(sample1)
       task {
         text(LessonsBundle.message("basic.completion.start.typing",
-                                   LessonUtil.productName, code(item1Completion)))
+                                   code(item1Completion)))
         triggerByListItemAndHighlight(highlightBorder = false, highlightInside = false) { // no highlighting
           it.toString().contains(item1Completion)
         }
index c52c11c7a0165efb06e884daf5662770d0af204a..4c06d9617ad443487698bebebee3f7474202299b 100644 (file)
@@ -2,7 +2,6 @@
 package training.learn.lesson.general.navigation
 
 import com.intellij.ide.dnd.aware.DnDAwareTree
-import com.intellij.openapi.application.ApplicationNamesInfo
 import com.intellij.openapi.editor.impl.EditorComponentImpl
 import com.intellij.testGuiFramework.framework.GuiTestUtil
 import com.intellij.testGuiFramework.util.Key
@@ -29,7 +28,7 @@ abstract class FileStructureLesson(module: Module, lang: String)
         LessonsBundle.message("file.structure.open.popup", action(it))
       }
       task(searchSubstring) {
-        text(LessonsBundle.message("file.structure.request.prefixes", code(firstWord), code(secondWord), code(searchSubstring)))
+        text(LessonsBundle.message("file.structure.request.prefixes", strong(firstWord), strong(secondWord), code(searchSubstring)))
         stateCheck { checkWordInSearch(it) }
         test {
           ideFrame {
@@ -44,7 +43,7 @@ abstract class FileStructureLesson(module: Module, lang: String)
         test { GuiTestUtil.shortcut(Key.ENTER) }
       }
       task("ActivateStructureToolWindow") {
-        text(LessonsBundle.message("file.structure.toolwindow", LessonUtil.productName, action(it)))
+        text(LessonsBundle.message("file.structure.toolwindow", action(it)))
         stateCheck { focusOwner?.javaClass?.name?.contains("StructureViewComponent") ?: false }
         test { actions(it) }
       }
index 1ae32778559db614e321fcbf010dd9949732994d..db3c2fa08cccac40479f62f3f527d3911d793cfa 100644 (file)
@@ -18,7 +18,7 @@ abstract class RefactoringMenuLessonBase(lessonId: String, module: Module, langu
   : KLesson(lessonId, LessonsBundle.message("refactoring.menu.lesson.name"), module, languageId) {
   fun LessonContext.extractParameterTasks() {
     actionTask("Refactorings.QuickListPopupAction") {
-      LessonsBundle.message("refactoring.menu.show.refactoring.list", LessonUtil.productName, action(it))
+      LessonsBundle.message("refactoring.menu.show.refactoring.list", action(it))
     }
     task(ActionsBundle.message("action.IntroduceParameter.text").dropMnemonic()) {
       text(LessonsBundle.message("refactoring.menu.introduce.parameter", strong(it)))
index 277555ebdbc8530082ab7906a841ec1ca9ccd656..305ff75eb54eee0195e4e4e0c7b07ce62c480519 100644 (file)
@@ -12,7 +12,6 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
 import com.intellij.openapi.actionSystem.DataProvider
 import com.intellij.openapi.actionSystem.impl.ActionButton
 import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.application.ApplicationNamesInfo
 import com.intellij.openapi.application.invokeLater
 import com.intellij.openapi.application.runWriteAction
 import com.intellij.openapi.command.WriteCommandAction
@@ -260,8 +259,7 @@ abstract class CommonDebugLesson(module: Module, id: String, languageId: String)
       val shortcut = if (hasShortcut) "" else " " + LessonsBundle.message("debug.workflow.consider.to.add.a.shortcut")
 
       text(LessonsBundle.message("debug.workflow.use.watches",
-                                 LessonUtil.productName, strong(TaskBundle.message("debugger.watches")),
-                                 icon(AllIcons.General.Add), action(it), shortcut))
+                                 strong(TaskBundle.message("debugger.watches")), icon(AllIcons.General.Add), action(it), shortcut))
       stateCheck {
         val watches = (XDebuggerManager.getInstance(project) as XDebuggerManagerImpl).watchesManager.getWatches(confNameForWatches)
         watches.any { watch -> watch.expression == needAddToWatch }
index 276ae3c853dce89c55641c7df39050725fd8177e..719856200149e719ee6067cae77c0bf8f21f63a9 100644 (file)
@@ -42,8 +42,7 @@ abstract class CommonRunConfigurationLesson(module: Module, id: String, language
 
       actionTask("HideActiveWindow") {
         LearningUiHighlightingManager.clearHighlights()
-        LessonsBundle.message("run.configuration.hide.toolwindow",
-                              LessonUtil.productName, runToolWindow(), action(it))
+        LessonsBundle.message("run.configuration.hide.toolwindow", runToolWindow(), action(it))
       }
 
       task {
@@ -55,7 +54,7 @@ abstract class CommonRunConfigurationLesson(module: Module, id: String, language
       val saveConfigurationItemName = ExecutionBundle.message("save.temporary.run.configuration.action.name", demoConfigurationName)
         .dropMnemonic()
       task {
-        text(LessonsBundle.message("run.configuration.temporary.to.permanent", LessonUtil.productName))
+        text(LessonsBundle.message("run.configuration.temporary.to.permanent"))
         triggerByListItemAndHighlight { item ->
           item.toString() == saveConfigurationItemName
         }
index bb47c31237775a3ba5553cdce907855d25070aba..a780a93c9b809f57116345578af01498e8a4b425 100644 (file)
@@ -6,7 +6,6 @@ import training.learn.LessonsBundle
 import training.learn.interfaces.Module
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
-import training.learn.lesson.kimpl.LessonUtil
 import training.learn.lesson.kimpl.parseLessonSample
 
 class BasicCompletionLesson(module: Module)
@@ -39,7 +38,7 @@ class BasicCompletionDemo implements Runnable{
       return {
         prepareSample(sample)
         actionTask("EditorChooseLookupItem") {
-          LessonsBundle.message("basic.completion.start.typing", LessonUtil.productName, code("Run")) +
+          LessonsBundle.message("basic.completion.start.typing", code("Run")) +
           " " + LessonsBundle.message("java.basic.completion.choose.first", action(it))
         }
         caret(18, 36)
index e3f45813828fe61547fea8be62105144f714c1f9..01dc4794de039849f5d2f532401dc265e0b91d28 100644 (file)
@@ -4,13 +4,11 @@ package training.learn.lesson.java.refactorings
 import com.intellij.CommonBundle
 import com.intellij.codeInsight.template.impl.TemplateManagerImpl
 import com.intellij.java.refactoring.JavaRefactoringBundle
-import com.intellij.openapi.application.ApplicationNamesInfo
 import com.intellij.refactoring.rename.RenameProcessor
 import com.intellij.testGuiFramework.impl.button
 import com.intellij.util.ui.UIUtil
 import training.commands.kotlin.TaskContext
 import training.commands.kotlin.TaskRuntimeContext
-import training.commands.kotlin.TaskTestContext
 import training.learn.LessonsBundle
 import training.learn.interfaces.Module
 import training.learn.lesson.kimpl.*
@@ -102,8 +100,7 @@ class JavaRenameLesson(module: Module)
     task {
       val okButtonText = CommonBundle.getOkButtonText()
       text(LessonsBundle.message("java.rename.confirm.accessors.rename",
-                                 ApplicationNamesInfo.getInstance().productName, LessonUtil.rawEnter(),
-                                 strong(okButtonText)))
+                                 LessonUtil.rawEnter(), strong(okButtonText)))
       stateCheck {
         val fieldName = getFieldName()
         val shouldBe = fieldName?.let { replaceTemplate(it).replace("<caret>", "").replace("<caret id=2/>", "") }
index 59daf1efc38d854c87dc8db15100603b9167b9bf..3492677bc868659f616d4d02e764bd3218275581 100644 (file)
@@ -12,7 +12,6 @@ import training.learn.interfaces.Module
 import training.learn.lesson.javascript.setLanguageLevel
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
-import training.learn.lesson.kimpl.LessonUtil.productName
 import training.learn.lesson.kimpl.dropMnemonic
 import training.learn.lesson.kimpl.parseLessonSample
 import javax.swing.tree.DefaultMutableTreeNode
@@ -41,12 +40,15 @@ class BeforeDebuggingLesson(module: Module)
         setLanguageLevel()
         prepareSample(jsDebuggerSample)
         task("RunClass") {
-          text(LessonsBundle.message("js.debugger.before.intro", productName, strong("Different!"), strong("Equal!"), action(it)))
+          text(LessonsBundle.message("js.debugger.before.intro",
+                                     "https://nodejs.org/en/", strong("Different!"), strong("Equal!"),
+                                     "https://nodejs.org/en/download/", action(it)))
           trigger(it)
         }
         task("HideActiveWindow") {
           text(
-            LessonsBundle.message("js.debugger.before.describe.tool.window", action("RunClass"), strong(UIBundle.message("tool.window.name.run")), productName, action(it)))
+            LessonsBundle.message("js.debugger.before.describe.tool.window",
+                                  action("RunClass"), strong(UIBundle.message("tool.window.name.run")), action(it)))
           trigger(it)
         }
         task {
index 95a36e77cbec1f04fa1abb53ec8745e56054b6b8..a9f1f5adeafd2e24a4b23e851017e3dabd087b32 100644 (file)
@@ -28,7 +28,7 @@ class DebuggingFirstPartLesson(module: Module)
         }
 
         task {
-          text(LessonsBundle.message("js.debugger.part.1.gutter", strong("10"), strong("-20"), strong("Different!"), strong("Equal!")))
+          text(LessonsBundle.message("js.debugger.part.1.gutter", code("10"), code("-20"), code("Different!"), code("Equal!")))
           stateCheck {
             lineContainsBreakpoint(1)
           }
index c03e6494839375f0c71ad3110150b14bbdc77cb1..545e864d012828921f4b3eadcbd73d37da93b67a 100644 (file)
@@ -26,8 +26,7 @@ class DebuggingSecondPartLesson(module: Module)
           text(LessonsBundle.message("js.debugger.part.2.step.into", 
                                      action("DebugClass"), 
                                      strong(XDebuggerBundle.message("xdebugger.debugger.tab.title")), 
-                                     productName, 
-                                     ActionsBundle.message("action.Resume.text").dropMnemonic(), 
+                                     ActionsBundle.message("action.Resume.text").dropMnemonic(),
                                      icon(AllIcons.Actions.Resume), 
                                      action(it), ActionsBundle.message("action.StepInto.text").dropMnemonic(), 
                                      icon(AllIcons.Actions.TraceInto)))
@@ -41,14 +40,16 @@ class DebuggingSecondPartLesson(module: Module)
                                      strong(ActionsBundle.message("action.SmartStepInto.text").dropMnemonic()), 
                                      action("SmartStepInto"), 
                                      strong(ActionsBundle.message("action.StepOut.text").dropMnemonic()), 
-                                     action("StepOut"), productName, 
+                                     action("StepOut"),
                                      strong(XDebuggerBundle.message("xdebugger.dialog.title.evaluate.expression")), 
                                      action(it)))
           trigger(it)
         }
 
         task {
-          text(LessonsBundle.message("js.debugger.part.2.evaluate", strong("a === b"), strong(XDebuggerBundle.message("xdebugger.button.evaluate").dropMnemonic()), strong("false"), strong("true (a !== b)"), strong("()"), strong("a === b"), strong("a !== b")))
+          text(LessonsBundle.message("js.debugger.part.2.evaluate",
+                                     code("a === b"), strong(XDebuggerBundle.message("xdebugger.button.evaluate").dropMnemonic()), code("false"), code("true (a !== b)"),
+                                     code("()"), code("a === b"), code("a !== b")))
           stateCheck {
             textOnLine(1, "a !== b")
           }
@@ -60,7 +61,10 @@ class DebuggingSecondPartLesson(module: Module)
         }
 
         task {
-          text(LessonsBundle.message("js.debugger.part.2.end", strong(LessonsBundle.message("js.debugger.module.title", productName))))
+          text(LessonsBundle.message("js.debugger.part.2.end",
+                                     strong(LessonsBundle.message("js.debugger.module.title", productName)),
+                                     "https://www.jetbrains.com/help/webstorm/2019.2/debugging-code.html",
+                                     "https://blog.jetbrains.com/webstorm/tag/debug/"))
         }
       }
     }
index a54de120034ec097b1957dd3315ec20d1dd51291..6e088014bca624d39a0bc7763a6b2069bbf0af10 100644 (file)
@@ -8,7 +8,6 @@ import training.learn.lesson.javascript.setLanguageLevel
 import training.learn.lesson.javascript.textBeforeCaret
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
-import training.learn.lesson.kimpl.LessonUtil.productName
 import training.learn.lesson.kimpl.parseLessonSample
 
 class BasicCompletionLesson(module: Module)
@@ -35,16 +34,16 @@ class BasicCompletionLesson(module: Module)
 
         caret(136)
         task("EditorChooseLookupItem") {
-          text(LessonsBundle.message("js.editor.completion.choose.lookup", productName, strong("Ma"), action("EditorChooseLookupItem"),
-                                     strong("Math")))
+          text(LessonsBundle.message("js.editor.completion.choose.lookup", strong("Ma"), action("EditorChooseLookupItem"),
+                                     code("Math")))
           trigger(it) {
             textBeforeCaret("Math")
           }
         }
 
         task("EditorChooseLookupItem") {
-          text(LessonsBundle.message("js.editor.completion.choose.method", action("EditorEnter"), action("EditorTab"), strong("."), strong("Math"), strong("f"),
-                                     strong("floor")))
+          text(LessonsBundle.message("js.editor.completion.choose.method",
+                                     action("EditorEnter"), action("EditorTab"), code("."), code("Math"), strong("f"), code("floor")))
           trigger(it) {
             textBeforeCaret("Math.floor(")
           }
@@ -52,7 +51,8 @@ class BasicCompletionLesson(module: Module)
 
         task("QuickJavaDoc") {
           text(
-            LessonsBundle.message("js.editor.completion.parameter.info", action("ParameterInfo"), strong("()"), action(it)))
+            LessonsBundle.message("js.editor.completion.parameter.info",
+                                  action("ParameterInfo"), code("()"), action(it)))
           stateCheck {
             val line = editor.caretModel.logicalPosition.line
             val column = editor.caretModel.logicalPosition.column
@@ -61,15 +61,16 @@ class BasicCompletionLesson(module: Module)
           trigger(it)
         }
         task {
-          text(LessonsBundle.message("js.editor.completion.add.parameter", strong("rnd"), strong("()")))
+          text(LessonsBundle.message("js.editor.completion.add.parameter",
+                                     code("rnd"), code("()")))
           stateCheck {
             textBeforeCaret("Math.floor(rnd")
           }
         }
         task("EditorChooseLookupItem") {
           text(
-            LessonsBundle.message("js.editor.completion.console.log.argument", strong("console.log"), strong("()"),
-                                  strong("pickAnimal(favoriteAnimals)")))
+            LessonsBundle.message("js.editor.completion.console.log.argument",
+                                  code("console.log"), code("()"), code("pickAnimal(favoriteAnimals)")))
           trigger(it) {
             textBeforeCaret("pickAnimal(favoriteAnimals")
           }
index de2eeac35603fe5dc38e3807343ddef2e329f8e4..d30d830927df542b74502d98a05761f8e260d04b 100644 (file)
@@ -10,7 +10,6 @@ import training.learn.lesson.javascript.textBeforeOffset
 import training.learn.lesson.javascript.textOnLine
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
-import training.learn.lesson.kimpl.LessonUtil.productName
 import training.learn.lesson.kimpl.parseLessonSample
 
 class CodeEditingLesson(module: Module)
@@ -51,7 +50,7 @@ class CodeEditingLesson(module: Module)
         }
         prepareSample(sample)
         task("ReformatCode") {
-          text(LessonsBundle.message("js.editor.code.editing.reformat.start", productName, action(it)))
+          text(LessonsBundle.message("js.editor.code.editing.reformat.start", action(it)))
           trigger(it)
         }
         waitBeforeContinue(500)
@@ -72,7 +71,8 @@ class CodeEditingLesson(module: Module)
           trigger(it)
         }
         task {
-          text(LessonsBundle.message("js.editor.code.editing.multi.caret", strong("td"), strong("td"), action("SelectNextOccurrence"), strong("td"), strong("th"), action("EditorEscape")))
+          text(LessonsBundle.message("js.editor.code.editing.multi.caret",
+                                     code("td"), code("td"), action("SelectNextOccurrence"), code("td"), code("th"), action("EditorEscape")))
           stateCheck {
             textOnLine(9, "<th>") &&
             textOnLine(10, "<th>") &&
index 10c01e3e0538a69b3bac6f69f8c9425e9311f56a..76b411f5e367820b10050751214d50d42fc7fd27 100644 (file)
@@ -11,7 +11,6 @@ import training.learn.lesson.javascript.textAtCaretEqualsTo
 import training.learn.lesson.javascript.textOnLine
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
-import training.learn.lesson.kimpl.LessonUtil.productName
 import training.learn.lesson.kimpl.parseLessonSample
 
 class CodeInspectionLesson(module: Module)
@@ -43,13 +42,14 @@ class CodeInspectionLesson(module: Module)
         setLanguageLevel()
         prepareSample(sample)
         task("GotoNextError") {
-          text(LessonsBundle.message("js.editor.code.inspection.intro", productName, action(it)))
+          text(LessonsBundle.message("js.editor.code.inspection.intro", action(it)))
           trigger(it) {
             editor.caretModel.logicalPosition.line == 3 && textAtCaretEqualsTo("book")
           }
         }
         task("ShowIntentionActions") {
-          text(LessonsBundle.message("js.editor.code.inspection.show.intentions", action("GotoNextError"), strong("book"), strong("book"), action(it)))
+          text(LessonsBundle.message("js.editor.code.inspection.show.intentions",
+                                     action("GotoNextError"), code("book"), code("book"), action(it)))
           before { caret(editor.document.getLineEndOffset(3) - 11) }
           
           //handle simple alt+enter and alt+enter for the error tooltip 
@@ -64,7 +64,8 @@ class CodeInspectionLesson(module: Module)
           }
         }
         task("ShowIntentionActions") {
-          text(LessonsBundle.message("js.editor.code.inspection.checkmark", icon(AllIcons.General.InspectionsOK), strong("function"), action(it)))
+          text(LessonsBundle.message("js.editor.code.inspection.checkmark", icon(AllIcons.General.InspectionsOK),
+                                     code("function"), action(it)))
           stateCheck {
             val line = editor.caretModel.logicalPosition.line
             line == 2 && textAtCaretEqualsTo("function")
@@ -72,7 +73,8 @@ class CodeInspectionLesson(module: Module)
           trigger(it)
         }
         task {
-          text(LessonsBundle.message("js.editor.code.inspection.make.shorter", strong(JavaScriptBundle.message("js.convert.to.arrow.function")), action("EditorEnter")))
+          text(LessonsBundle.message("js.editor.code.inspection.make.shorter",
+                                     strong(JavaScriptBundle.message("js.convert.to.arrow.function")), action("EditorEnter")))
           stateCheck {
             textOnLine(2, "books.forEach(book => {")
           }
index 26fd450a34febc5c94cbe27f441bf1d4b8c61b9c..de52811848bcad1226ffd4b6d377aa9d8b10a98d 100644 (file)
@@ -69,13 +69,13 @@ class NavigationLesson(module: Module)
           }
         }
         task("ActivateStructureToolWindow") {
-          text(LessonsBundle.message("js.editor.navigation.activate.structure", strong(UIBundle.message("tool.window.name.structure")), strong("giveTreat"), action("EditorEnter"), action(it)))
+          text(LessonsBundle.message("js.editor.navigation.activate.structure", strong(UIBundle.message("tool.window.name.structure")), code("giveTreat"), action("EditorEnter"), action(it)))
           stateCheck {
             textAtCaretEqualsTo("giveTreat") && focusOwner is EditorComponentImpl
           }
         }
         task("FindUsages") {
-          text(LessonsBundle.message("js.editor.navigation.find.usages", strong("giveTreat"), action(it)))
+          text(LessonsBundle.message("js.editor.navigation.find.usages", code("giveTreat"), action(it)))
           stateCheck {
             textAtCaretEqualsTo("giveTreat")
           }
@@ -101,14 +101,16 @@ class NavigationLesson(module: Module)
           }
         }
         task("GotoDeclaration") {
-          text(LessonsBundle.message("js.editor.navigation.go.to.declaration", action(it), action(it)))
+          text(LessonsBundle.message("js.editor.navigation.go.to.declaration", action(it), code("snoopy")))
           stateCheck {
             textAtCaretEqualsTo("snoopy")
           }
           trigger(it)
         }
         task {
-          text(LessonsBundle.message("js.editor.navigation.keymap.reference", strong(LessonsBundle.message("js.editor.module.title"))))
+          text(LessonsBundle.message("js.editor.navigation.keymap.reference",
+                                     strong(LessonsBundle.message("js.editor.module.title")),
+                                     "https://resources.jetbrains.com/storage/products/webstorm/docs/WebStorm_ReferenceCard.pdf"))
         }
       }
     }
index 0741b961acf093e072c688eecc90d0c0dd60a9cb..40d05d0e7e46a9ad919e4027b0414f647dcccdac 100644 (file)
@@ -12,7 +12,6 @@ import training.learn.lesson.javascript.textAtCaretEqualsTo
 import training.learn.lesson.javascript.textOnLine
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
-import training.learn.lesson.kimpl.LessonUtil.productName
 import training.learn.lesson.kimpl.dropMnemonic
 import training.learn.lesson.kimpl.parseLessonSample
 
@@ -47,7 +46,11 @@ class RefactoringLesson(module: Module)
         setLanguageLevel()
         prepareSample(sample)
         task("Refactorings.QuickListPopupAction") {
-          text(LessonsBundle.message("js.editor.refactorings.this", productName, strong("books"), action(it), strong(ActionsBundle.message("group.RefactoringMenu.text").dropMnemonic() + " > " + ActionsBundle.message("action.Refactorings.QuickListPopupAction.text"))))
+          val quickListPopup = ActionsBundle.message("group.RefactoringMenu.text").dropMnemonic() + " > " +
+                               ActionsBundle.message("action.Refactorings.QuickListPopupAction.text")
+          text(LessonsBundle.message("js.editor.refactorings.this",
+                                     "https://www.jetbrains.com/help/webstorm/refactoring-source-code.html#ws_supported_refactorings",
+                                     code("books"), action(it), strong(quickListPopup)))
           stateCheck {
             textAtCaretEqualsTo("books")
           }
@@ -63,14 +66,14 @@ class RefactoringLesson(module: Module)
 
         task {
           text(
-            LessonsBundle.message("js.editor.refactorings.rename.apply", strong("books"), strong("listOfBooks"), action("EditorEnter")))
+            LessonsBundle.message("js.editor.refactorings.rename.apply", code("books"), code("listOfBooks"), action("EditorEnter")))
           stateCheck {
             textOnLine(0, "function listBookAuthors(listOfBooks) {") &&
             TemplateManager.getInstance(project).getActiveTemplate(editor) == null
           }
         }
         task("IntroduceVariable") {
-          text(LessonsBundle.message("js.editor.refactorings.shortcut", strong("author"), action(it)))
+          text(LessonsBundle.message("js.editor.refactorings.shortcut", code("author"), action(it)))
           stateCheck {
             textAtCaretEqualsTo("author")
           }
@@ -78,13 +81,13 @@ class RefactoringLesson(module: Module)
         }
         task {
           text(
-            LessonsBundle.message("js.editor.refactoring.select.expression", strong("author"), strong("book.author"), action("EditorEnter")))
+            LessonsBundle.message("js.editor.refactoring.select.expression", code("author"), code("book.author"), action("EditorEnter")))
           stateCheck {
             focusOwner is JBList<*> && (focusOwner as JBList<*>).model.getElementAt(0).toString() == "NO"
           }
         }
         task {
-          text(LessonsBundle.message("js.editor.refactoring.replace", strong("let"), strong("author")))
+          text(LessonsBundle.message("js.editor.refactoring.replace", code("let"), code("author")))
           stateCheck {
             textOnLine(3, "let author = book.author;") &&
             textOnLine(4, "if (!listOfAuthors.includes(author)) {") &&
@@ -94,7 +97,10 @@ class RefactoringLesson(module: Module)
         }
         task {
           text(
-            LessonsBundle.message("js.editor.refactorings.next", productName, strong(ActionsBundle.message("group.RefactoringMenu.text").dropMnemonic()), action("learn.next.lesson")))
+            LessonsBundle.message("js.editor.refactorings.next",
+                                  "https://resources.jetbrains.com/storage/products/webstorm/docs/WebStorm_ReferenceCard.pdf",
+                                  strong(ActionsBundle.message("group.RefactoringMenu.text").dropMnemonic()),
+                                  action("learn.next.lesson")))
         }
       }
     }
index b6451cc937917d560e4826d5a3293e0d0f7085e0..1c76a7cc6909c5ecae50dd94e013324a0cde7bb0 100644 (file)
@@ -63,10 +63,13 @@ class JestLesson(module: Module)
         }
 
         task("editRunConfigurations") {
-          text(LessonsBundle.message("js.testing.jest.prepare", ActionsBundle.message("group.RunMenu.text").dropMnemonic(),
-                                     ExecutionBundle.message(
-                                       "edit.configuration.action").dropMnemonic(), strong("Jest"), strong("OK"),
-                                     icon(AllIcons.General.Add)))
+          text(LessonsBundle.message("js.testing.jest.prepare",
+                                     "https://jestjs.io/en/",
+                                     "https://github.com/facebook/jest/tree/master/examples/getting-started",
+                                     "https://jestjs.io/docs/en/getting-started",
+                                     ActionsBundle.message("group.RunMenu.text").dropMnemonic(), ExecutionBundle.message(
+            "edit.configuration.action").dropMnemonic(),
+                                     icon(AllIcons.General.Add), strong("Jest"), strong("OK")))
           stateCheck {
             RunManager.getInstance(project).findConfigurationByName(TestRunnerBundle.message("all.tests.scope.presentable.text")) != null
           }
@@ -85,6 +88,7 @@ class JestLesson(module: Module)
                                      icon(AllIcons.RunConfigurations.TestState.Run),
                                      icon(AllIcons.RunConfigurations.RerunFailedTests),
                                      icon(AllIcons.RunConfigurations.ShowPassed),
+                                     "https://blog.jetbrains.com/webstorm/2018/10/testing-with-jest-in-webstorm/#run_tests_in_watch_mode",
                                      strong(SmRunnerBundle.message("sm.test.runner.ui.tests.tree.presentation.labels.test.results")),
                                      strong("add"),
                                      shortcut(KeymapUtil.getKeyText(KeyEvent.VK_ENTER))))
@@ -127,7 +131,9 @@ class JestLesson(module: Module)
         }
 
         task {
-         text(LessonsBundle.message("js.testing.jest.end", productName))
+          text(LessonsBundle.message("js.testing.jest.end",
+                                     "https://blog.jetbrains.com/webstorm/2018/10/testing-with-jest-in-webstorm/",
+                                     "https://www.jetbrains.com/help/webstorm/unit-testing-javascript.html"))
         }
       }
     }
index 3d43190ed89909f73c7ae0216c30339281f12cce..b5de2da28a7eb0736ed208dcd1c057a2697fca4f 100644 (file)
@@ -7,7 +7,6 @@ import training.learn.LessonsBundle
 import training.learn.interfaces.Module
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
-import training.learn.lesson.kimpl.LessonUtil
 import training.learn.lesson.kimpl.LessonUtil.checkExpectedStateOfEditor
 import training.learn.lesson.kimpl.parseLessonSample
 
@@ -52,7 +51,7 @@ class FStringCompletionLesson(module: Module)
   override val lessonContent: LessonContext.() -> Unit = {
     prepareSample(sample)
     task("\${my") {
-      text(LessonsBundle.message("python.f.string.completion.type.prefix", LessonUtil.productName, code(it)))
+      text(LessonsBundle.message("python.f.string.completion.type.prefix", code(it)))
       runtimeText {
         val prefixTyped = checkExpectedStateOfEditor(sample) { change ->
           "\${my_car".startsWith(change) && change.startsWith(it)
index d2abdc6e1f896e951c1498217c6950f362f5862a..0c4e494f14551573ad45f9b5fcdb3ceb2313399e 100644 (file)
@@ -1,14 +1,12 @@
 // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package training.learn.lesson.python.completion
 
-import com.intellij.openapi.application.ApplicationNamesInfo
 import com.intellij.testGuiFramework.framework.GuiTestUtil.typeText
 import com.intellij.testGuiFramework.impl.jList
 import training.learn.LessonsBundle
 import training.learn.interfaces.Module
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
-import training.learn.lesson.kimpl.LessonUtil
 import training.learn.lesson.kimpl.LessonUtil.checkExpectedStateOfEditor
 import training.learn.lesson.kimpl.parseLessonSample
 
@@ -42,8 +40,7 @@ class PythonPostfixCompletionLesson(module: Module)
     get() = {
       prepareSample(sample)
       task {
-        text(LessonsBundle.message("postfix.completion.type.template",
-                                   LessonUtil.productName, code(completionSuffix)))
+        text(LessonsBundle.message("postfix.completion.type.template", code(completionSuffix)))
         triggerByListItemAndHighlight {
           it.toString() == completionSuffix
         }
index 38b9bb9b07cf7e00f425cd553102469dd2b53d4a..6ee73e8d341f80d661224509e15d63c4a2383168 100644 (file)
@@ -1,7 +1,6 @@
 // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package training.learn.lesson.python.completion
 
-import com.intellij.openapi.application.ApplicationNamesInfo
 import training.commands.kotlin.TaskContext
 import training.learn.LessonsBundle
 import training.learn.interfaces.Module
@@ -31,7 +30,7 @@ class PythonSmartCompletionLesson(module: Module)
         }
         task("SmartTypeCompletion") {
           text(LessonsBundle.message("python.smart.completion.use.smart.completion",
-                                     LessonUtil.productName, code("x"), action(it)))
+                                     code("x"), action(it)))
           triggerByListItemAndHighlight { ui ->
             ui.toString().contains(methodName)
           }
index 5e92f1a9dfe31eda4f740fe6184780fd16b851d8..affefdd266e95b0d0d4e1871d9604f9156c86adf 100644 (file)
@@ -33,7 +33,7 @@ class PythonSearchEverywhereLesson(module: Module)
       LessonsBundle.message("python.search.everywhere.invoke.search.everywhere", LessonUtil.actionName(it), shortcut)
     }
     task("cae") {
-      text(LessonsBundle.message("python.search.everywhere.type.prefixes", code("cache"), code("extension"), code(it)))
+      text(LessonsBundle.message("python.search.everywhere.type.prefixes", strong("cache"), strong("extension"), code(it)))
       stateCheck { checkWordInSearch(it) }
       test {
         Thread.sleep(500)
index a6201c7129b0ed1ac8f7935e6758f5a706d81c71..e11c9da2ac3d8c4dbfefb5affb675a4ea9d46b3e 100644 (file)
@@ -2,7 +2,6 @@
 package training.learn.lesson.python.refactorings
 
 import com.intellij.icons.AllIcons
-import com.intellij.openapi.application.ApplicationNamesInfo
 import com.intellij.testGuiFramework.framework.GuiTestUtil
 import com.intellij.testGuiFramework.util.Key
 import training.commands.kotlin.TaskRuntimeContext
@@ -50,7 +49,6 @@ class PythonInPlaceRefactoringLesson(module: Module)
     task("ShowIntentionActions") {
       text(
         LessonsBundle.message("python.in.place.refactoring.invoke.intentions",
-                              LessonUtil.productName,
                               icon(AllIcons.Gutter.SuggestedRefactoringBulb), action(it)))
       triggerByListItemAndHighlight(highlightBorder = true, highlightInside = false) { ui -> // no highlighting
         ui.toString().contains("Rename usages")
@@ -109,7 +107,6 @@ class PythonInPlaceRefactoringLesson(module: Module)
 
     task("ShowIntentionActions") {
       text(LessonsBundle.message("python.in.place.refactoring.invoke.intention.for.parameter",
-                                 LessonUtil.productName,
                                  icon(AllIcons.Gutter.SuggestedRefactoringBulb), action(it)))
       triggerByListItemAndHighlight(highlightBorder = true, highlightInside = false) { item ->
         item.toString().contains("Update usages to")
@@ -133,7 +130,7 @@ class PythonInPlaceRefactoringLesson(module: Module)
     }
 
     task {
-      text(LessonsBundle.message("python.in.place.refactoring.signature.preview", LessonUtil.productName, LessonUtil.rawEnter()))
+      text(LessonsBundle.message("python.in.place.refactoring.signature.preview", LessonUtil.rawEnter()))
       triggerByUiComponentAndHighlight(highlightBorder = false, highlightInside = false) { ui: JLabel -> // no highlighting
         ui.text == "Add values for new parameters:"
       }
index f77473b2f245b7908e163c1625e521dcc59ae553..588b67f8e60faf92239181419ea8c13a088966e5 100644 (file)
@@ -1,7 +1,6 @@
 // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 package training.learn.lesson.python.refactorings
 
-import com.intellij.openapi.application.ApplicationNamesInfo
 import com.intellij.openapi.application.ModalityState
 import com.intellij.openapi.application.invokeAndWaitIfNeeded
 import com.intellij.openapi.editor.impl.EditorComponentImpl
@@ -65,7 +64,7 @@ class PythonQuickFixesRefactoringLesson(module: Module)
     }
 
     task("ShowIntentionActions") {
-      text(LessonsBundle.message("python.quick.fix.refactoring.invoke.intentions", LessonUtil.productName, action(it)))
+      text(LessonsBundle.message("python.quick.fix.refactoring.invoke.intentions", action(it)))
       triggerByListItemAndHighlight(highlightBorder = true, highlightInside = false) { item ->
         item.toString().contains("Change signature of")
       }
@@ -99,7 +98,7 @@ class PythonQuickFixesRefactoringLesson(module: Module)
                                  action("EditorTab"), LessonUtil.rawEnter()))
 
       val selector = { collection: Collection<EditorComponentImpl> ->
-        collection.takeIf { it.size > 2 }?.maxBy { it.locationOnScreen.x }
+        collection.takeIf { it.size > 2 }?.maxByOrNull { it.locationOnScreen.x }
       }
       triggerByUiComponentAndHighlight(selector = selector) { editor: EditorComponentImpl ->
         UIUtil.getParentOfType(JDialog::class.java, editor) != null
@@ -115,7 +114,7 @@ class PythonQuickFixesRefactoringLesson(module: Module)
     }
     task {
       text(LessonsBundle.message("python.quick.fix.refactoring.set.default.value",
-                                 action("EditorTab"), LessonUtil.productName))
+                                 action("EditorTab")))
       restoreByUi()
       stateCheck {
         (previous.ui as? EditorComponentImpl)?.text == "0"
index 53b87dc8e5033637b6ebcc4fc0041bc055982728..50f55987f6288f404b5f88d9a98e06325c71b2a4 100644 (file)
@@ -17,7 +17,10 @@ import training.commands.kotlin.TaskTestContext
 import training.learn.LearnBundle
 import training.learn.LessonsBundle
 import training.learn.interfaces.Module
-import training.learn.lesson.kimpl.*
+import training.learn.lesson.kimpl.KLesson
+import training.learn.lesson.kimpl.LessonContext
+import training.learn.lesson.kimpl.dropMnemonic
+import training.learn.lesson.kimpl.parseLessonSample
 import java.util.regex.Pattern
 import javax.swing.JButton
 import javax.swing.JTree
@@ -95,7 +98,7 @@ class PythonRenameLesson(module: Module)
       }
       val dynamicReferencesString = LearnBundle.message("refactoring.dynamic.references.prefix")
       text(LessonsBundle.message("python.rename.expand.dynamic.references",
-                                 LessonUtil.productName, code("teams"), strong(dynamicReferencesString)))
+                                 code("teams"), strong(dynamicReferencesString)))
 
       triggerByFoundPathAndHighlight { _: JTree, path: TreePath ->
         path.pathCount == 6 && path.getPathComponent(5).toString().contains("company_members")
index 6fcf5083cd7ebf8b19bb183a7ff1bb0e129d2135..5a2aea8a8782f1b79d08a741e85cbfc9375537e6 100644 (file)
@@ -13,7 +13,6 @@ import training.learn.LessonsBundle
 import training.learn.interfaces.Module
 import training.learn.lesson.kimpl.KLesson
 import training.learn.lesson.kimpl.LessonContext
-import training.learn.lesson.kimpl.LessonUtil
 import training.learn.lesson.kimpl.parseLessonSample
 
 class RubyRefactorMenuLesson(module: Module)
@@ -38,7 +37,7 @@ class RubyRefactorMenuLesson(module: Module)
     get() = {
       prepareSample(sample)
       actionTask("Refactorings.QuickListPopupAction") {
-        LessonsBundle.message("ruby.refactoring.menu.invoke.refactoring.list", LessonUtil.productName, action(it))
+        LessonsBundle.message("ruby.refactoring.menu.invoke.refactoring.list", action(it))
       }
       task(RefactoringBundle.message("push.members.down.title")) {
         text(LessonsBundle.message("ruby.refactoring.menu.use.push.method.down", strong(it), code("meow()")))
index a8c8d9c844ea878a089ff1de3f4c3c29e6b78aa8..870b7b29955d9e2b01dd0bd4d29d1bae6c451056 100644 (file)
@@ -7,7 +7,10 @@ import com.intellij.ui.treeStructure.Tree
 import training.commands.kotlin.TaskTestContext
 import training.learn.LessonsBundle
 import training.learn.interfaces.Module
-import training.learn.lesson.kimpl.*
+import training.learn.lesson.kimpl.KLesson
+import training.learn.lesson.kimpl.LessonContext
+import training.learn.lesson.kimpl.dropMnemonic
+import training.learn.lesson.kimpl.parseLessonSample
 import java.util.concurrent.Future
 import java.util.concurrent.TimeUnit
 import java.util.regex.Pattern
@@ -68,7 +71,7 @@ class RubyRenameLesson(module: Module)
         before {
           result = template.replace("<name>", replace.get(2, TimeUnit.SECONDS)).replace("<caret>", "")
         }
-        text(LessonsBundle.message("ruby.rename.confirm", LessonUtil.productName, strong(it)))
+        text(LessonsBundle.message("ruby.rename.confirm", strong(it)))
         stateCheck { editor.document.text == result }
         test {
           ideFrame {