## Setup
First, make your own fork, and [install Ruby](http://installfest.railsbridge.org/installfest/) and [git](https://git-scm.com/) on your computer. Then...
-1. `git clone XXX` (where XXX is either `https://github.com/alexch/codelikethis.git` or your personal github repo URL)
+1. `git clone XXX` (where XXX is either `https://github.com/burlingtoncodeacademy/codelikethis.git` or your personal github repository URL)
2. `cd codelikethis`
3. `gem install bundler`
4. `bundle install`
5. `rake spec` (to run all tests and verify setup)
6. `rake build` (to compile CSS)
-7. `rake run` (or `rerun` to rebuild/restart on file changes)
+7. `rake run` (or `rerun` to rebuild/restart on file changes)
8. open
## Usage
@@ -24,14 +67,14 @@ SCSS is currently built using Sass. Run this all the time in development, or at
rake build
-|Command|Description|
-|---|---|
-|`rake spec` | run all tests and verify setup |
-|`rake build` | compile CSS |
-|`rake run` | run local server on |
-|`rerun rackup` |run with rebuild/restart on file changes |
-|`rerun --pattern '*.scss' --exit -- rake build` | run this in a separate terminal to compile CSS when SCSS changes too |
-|`./check-links.sh` | check entire site for broken links |
+| Command | Description |
+|-------------------------------------------------|----------------------------------------------------------------------|
+| `rake spec` | run all tests and verify setup |
+| `rake build` | compile CSS |
+| `rake run` | run local server on |
+| `rerun rackup` | run with rebuild/restart on file changes |
+| `rerun --pattern '*.scss' --exit -- rake build` | run this in a separate terminal to compile CSS when SCSS changes too |
+| `./check-links.sh` | check entire site for broken links |
Note that any of the above may need to be preceded by `bundle exec` e.g. `bundle exec rerun rackup` (whether you need to do this or not depends on gnarly details of your Ruby installation).
@@ -39,34 +82,34 @@ Note that any of the above may need to be preceded by `bundle exec` e.g. `bundle
Local -> Github -> CircleCI -> Heroku
- * https://dashboard.heroku.com/apps/codelikethis/deploy/github
+ * https://dashboard.heroku.com/apps/btvca-curriculum/deploy/github
* https://circleci.com/gh/BurlingtonCodeAcademy/codelikethis
* https://github.com/settings/applications
* https://github.com/BurlingtonCodeAcademy/codelikethis/settings/hooks/90661849
-
-## Layout
-
-|Path|Description|
-|---|---|
-|`./app.rb` | main app |
-|`./config.ru` | app config |
-|`lib` | ruby source code |
-|`lib/thing.rb::WEIRD_WORDS` | list of oddly-capitalized words (e.g. CSS, JavaScript) |
-|`lib/bootcamp.rb` | ruby Site describing the Bootcamp course(s) |
-|`lib/bootcamp-schedule.json` | JSON describing the Bootcamp course schedule |
-|`spec` | ruby test source code |
-|`public` | web-visible files |
-|`public/images` | web site images |
-|`public/lessons/images` | images used by some lessons |
-|`public/lessons/foo/bar.jpg` | an image used by only a single lesson |
-|`public/js` | web site scripts |
-|`public/css` | web site css files -- **do not edit** these directly! |
-|`public/scss` | web site sass source files, compiled into public/css |
-|`public/lessons` | course files (markdown and images), organized by track |
-|`public/lessons/trackname/` | track files (markdown and images), organized by track |
-|`public/lessons/trackname/trackname.rb` | track description files; names match public/lessons subdirs |
-|`public/lessons/trackname/baking.md` | markdown slides for a single lesson named `baking` (served from `/lessons/trackname/bake_cookies` URL path) |
-|`public/projects/bake_cookies.md` | markdown slides for a single project named `bake_cookies` (served from `/projects/bake_cookies` URL path) |
+
+## Layout
+
+| Path | Description |
+|-----------------------------------------|-------------------------------------------------------------------------------------------------------------|
+| `./app.rb` | main app |
+| `./config.ru` | app config |
+| `lib` | ruby source code |
+| `lib/thing.rb::WEIRD_WORDS` | list of oddly-capitalized words (e.g. CSS, JavaScript) |
+| `lib/bootcamp.rb` | ruby Site describing the Bootcamp course(s) |
+| `lib/bootcamp-schedule.json` | JSON describing the Bootcamp course schedule |
+| `spec` | ruby test source code |
+| `public` | web-visible files |
+| `public/images` | web site images |
+| `public/lessons/images` | images used by some lessons |
+| `public/lessons/foo/bar.jpg` | an image used by only a single lesson |
+| `public/js` | web site scripts |
+| `public/css` | web site css files -- **do not edit** these directly! |
+| `public/scss` | web site sass source files, compiled into public/css |
+| `public/lessons` | course files (markdown and images), organized by track |
+| `public/lessons/trackname/` | track files (markdown and images), organized by track |
+| `public/lessons/trackname/trackname.rb` | track description files; names match public/lessons subdirs |
+| `public/lessons/trackname/baking.md` | markdown slides for a single lesson named `baking` (served from `/lessons/trackname/bake_cookies` URL path) |
+| `public/projects/bake_cookies.md` | markdown slides for a single project named `bake_cookies` (served from `/projects/bake_cookies` URL path) |
## Sites
@@ -76,23 +119,23 @@ a Site is
* an ordered collection of Tracks
* a home page
* a schedule
-
+
Currently there are three Sites:
-1. CodeLikeThis - the main site, containing all Tracks (listed in alphabetical order)
-2. Bootcamp - the site for *Burlington Code Academy's 2018 Web Development Bootcamp*, which runs from June through August in (where else?) Burlington, Vermont
-3. JavaScript After Hours
+1. The Bootcamp Curriculum
+1. JavaScript After Hours
+1. JavaScript One Night Introduction
-Both sites are served from the same web application instance, running on Heroku (). The app looks at `request.host` and serves a different Site to each hostname.
+Both sites are served from the same web application instance, running on Heroku (). The app looks at `request.host` and serves a different Site to each hostname.
To add a Site, follow the example of [Bootcamp](lib/bootcamp.rb).
To point DNS at a new Site:
-1. run `heroku domains:add newsite --app codelikethis`
-2. run `heroku domains --app codelikethis` and note the "DNS Target" for your new site
+1. run `heroku domains:add newsite --app btvca-curriculum`
+2. run `heroku domains --app btvca-curriculum` and note the "DNS Target" for your new site
3. in your DNS manager, add a CNAME record pointing the subdomain name (e.g. `newsite`) to the DNS target (e.g. `salty-hyena-j9awwxxx123.herokudns.com`)
-(Note that [Heroku SSL ACM](https://devcenter.heroku.com/articles/automated-certificate-management) does not support wildcard domains, so each CNAME
+(Note that [Heroku SSL ACM](https://devcenter.heroku.com/articles/automated-certificate-management) does not support wildcard domains, so each CNAME
subdomain will need a separate heroku DNS Target.)
To view a Site locally, use a `site` parameter, e.g. . This parameter *sets a cookie* so future page requests will stay on that site; this is a convenience for localhost development and should not be used in a production environment (and if it is used, it may override the *real* site as specified by the subdomain).
@@ -101,7 +144,7 @@ To view a Site locally, use a `site` parameter, e.g. `Cook Food`)
2. create a new subdir inside `public/lessons` (e.g. `public/lessons/cook_food/`)
-3. define a `Track` subclass in a new file inside that dir (e.g. `public/lessons/cook_food/cook_food.rb`) and
+3. define a `Track` subclass in a new file inside that dir (e.g. `public/lessons/cook_food/cook_food.rb`) and
4. declare your lessons inside the track file. Look at the existing `.rb` files inside `public/lessons` for examples.
5. for each Lesson, put its slides in a markdown file with its name in the lessons directory (e.g. `public/lessons/cook_food/stirfry.md`)
6. add the Track to your Site by following the example of [Bootcamp](lib/bootcamp.rb)
@@ -123,5 +166,4 @@ We should clean this up, so we don't have duplication/omission of e.g. project d
If you rename a track or lesson, add an entry to `config.ru` so external links to the old name do not become dead links.
-`config.ru` also rewrites incoming URLs containing underscores, converting from snake_case to kebab-case for lessons, projects, etc. -- but **NOT** for image files and other media -- and the app can find lesson etc. files in either snake_case or kebab-case format.
-
+`config.ru` also rewrites incoming URLs containing underscores, converting from snake_case to kebab-case for lessons, projects, etc. -- but **NOT** for image files and other media -- and the app can find lesson etc. files in either snake_case or kebab-case format.
diff --git a/Rakefile b/Rakefile
index 8efd48b5..8667a0d1 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,4 +1,5 @@
require 'rspec/core/rake_task'
+require 'rake/notes/rake_task'
task :default => :spec
@@ -18,17 +19,16 @@ task :build_css do
sass_dir = File.join public_dir, "scss"
images_dir = File.join public_dir, "images"
javascripts_dir = File.join public_dir, "js"
- bootstrap_dir = File.join sass_dir, "bootstrap-4.0.0-beta.2/scss"
+ bootstrap_dir = File.join sass_dir, "bootstrap-4.3.1/scss"
puts "Building CSS..."
scss_file = File.join(sass_dir, "app.scss")
css_file = File.join(css_dir, "app.css")
- if File.mtime(scss_file) > File.mtime(css_file)
- sh(["sass",
+ if !File.exist?(css_file) || File.mtime(scss_file) > File.mtime(css_file)
+ sh(["bin/sass",
"--load-path #{bootstrap_dir}",
- "--line-numbers", # adds comments inside the .css file
- "--line-comments", # creates a .map file
+ "--style compressed",
scss_file,
css_file,
].join(" "))
@@ -45,7 +45,6 @@ task :build => [
puts "Built."
end
-require 'awesome_print'
desc "run app and keep building and running it"
task :rerun do
cmd = %w{bundle exec rerun -- rackup}
@@ -54,5 +53,15 @@ end
desc "run app"
task :run => :build do
- sh "rackup"
+ sh "bundle exec rackup"
+end
+
+desc "clean"
+task :clean do
+ public_dir = "public"
+ css_dir = File.join public_dir, "css"
+ css_file = File.join(css_dir, "app.css")
+ map_file = File.join(css_dir,"app.css.map")
+ File.delete(css_file)
+ File.delete(map_file)
end
diff --git a/app.json b/app.json
new file mode 100644
index 00000000..e1239155
--- /dev/null
+++ b/app.json
@@ -0,0 +1,64 @@
+{
+ "addons": [
+ "librato",
+ "papertrail",
+ "rollbar"
+ ],
+ "buildpacks": [
+ {
+ "url": "heroku/metrics"
+ },
+ {
+ "url": "heroku/ruby"
+ }
+ ],
+ "description": "Burlington Code Academy curriculum content",
+ "env": {
+ "LANG": {
+ "required": true
+ },
+ "LIBRATO_PASSWORD": {
+ "required": true
+ },
+ "LIBRATO_TOKEN": {
+ "required": true
+ },
+ "LIBRATO_USER": {
+ "required": true
+ },
+ "PAPERTRAIL_API_TOKEN": {
+ "required": true
+ },
+ "RACK_ENV": {
+ "required": true
+ },
+ "ROLLBAR_ACCESS_TOKEN": {
+ "required": true
+ },
+ "ROLLBAR_ENDPOINT": {
+ "required": true
+ }
+ },
+ "formation": {
+ "web": {
+ "quantity": 1
+ }
+ },
+ "name": "codelikethis",
+ "scripts": {
+ },
+ "stack": "heroku-18",
+ "environments": {
+ "review": {
+ "addons": [],
+ "env": {
+ "LANG": {
+ "required": true
+ },
+ "RACK_ENV": {
+ "required": true
+ }
+ }
+ }
+ }
+}
diff --git a/app.rb b/app.rb
index 9436ddd8..b2e514b0 100644
--- a/app.rb
+++ b/app.rb
@@ -1,20 +1,18 @@
-require 'sinatra/base'
-require "sinatra/cookies"
-
-require 'erector'
-require 'deck/slide'
-require 'deck/slide_deck'
-require 'deck/rack_app'
+# frozen_string_literal: true
# add "lib" dir to Ruby load path
here = ::File.expand_path(File.dirname(__FILE__))
lib = "#{here}/lib"
-$: << lib
+$LOAD_PATH << lib
+require 'sinatra/base'
+require 'sinatra/cookies'
+require 'erector'
+require 'deck/slide'
+require 'deck/slide_deck'
+require 'deck/rack_app'
require 'util'
-require "hash_extensions"
-# require_all(lib)
-
+require 'hash_extensions'
require 'site'
require 'app_page'
require 'tracks_table'
@@ -25,8 +23,7 @@ module AppHelpers
def page_title object, extra = nil
[
(object.display_name rescue object.to_s),
- extra,
- "- Code Like This"
+ extra
].compact.join(' ')
end
end
@@ -37,7 +34,15 @@ class App < Sinatra::Base
include Erector::Mixin
include AppHelpers
+ if ENV['ROLLBAR_ACCESS_TOKEN']
+ require 'rollbar/middleware/sinatra'
+ use Rollbar::Middleware::Sinatra
+ end
+
+ set :static_cache_control, [:public, :max_age => 300]
+
before do
+ cache_control :public, max_age: 300
Thread.current[:development_mode] = (request.host =~ /^(localhost|127\.0\.0\.1)$/)
end
@@ -67,6 +72,10 @@ def view
end
end
+ get '/favicon.ico' do
+ send_file(File.join(here, "public", "images", "favicon.ico"))
+ end
+
get '/lessons' do
page(thing: Tracks.new(site: site)).to_html
end
@@ -170,6 +179,20 @@ def find_file_in_tracks first_dir, filename
page(thing: project).to_html
end
+ get "/references" do
+ page(thing: site.references).to_html
+ end
+
+ get "/references/:file.:ext" do
+ path = File.join(here, "public", "references", "#{params[:file]}.#{params[:ext]}")
+ send_file(path)
+ end
+
+ get "/references/:reference_name" do
+ reference = Reference.new(name: params[:reference_name])
+ page(thing: reference).to_html
+ end
+
get "/schedule" do
if (site && site.schedule)
page(thing: site.schedule).to_html
@@ -179,7 +202,7 @@ def find_file_in_tracks first_dir, filename
end
get "/topics/:topic_name" do
- # todo: make this actually work
+ # TODO: make this actually work
topic = Topic.new(name: params[:topic_name], site: site)
page(thing: topic).to_html
end
@@ -217,17 +240,17 @@ def create_site
end
site = [
- CodeLikeThis,
Bootcamp,
JavascriptAfterHours,
Curriculum,
- Taste
+ Taste,
+ CodeLikeThis,
].map(&:new).detect do |site|
site.host? sitename
end
if site.nil?
- @warning = "No site found for #{sitename}; using CodeLikeThis content."
- site = CodeLikeThis.new
+ @warning = "No site found for #{sitename}; using Bootcamp content."
+ site = Bootcamp.new
end
site
end
diff --git a/bin/sass b/bin/sass
new file mode 100755
index 00000000..0aae53f6
--- /dev/null
+++ b/bin/sass
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'sass' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
+
+bundle_binstub = File.expand_path("../bundle", __FILE__)
+
+if File.file?(bundle_binstub)
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+ load(bundle_binstub)
+ else
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+ end
+end
+
+require "rubygems"
+require "bundler/setup"
+
+load Gem.bin_path("sass", "sass")
diff --git a/bin/sass-convert b/bin/sass-convert
new file mode 100755
index 00000000..bd0a00b4
--- /dev/null
+++ b/bin/sass-convert
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'sass-convert' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
+
+bundle_binstub = File.expand_path("../bundle", __FILE__)
+
+if File.file?(bundle_binstub)
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+ load(bundle_binstub)
+ else
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+ end
+end
+
+require "rubygems"
+require "bundler/setup"
+
+load Gem.bin_path("sass", "sass-convert")
diff --git a/bin/scss b/bin/scss
new file mode 100755
index 00000000..64605035
--- /dev/null
+++ b/bin/scss
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'scss' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
+
+bundle_binstub = File.expand_path("../bundle", __FILE__)
+
+if File.file?(bundle_binstub)
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+ load(bundle_binstub)
+ else
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+ end
+end
+
+require "rubygems"
+require "bundler/setup"
+
+load Gem.bin_path("sass", "scss")
diff --git a/config.ru b/config.ru
index b80d8427..a8da40cc 100644
--- a/config.ru
+++ b/config.ru
@@ -1,46 +1,70 @@
require './app'
require 'rack/rewrite'
+require 'rack/cache'
-use Rack::ShowExceptions
+# Production/Staging level services or config
+require 'newrelic_rpm' if ENV['NEW_RELIC_LICENSE_KEY']
+if ENV['ROLLBAR_ACCESS_TOKEN']
+ require 'rollbar'
+ Rollbar.configure do |config|
+ config.access_token = ENV['ROLLBAR_ACCESS_TOKEN']
+ end
+end
+if ENV['RACK_ENV'] == 'production'
+ require 'rack/ssl'
+ use Rack::SSL
+end
+
+use Rack::Cache
+use Rack::ConditionalGet
+use Rack::ETag
+use Rack::Deflater
use Rack::ShowStatus
# https://github.com/jtrupiano/rack-rewrite
use Rack::Rewrite do
-
moved_permanently %r{^/(.*)/+$}, '/$1' # always remove trailing /
-
moved_permanently %r{^(/lessons/learn[_-]to[_-]code[_-]with[_-]javascript)(/.*)?$}, (lambda do |match, env|
"/lessons/javascript#{match[2] && match[2].gsub(/_+/, '-')}"
end)
-
# replace underscores with dashes...
moved_permanently %r{^.*_.*$}, (lambda do |match, env|
match[0].gsub(/_+/, '-')
end), :if => (lambda do |rack_env|
# ...except for media file requests
- rack_env["REQUEST_PATH"] !~ /\.(jpg|jpeg|gif|png|svg|js|css|html|mp4|wav|mp3)$/
+ rack_env["REQUEST_PATH"] !~ /\.(jpg|jpeg|gif|png|svg|js|css|scss|html|mp4|wav|mp3)$/
end)
- moved_permanently '/lessons/learn_to_code/learn_to_code', '/lessons/learn_to_code/intro'
- moved_permanently '/lessons/ruby_advanced/intro', '/lessons/ruby/ruby_for_programmers'
- moved_permanently '/lessons/ruby/intro', '/lessons/ruby/ruby_for_programmers'
- moved_permanently '/lessons/javascript/dom', '/lessons/client_side_coding/dom'
- moved_permanently '/lessons/javascript/jquery', '/lessons/client_side_coding/jquery'
- moved_permanently '/lessons/javascript/ajax', '/lessons/client_side_coding/ajax'
- moved_permanently '/lessons/javascript/filter-functions', '/lessons/javascript/iteration-methods'
+ moved_permanently '/lessons/learn_to_code/learn_to_code',
+ '/lessons/learn_to_code/intro'
+ moved_permanently '/lessons/ruby_advanced/intro',
+ '/lessons/ruby/ruby_for_programmers'
+ moved_permanently '/lessons/ruby/intro',
+ '/lessons/ruby/ruby_for_programmers'
+ moved_permanently '/lessons/javascript/dom',
+ '/lessons/client_side_coding/dom'
+ moved_permanently '/lessons/javascript/jquery',
+ '/lessons/client_side_coding/jquery'
+ moved_permanently '/lessons/javascript/ajax',
+ '/lessons/client_side_coding/ajax'
+ moved_permanently '/lessons/javascript/filter-functions',
+ '/lessons/javascript/iteration-methods'
moved_permanently '/lessons/test_driven/test_driven',
'/lessons/agile_development/test_driven'
# renamed tracks
{
- ruby_advanced: 'ruby',
- agile_development: 'agile',
- the_world_wide_web: 'www',
+ ruby_advanced: 'ruby',
+ agile_development: 'agile',
+ the_world_wide_web: 'www'
}.each_pair do |old_name, new_name|
moved_permanently %r{/lessons/#{old_name}(/\w*)?}, "/lessons/#{new_name}$1"
end
end
-run Rack::Cascade.new([
- App,
- Deck::RackApp.build([]) # so support files from the deckrb gem get served too
- ])
+# Support files from the deckrb gem get served too
+run Rack::Cascade.new(
+ [
+ App,
+ Deck::RackApp.build([])
+ ]
+)
diff --git a/config/puma.rb b/config/puma.rb
new file mode 100644
index 00000000..c6f09057
--- /dev/null
+++ b/config/puma.rb
@@ -0,0 +1,17 @@
+require 'barnes'
+
+workers Integer(ENV['WEB_CONCURRENCY'] || 2)
+
+min_threads = Integer(ENV['MIN_THREADS'] || 1)
+max_threads = Integer(ENV['MAX_THREADS'] || 4)
+threads min_threads, max_threads
+
+preload_app!
+
+rackup DefaultRackup
+port ENV['PORT'] || 3000
+environment ENV['RACK_ENV'] || 'development'
+
+before_fork do
+ Barnes.start
+end
diff --git a/fontawesome-free-5.0.4.zip b/fontawesome-free-5.0.4.zip
deleted file mode 100644
index e300a8d0..00000000
Binary files a/fontawesome-free-5.0.4.zip and /dev/null differ
diff --git a/lib/app_page.rb b/lib/app_page.rb
index 15fd96cc..fe75e77f 100644
--- a/lib/app_page.rb
+++ b/lib/app_page.rb
@@ -19,7 +19,7 @@ class ThingPage < AppPage
include Views
def doctype
- ''
+ ''
end
def html_attributes
@@ -34,7 +34,7 @@ def page_title
].compact.uniq.join(' - ')
end
- # todo: promote into Page
+ # TODO: promote into Page
# font_name: if nil, use href param
# href: if nil or default, use local path /name.css
def font name: nil, href: nil
@@ -43,19 +43,6 @@ def font name: nil, href: nil
link rel: "stylesheet", href: href, type: "text/css", charset: "utf-8"
end
- # todo: promote into Page
- def stylesheet attributes = {}
- href = if attributes[:href]
- href
- elsif attributes[:name]
- "/css/#{attributes[:name]}.css"
- else
- raise "requires either a name or an href"
- end
- link_attributes = {rel: "stylesheet", href: href}.merge(attributes)
- link(link_attributes)
- end
-
def head_content
super
@@ -68,95 +55,44 @@ def head_content
meta name: 'keywords', content: @thing.topics.map(&:name).join(',')
end
- # todo: parameterize bootstrap version
- # todo: parameterize using CDN vs local file
- stylesheet href: "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css",
- integrity: "sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb",
+ stylesheet href: "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css",
+ integrity: "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T",
crossorigin: "anonymous"
+ stylesheet name: 'app'
- font name: "fonts/Museo500"
- font href: "https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700|Raleway:600"
-
- stylesheet name: "github-markdown" # from https://github.com/sindresorhus/github-markdown-css/blob/gh-pages/github-markdown.css
-
- # load this application's CSS from /css/app.css
- stylesheet name: "app"
+ end
- # todo: parameterize using CDN vs local file for jQuery
- script src: "https://code.jquery.com/jquery-3.2.1.slim.min.js",
- integrity: "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN",
+ def body_scripts
+ script defer: "defer",
+ src: "https://code.jquery.com/jquery-3.4.1.slim.min.js",
+ integrity: "sha256-pasqAKBDmFT4eHoN2ndd6lN370kFiGUFyTiUHWhU7k8=",
crossorigin: "anonymous"
- # todo: use local file for jQuery if CDN failed
- # todo: parameterize location of local file
- # script raw("window.jQuery || document.write('
HTML
end
@@ -45,8 +57,8 @@ def munge_md text
text.gsub('', "\n" )
end
- # todo: test
- # todo: unify with Deck::Slide's markdown munging
+ # TODO: test
+ # TODO: unify with Deck::Slide's markdown munging
def munge_html html
lines = (["
"] +
html.split("\n").map do |line|
diff --git a/public/css/app.css b/public/css/app.css
deleted file mode 100644
index 2532c4cd..00000000
--- a/public/css/app.css
+++ /dev/null
@@ -1,493 +0,0 @@
-/* line 2, ../scss/tables.scss */
-.slide table {
- display: table;
- border-collapse: collapse;
- border-spacing: 2px;
- border-color: gray;
- margin: 15px 0; }
-/* line 10, ../scss/tables.scss */
-.slide table tr {
- border-top: 1px solid #CCC;
- background-color: white;
- margin: 0;
- padding: 0; }
-/* line 17, ../scss/tables.scss */
-.slide table tr th, .slide table tr td {
- border: 1px solid #CCC;
- text-align: left;
- margin: 0;
- padding: 6px 13px; }
-/* line 24, ../scss/tables.scss */
-.slide table thead tr {
- background-color: #F2F2F8; }
-/* line 28, ../scss/tables.scss */
-.slide table tr:nth-child(2n) {
- background-color: #F8F8F8; }
-
-/* line 13, ../scss/app.scss */
-body {
- font-family: "Open Sans", Helvetica, Arial, sans-serif;
- font-weight: normal;
- font-size: 1rem;
- text-rendering: optimizelegibility;
- padding-top: 75px; }
-
-@media print {
- /* line 23, ../scss/app.scss */
- nav.navbar, #sidebar, .twitter, div.notice, a[name=content] {
- display: none !important; }
-
- /* line 26, ../scss/app.scss */
- body {
- padding-top: 0; } }
-/* line 31, ../scss/app.scss */
-nav.navbar {
- background: white;
- font-family: "Raleway", Helvetica, Arial, sans-serif;
- text-transform: uppercase;
- font-weight: 600;
- font-size: 13px;
- font-style: normal;
- height: 75px;
- /* so the logo doesn't push the hamburger down on narrow screens */ }
- /* line 40, ../scss/app.scss */
- nav.navbar.navbar-light .navbar-nav .nav-link {
- color: #333333; }
- /* line 42, ../scss/app.scss */
- nav.navbar.navbar-light .navbar-nav .nav-link.btn-sm {
- font-weight: 600;
- font-size: 13px;
- color: white;
- background-color: #f7931e;
- border-color: #f7931e;
- padding: 1em 1.5em; }
- /* line 52, ../scss/app.scss */
- nav.navbar li {
- padding-left: 7px;
- padding-right: 7px; }
- /* line 56, ../scss/app.scss */
- nav.navbar a {
- letter-spacing: 1px;
- zoom: 1; }
- /* line 64, ../scss/app.scss */
- nav.navbar .col.navbar-left {
- max-width: 75%; }
- /* line 66, ../scss/app.scss */
- nav.navbar .col.navbar-left a.navbar-brand {
- max-width: 100%; }
- /* line 68, ../scss/app.scss */
- nav.navbar .col.navbar-left a.navbar-brand img.logo {
- height: 74px;
- width: auto;
- vertical-align: middle;
- max-height: 75px; }
- /* line 77, ../scss/app.scss */
- nav.navbar .navbar-collapse.collapse.show {
- position: fixed;
- overflow: scroll;
- top: 75px;
- left: 0;
- right: 0;
- background-color: white;
- border: 1px solid gray; }
- /* line 87, ../scss/app.scss */
- nav.navbar .navbar-collapse.collapse.show .dropdown.show {
- padding-left: 3.5em; }
- /* line 93, ../scss/app.scss */
- nav.navbar li.nav-item.bordered {
- border: 1px solid black;
- border-radius: .25rem; }
- @media (max-width: 767px) {
- /* line 99, ../scss/app.scss */
- nav.navbar #pageNavbar {
- padding-bottom: 1rem;
- border-bottom: 1px solid lightgray; } }
-
-/* line 108, ../scss/app.scss */
-main {
- background-color: white;
- max-width: 80em; }
- /* line 111, ../scss/app.scss */
- main center.logo {
- padding: 1rem; }
- /* line 114, ../scss/app.scss */
- main h1, main h2, main h3, main h4, main h5 {
- font-family: "Museo500Regular", "Open Sans", Helvetica, Arial, sans-serif; }
- /* line 117, ../scss/app.scss */
- main img {
- max-width: 100%; }
- /* line 120, ../scss/app.scss */
- main blockquote {
- background: #f9f9f9;
- border-left: 10px solid #ccc;
- margin: 1.5em 0.5em;
- padding: 0.5em;
- font-style: italic;
- font-size: 110%; }
-
-/* line 130, ../scss/app.scss */
-section.slide {
- padding: 1em;
- margin-bottom: 2em;
- margin-top: 3em;
- border: 1px solid black; }
- /* line 136, ../scss/app.scss */
- section.slide h1, section.slide > h2:first-child {
- text-decoration: lightblue underline; }
- /* line 139, ../scss/app.scss */
- section.slide > h2:first-child {
- margin: 2px 0 8px -4px;
- font-size: 2rem; }
- /* line 143, ../scss/app.scss */
- section.slide > h1 {
- font-size: 3em; }
- /* line 148, ../scss/app.scss */
- section.slide.subsection > h1 {
- background-color: #e8e8fc;
- text-align: center; }
- /* line 152, ../scss/app.scss */
- section.slide.subsection > h2:first-child {
- font-size: 3em; }
- /* line 157, ../scss/app.scss */
- section.slide h1 code, section.slide h2 code {
- color: inherit;
- padding: inherit;
- background-color: inherit; }
- /* line 163, ../scss/app.scss */
- section.slide blockquote {
- font-style: italic;
- border-left: 2px solid #ddd;
- padding-left: 1em;
- font-size: 110%;
- background-color: wheat;
- color: black; }
- /* line 172, ../scss/app.scss */
- section.slide li {
- margin-bottom: .5em; }
- /* line 176, ../scss/app.scss */
- section.slide li:first-child {
- margin-top: .5em; }
- /* line 180, ../scss/app.scss */
- section.slide pre {
- white-space: pre-wrap;
- word-wrap: break-word;
- border: 1px solid #ccc;
- background: #f8f8f5;
- padding: .5em;
- /* display: inline-block; /* so it's only as wide as its contents */ }
-
-/* line 190, ../scss/app.scss */
-div.right_side {
- float: right;
- max-width: 24em; }
-
-/* line 195, ../scss/app.scss */
-div.twitter {
- padding-left: 1em; }
-
-/* line 199, ../scss/app.scss */
-div.blog .rssHeader > a:after {
- content: " - Recent Blog Entries"; }
-
-/* left sidebar ("Tracks") */
-/* line 211, ../scss/app.scss */
-.tracks-toggler {
- padding: .25rem .75rem;
- font-size: 1.25rem;
- line-height: 1;
- background: 0 0; }
- @media (min-width: 768px) {
- /* line 211, ../scss/app.scss */
- .tracks-toggler {
- display: none; } }
- /* line 24, /Volumes/Mead/Dropbox/dev/codelikethis/public/scss/bootstrap-4.0.0-beta.2/scss/mixins/_hover.scss */
- .tracks-toggler:focus, .tracks-toggler:hover {
- text-decoration: none; }
-
-/* line 226, ../scss/app.scss */
-.tracks-toggler span.svg-icon, .toggler span.svg-icon {
- background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpolygon points='1,1 30,1 15,30 1,1' style='fill:gray;stroke:black;stroke-width:1' /%3E%3C/svg%3E"); }
-/* line 229, ../scss/app.scss */
-.tracks-toggler.collapsed span.svg-icon, .toggler.collapsed span.svg-icon {
- background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpolygon points='1,1 1,30 30,15 1,1' style='fill:gray;stroke:black;stroke-width:1' /%3E%3C/svg%3E"); }
-
-/* line 234, ../scss/app.scss */
-span.svg-icon {
- display: inline-block;
- width: 0.75em;
- height: 0.75em;
- vertical-align: middle;
- content: "";
- background-size: 100% 100%;
- background-repeat: no-repeat;
- background-position-x: center;
- background-position-y: center; }
-
-/* line 248, ../scss/app.scss */
-.link .icon.freecodecamp img {
- width: 30px;
- height: 24px;
- margin: 2px 4px;
- background: green;
- border: 2px solid green; }
-/* line 257, ../scss/app.scss */
-.link .icon.codecademy img {
- width: 40px;
- height: 40px;
- margin: 2px 2px;
- border: none; }
-/* line 266, ../scss/app.scss */
-.link.topic a, .link.topic a:visited {
- font-size: 80%;
- color: black;
- background: lavender;
- border: 1px solid purple;
- border-radius: 4px;
- padding: 3px 6px;
- margin: 2px;
- display: inline-block; }
-
-/* line 280, ../scss/app.scss */
-.box {
- border: 1px solid black;
- padding: 1em;
- margin: 1em 0; }
- /* line 285, ../scss/app.scss */
- .box h2, .box h3, .box h4 {
- text-decoration: underline;
- font-family: "Open Sans", Helvetica, Arial, sans-serif; }
- /* line 290, ../scss/app.scss */
- .box pre {
- background: #ededfc; }
-
-/* make the sidebars scrolly and fixed on bigger screens */
-@media (min-width: 768px) {
- /* line 297, ../scss/app.scss */
- #sidebar, #right-sidebar {
- display: block;
- max-height: calc(100vh - 75px);
- overflow-y: auto;
- position: sticky;
- top: 75px;
- z-index: 1000;
- padding-top: 1rem; }
-
- /* line 309, ../scss/app.scss */
- a[name=content] {
- display: block;
- position: relative;
- height: 75px; }
-
- /* line 314, ../scss/app.scss */
- a.slide-anchor {
- display: block;
- position: relative;
- visibility: hidden;
- height: 0;
- top: -75px; } }
-@media (min-width: 768px) {
- /* line 323, ../scss/app.scss */
- #sidebar-tracks {
- display: block; } }
-
-@media (max-width: 767px) {
- /* line 332, ../scss/app.scss */
- #sidebar {
- border-bottom: 1px solid lightgray;
- border-top: 1px solid lightgray; }
- /* line 335, ../scss/app.scss */
- #sidebar h1, #sidebar h2, #sidebar h3, #sidebar h4 {
- margin: 2px 0; } }
-/* line 341, ../scss/app.scss */
-#sidebar-tracks, #right-sidebar > .outline > .list-group {
- font-size: 85%; }
- /* line 344, ../scss/app.scss */
- #sidebar-tracks .list-group.lesson-names, #right-sidebar > .outline > .list-group .list-group.lesson-names {
- margin-top: .5rem;
- border-radius: 0; }
- /* line 347, ../scss/app.scss */
- #sidebar-tracks .list-group.lesson-names .list-group-item, #right-sidebar > .outline > .list-group .list-group.lesson-names .list-group-item {
- padding: .4rem 0 .4rem 1.8rem;
- margin: 0 -1rem; }
- /* line 353, ../scss/app.scss */
- #sidebar-tracks .list-group.lesson-names .loading_image, #right-sidebar > .outline > .list-group .list-group.lesson-names .loading_image {
- background-image: url(/images/loading.gif);
- background-repeat: no-repeat;
- background-position: center;
- background-size: contain;
- height: 18px;
- width: 18px;
- float: right;
- margin: 0 2px;
- display: none; }
- /* line 368, ../scss/app.scss */
- #sidebar-tracks .active, #right-sidebar > .outline > .list-group .active {
- background-color: #EEF; }
- /* line 371, ../scss/app.scss */
- #sidebar-tracks a, #right-sidebar > .outline > .list-group a {
- color: black;
- display: inline-block;
- width: 100%; }
-
-/* line 379, ../scss/app.scss */
-#sidebar-tracks a.track-info-link {
- display: inline;
- position: absolute;
- padding: 0 0;
- margin: -4px 2px;
- width: 28px;
- text-align: center;
- vertical-align: center;
- font-size: 150%;
- right: 2px;
- visibility: hidden; }
-/* line 394, ../scss/app.scss */
-#sidebar-tracks div.track-name:hover a.track-info-link {
- visibility: visible;
- background-color: white; }
-
-/* line 400, ../scss/app.scss */
-.dropdown-menu a.track-name {
- text-transform: none; }
-
-/* line 404, ../scss/app.scss */
-section.breadcrumbs {
- background-color: #f7f7f7;
- border-top: 1px solid #e6e0e6;
- border-bottom: 1px solid #e6e0e6;
- padding: .5em; }
- /* line 410, ../scss/app.scss */
- section.breadcrumbs > .row {
- max-width: 100em;
- margin: auto; }
- /* line 415, ../scss/app.scss */
- section.breadcrumbs h1.lesson-name {
- font-family: "Museo500Regular", "Open Sans", Helvetica, Arial, sans-serif;
- margin-bottom: 0;
- line-height: 1.0; }
- /* line 421, ../scss/app.scss */
- section.breadcrumbs a.next_lesson, section.breadcrumbs a.previous_lesson {
- font-size: 80%;
- font-weight: bold;
- font-style: italic; }
- /* line 427, ../scss/app.scss */
- section.breadcrumbs a {
- color: black; }
-
-/* line 432, ../scss/app.scss */
-div#disqus_thread {
- border: 1px solid gray;
- padding: 1em; }
-
-/* line 437, ../scss/app.scss */
-div.main_column img {
- max-width: 100%; }
-
-/* line 441, ../scss/app.scss */
-footer {
- clear: both;
- padding: 2rem;
- border-top: 1px solid #EEEEEE;
- text-align: center;
- max-width: 60em;
- margin: auto; }
-
-/* line 450, ../scss/app.scss */
-.video-container {
- position: relative;
- padding-bottom: 56.25%;
- /* 16:9 */
- padding-top: 25px;
- height: 0;
- overflow: hidden;
- margin: 1em;
- border: 6px solid gray; }
- /* line 459, ../scss/app.scss */
- .video-container iframe, .video-container object, .video-container embed {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%; }
-
-/* line 468, ../scss/app.scss */
-table {
- border: 2px solid gray;
- border-collapse: collapse;
- box-shadow: #c8c8f1 2px 2px 4px; }
- /* line 473, ../scss/app.scss */
- table ul {
- list-style: none;
- -webkit-margin-before: 0;
- -webkit-margin-after: 0;
- -webkit-margin-start: 0;
- -webkit-margin-end: 0;
- -webkit-padding-start: 0; }
- /* line 481, ../scss/app.scss */
- table td.lessons {
- font-size: 90%;
- padding-top: .5em; }
- /* line 485, ../scss/app.scss */
- table, table td, table th {
- border: 1px solid black;
- padding: 4px 8px 8px; }
- /* line 489, ../scss/app.scss */
- table th {
- text-shadow: 1px 1px #ededed;
- background-color: #B3C8E8; }
- /* line 495, ../scss/app.scss */
- table tr:nth-child(even) {
- background-color: #EEEEF2; }
- /* line 498, ../scss/app.scss */
- table tr:nth-child(odd) {
- background-color: #FFFFFF; }
- /* line 501, ../scss/app.scss */
- table a {
- text-decoration: none;
- display: block;
- padding: 2px; }
- /* line 506, ../scss/app.scss */
- table a:hover {
- text-decoration: underline;
- background-color: #B3C8E8; }
- /* line 510, ../scss/app.scss */
- table a:visited {
- color: black; }
-
-/* line 515, ../scss/app.scss */
-.markdown {
- padding-left: 4em; }
- /* line 517, ../scss/app.scss */
- .markdown h1 {
- margin-left: -2em; }
- /* line 520, ../scss/app.scss */
- .markdown h2 {
- margin-left: -2em; }
- /* line 523, ../scss/app.scss */
- .markdown h3 {
- margin-left: -1em; }
- /* line 527, ../scss/app.scss */
- .markdown kbd {
- display: inline-block;
- padding: 3px 5px;
- font-size: 11px;
- line-height: 10px;
- color: #444d56;
- vertical-align: middle;
- background-color: #fafbfc;
- border: solid 1px #c6cbd1;
- border-bottom-color: #959da5;
- border-radius: 3px;
- box-shadow: inset 0 -1px 0 #959da5; }
-
-/* line 543, ../scss/app.scss */
-span.video_link {
- border: 1px dotted black;
- padding: 1px 2px;
- margin-left: 1em; }
- @media screen {
- /* line 543, ../scss/app.scss */
- span.video_link {
- float: right; } }
-
-/*# sourceMappingURL=app.css.map */
diff --git a/public/css/app.css.map b/public/css/app.css.map
deleted file mode 100644
index 78f46b45..00000000
--- a/public/css/app.css.map
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-"version": 3,
-"mappings": "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",
-"sources": ["../scss/tables.scss","../scss/app.scss","../scss/bootstrap-4.0.0-beta.2/scss/mixins/_breakpoints.scss","../scss/bootstrap-4.0.0-beta.2/scss/mixins/_hover.scss"],
-"names": [],
-"file": "app.css"
-}
diff --git a/public/css/slides.css b/public/css/slides.css
index 5efb4204..42de36b6 100644
--- a/public/css/slides.css
+++ b/public/css/slides.css
@@ -1,5 +1,5 @@
/* overrides for deckrb theme CSS */
-/* todo: switch to scss and add to the build */
+/* TODO: switch to scss and add to the build */
section.box {
border: 2px solid black;
diff --git a/public/projects/247Moms-1.png b/public/images/247Moms-1.png
similarity index 100%
rename from public/projects/247Moms-1.png
rename to public/images/247Moms-1.png
diff --git a/public/projects/247Moms-2.png b/public/images/247Moms-2.png
similarity index 100%
rename from public/projects/247Moms-2.png
rename to public/images/247Moms-2.png
diff --git a/public/projects/247Moms-3.png b/public/images/247Moms-3.png
similarity index 100%
rename from public/projects/247Moms-3.png
rename to public/images/247Moms-3.png
diff --git a/public/lessons/images/ASCII-Table-wide.svg b/public/images/ASCII-Table-wide.svg
similarity index 100%
rename from public/lessons/images/ASCII-Table-wide.svg
rename to public/images/ASCII-Table-wide.svg
diff --git a/public/projects/Mint-Login-Screen.png b/public/images/Mint-Login-Screen.png
similarity index 100%
rename from public/projects/Mint-Login-Screen.png
rename to public/images/Mint-Login-Screen.png
diff --git a/public/images/React-icon.svg b/public/images/React-icon.svg
new file mode 100644
index 00000000..5592ebec
--- /dev/null
+++ b/public/images/React-icon.svg
@@ -0,0 +1,35 @@
+
+
+
+
diff --git a/public/lessons/images/Von_Neumann_Architecture.svg b/public/images/Von_Neumann_Architecture.svg
similarity index 100%
rename from public/lessons/images/Von_Neumann_Architecture.svg
rename to public/images/Von_Neumann_Architecture.svg
diff --git a/public/lessons/agile/agile-retrospectives.jpg b/public/images/agile-retrospectives.jpg
similarity index 100%
rename from public/lessons/agile/agile-retrospectives.jpg
rename to public/images/agile-retrospectives.jpg
diff --git a/public/lessons/images/bash-cursor-shortcuts.jpg b/public/images/bash-cursor-shortcuts.jpg
similarity index 100%
rename from public/lessons/images/bash-cursor-shortcuts.jpg
rename to public/images/bash-cursor-shortcuts.jpg
diff --git a/public/lessons/agile/zen/buddha-statue.jpg b/public/images/buddha-statue.jpg
similarity index 100%
rename from public/lessons/agile/zen/buddha-statue.jpg
rename to public/images/buddha-statue.jpg
diff --git a/public/images/burlingtoncodeacademy-logo.png b/public/images/burlingtoncodeacademy-logo.png
index bd3c5e3a..d185f009 100644
Binary files a/public/images/burlingtoncodeacademy-logo.png and b/public/images/burlingtoncodeacademy-logo.png differ
diff --git a/public/images/by-cs-sa-license.png b/public/images/by-cs-sa-license.png
new file mode 100644
index 00000000..3c1980c4
Binary files /dev/null and b/public/images/by-cs-sa-license.png differ
diff --git a/public/images/callback-example.png b/public/images/callback-example.png
new file mode 100644
index 00000000..93a0a560
Binary files /dev/null and b/public/images/callback-example.png differ
diff --git a/public/lessons/responsive_layout/centered-flexbox.png b/public/images/centered-flexbox.png
similarity index 100%
rename from public/lessons/responsive_layout/centered-flexbox.png
rename to public/images/centered-flexbox.png
diff --git a/public/images/chrome-debugger.png b/public/images/chrome-debugger.png
new file mode 100644
index 00000000..f386c643
Binary files /dev/null and b/public/images/chrome-debugger.png differ
diff --git a/public/lessons/git/chunky-monkey-detail.png b/public/images/chunky-monkey-detail.png
similarity index 100%
rename from public/lessons/git/chunky-monkey-detail.png
rename to public/images/chunky-monkey-detail.png
diff --git a/public/images/codecademy-logo-400x400.jpg b/public/images/codecademy-logo-400x400.jpg
index 430136a7..05ab8f35 100644
Binary files a/public/images/codecademy-logo-400x400.jpg and b/public/images/codecademy-logo-400x400.jpg differ
diff --git a/public/images/codelikethis-logo.png b/public/images/codelikethis-logo.png
index 8ee41c23..cd4ab9b2 100644
Binary files a/public/images/codelikethis-logo.png and b/public/images/codelikethis-logo.png differ
diff --git a/public/lessons/www/complex_url.png b/public/images/complex_url.png
similarity index 100%
rename from public/lessons/www/complex_url.png
rename to public/images/complex_url.png
diff --git a/public/lessons/server_side_javascript/content-type.png b/public/images/content-type.png
similarity index 100%
rename from public/lessons/server_side_javascript/content-type.png
rename to public/images/content-type.png
diff --git a/public/images/control-flow.png b/public/images/control-flow.png
new file mode 100644
index 00000000..72196177
Binary files /dev/null and b/public/images/control-flow.png differ
diff --git a/public/lessons/images/cookie-recipe.gif b/public/images/cookie-recipe.gif
similarity index 100%
rename from public/lessons/images/cookie-recipe.gif
rename to public/images/cookie-recipe.gif
diff --git a/public/lessons/images/cornedbeefhash.jpeg b/public/images/cornedbeefhash.jpeg
similarity index 100%
rename from public/lessons/images/cornedbeefhash.jpeg
rename to public/images/cornedbeefhash.jpeg
diff --git a/public/images/crc-chat.jpg b/public/images/crc-chat.jpg
new file mode 100644
index 00000000..c8336dd7
Binary files /dev/null and b/public/images/crc-chat.jpg differ
diff --git a/public/lessons/images/css-is-awesome.jpg b/public/images/css-is-awesome.jpg
similarity index 100%
rename from public/lessons/images/css-is-awesome.jpg
rename to public/images/css-is-awesome.jpg
diff --git a/public/lessons/javascript/cypress-ny-la.png b/public/images/cypress-ny-la.png
similarity index 100%
rename from public/lessons/javascript/cypress-ny-la.png
rename to public/images/cypress-ny-la.png
diff --git a/public/lessons/javascript/cypress-ny.png b/public/images/cypress-ny.png
similarity index 100%
rename from public/lessons/javascript/cypress-ny.png
rename to public/images/cypress-ny.png
diff --git a/public/lessons/javascript/cypress-york.png b/public/images/cypress-york.png
similarity index 100%
rename from public/lessons/javascript/cypress-york.png
rename to public/images/cypress-york.png
diff --git a/public/lessons/javascript/cypress-yorklos-then.png b/public/images/cypress-yorklos-then.png
similarity index 100%
rename from public/lessons/javascript/cypress-yorklos-then.png
rename to public/images/cypress-yorklos-then.png
diff --git a/public/lessons/javascript/cypress-yorklos.png b/public/images/cypress-yorklos.png
similarity index 100%
rename from public/lessons/javascript/cypress-yorklos.png
rename to public/images/cypress-yorklos.png
diff --git a/public/images/dom-debugging.png b/public/images/dom-debugging.png
new file mode 100644
index 00000000..bf515fe3
Binary files /dev/null and b/public/images/dom-debugging.png differ
diff --git a/public/lessons/agile/zen/don-zen.gif b/public/images/don-zen.gif
similarity index 100%
rename from public/lessons/agile/zen/don-zen.gif
rename to public/images/don-zen.gif
diff --git a/public/lessons/learn_to_code/dot.jpg b/public/images/dot.jpg
similarity index 100%
rename from public/lessons/learn_to_code/dot.jpg
rename to public/images/dot.jpg
diff --git a/public/lessons/agile/elevator-pitch.png b/public/images/elevator-pitch.png
similarity index 100%
rename from public/lessons/agile/elevator-pitch.png
rename to public/images/elevator-pitch.png
diff --git a/public/images/event-listener.png b/public/images/event-listener.png
new file mode 100644
index 00000000..ac01dcee
Binary files /dev/null and b/public/images/event-listener.png differ
diff --git a/public/images/eventflow.svg b/public/images/eventflow.svg
new file mode 100644
index 00000000..16ae7185
--- /dev/null
+++ b/public/images/eventflow.svg
@@ -0,0 +1,113 @@
+
diff --git a/public/images/example-pull.png b/public/images/example-pull.png
new file mode 100644
index 00000000..ba9bcf84
Binary files /dev/null and b/public/images/example-pull.png differ
diff --git a/public/lessons/javascript/fancy-screenshot-tap.png b/public/images/fancy-screenshot-tap.png
similarity index 100%
rename from public/lessons/javascript/fancy-screenshot-tap.png
rename to public/images/fancy-screenshot-tap.png
diff --git a/public/lessons/javascript/fancy-screenshot.PNG b/public/images/fancy-screenshot.PNG
similarity index 100%
rename from public/lessons/javascript/fancy-screenshot.PNG
rename to public/images/fancy-screenshot.PNG
diff --git a/public/images/favicon.ico b/public/images/favicon.ico
new file mode 100644
index 00000000..7ef2c42f
Binary files /dev/null and b/public/images/favicon.ico differ
diff --git a/public/images/fcc-fire-white.png b/public/images/fcc-fire-white.png
index 6b0304fe..a236cad5 100644
Binary files a/public/images/fcc-fire-white.png and b/public/images/fcc-fire-white.png differ
diff --git a/public/images/firefox-debugger.png b/public/images/firefox-debugger.png
new file mode 100644
index 00000000..f79cdc37
Binary files /dev/null and b/public/images/firefox-debugger.png differ
diff --git a/public/lessons/javascript/fruit-banana-snack-banana.svg b/public/images/fruit-banana-snack-banana.svg
similarity index 100%
rename from public/lessons/javascript/fruit-banana-snack-banana.svg
rename to public/images/fruit-banana-snack-banana.svg
diff --git a/public/images/gaurd-clause.png b/public/images/gaurd-clause.png
new file mode 100644
index 00000000..86d7adb8
Binary files /dev/null and b/public/images/gaurd-clause.png differ
diff --git a/public/lessons/git/git-branch-basics.png b/public/images/git-branch-basics.png
similarity index 100%
rename from public/lessons/git/git-branch-basics.png
rename to public/images/git-branch-basics.png
diff --git a/public/lessons/git/git.png b/public/images/git.png
similarity index 100%
rename from public/lessons/git/git.png
rename to public/images/git.png
diff --git a/public/images/github-clone.png b/public/images/github-clone.png
new file mode 100644
index 00000000..cce6680d
Binary files /dev/null and b/public/images/github-clone.png differ
diff --git a/public/lessons/git/github-pencil.png b/public/images/github-pencil.png
similarity index 100%
rename from public/lessons/git/github-pencil.png
rename to public/images/github-pencil.png
diff --git a/public/images/github-pull.png b/public/images/github-pull.png
new file mode 100644
index 00000000..75426c6b
Binary files /dev/null and b/public/images/github-pull.png differ
diff --git a/public/lessons/react/granular-dom-updates.gif b/public/images/granular-dom-updates.gif
similarity index 100%
rename from public/lessons/react/granular-dom-updates.gif
rename to public/images/granular-dom-updates.gif
diff --git a/public/lessons/agile/zen/grievous.gif b/public/images/grievous.gif
similarity index 100%
rename from public/lessons/agile/zen/grievous.gif
rename to public/images/grievous.gif
diff --git a/public/lessons/agile/zen/hand-pool.gif b/public/images/hand-pool.gif
similarity index 100%
rename from public/lessons/agile/zen/hand-pool.gif
rename to public/images/hand-pool.gif
diff --git a/public/lessons/git/here-be-dragons.png b/public/images/here-be-dragons.png
similarity index 100%
rename from public/lessons/git/here-be-dragons.png
rename to public/images/here-be-dragons.png
diff --git a/public/lessons/images/high-five.svg b/public/images/high-five.svg
similarity index 100%
rename from public/lessons/images/high-five.svg
rename to public/images/high-five.svg
diff --git a/public/projects/mock_screenshots/home-1.png b/public/images/home-1.png
similarity index 100%
rename from public/projects/mock_screenshots/home-1.png
rename to public/images/home-1.png
diff --git a/public/projects/mock_screenshots/home-2.png b/public/images/home-2.png
similarity index 100%
rename from public/projects/mock_screenshots/home-2.png
rename to public/images/home-2.png
diff --git a/public/projects/mock_screenshots/home-3.png b/public/images/home-3.png
similarity index 100%
rename from public/projects/mock_screenshots/home-3.png
rename to public/images/home-3.png
diff --git a/public/projects/mock_screenshots/home-4.png b/public/images/home-4.png
similarity index 100%
rename from public/projects/mock_screenshots/home-4.png
rename to public/images/home-4.png
diff --git a/public/images/http-curl-example.png b/public/images/http-curl-example.png
new file mode 100644
index 00000000..19af6242
Binary files /dev/null and b/public/images/http-curl-example.png differ
diff --git a/public/lessons/www/http_request.png b/public/images/http_request.png
similarity index 100%
rename from public/lessons/www/http_request.png
rename to public/images/http_request.png
diff --git a/public/images/iife-breakdown.png b/public/images/iife-breakdown.png
new file mode 100644
index 00000000..3c6c3c64
Binary files /dev/null and b/public/images/iife-breakdown.png differ
diff --git a/public/lessons/agile/inception.jpg b/public/images/inception.jpg
similarity index 100%
rename from public/lessons/agile/inception.jpg
rename to public/images/inception.jpg
diff --git a/public/projects/mock_screenshots/left-1.png b/public/images/left-1.png
similarity index 100%
rename from public/projects/mock_screenshots/left-1.png
rename to public/images/left-1.png
diff --git a/public/projects/mock_screenshots/left-2.png b/public/images/left-2.png
similarity index 100%
rename from public/projects/mock_screenshots/left-2.png
rename to public/images/left-2.png
diff --git a/public/projects/mock_screenshots/left-3.png b/public/images/left-3.png
similarity index 100%
rename from public/projects/mock_screenshots/left-3.png
rename to public/images/left-3.png
diff --git a/public/images/loading.gif b/public/images/loading.gif
index 53dd589f..5706cca8 100644
Binary files a/public/images/loading.gif and b/public/images/loading.gif differ
diff --git a/public/lessons/git/long-running-branches-git.png b/public/images/long-running-branches-git.png
similarity index 100%
rename from public/lessons/git/long-running-branches-git.png
rename to public/images/long-running-branches-git.png
diff --git a/public/lessons/git/long-running-branches-many.png b/public/images/long-running-branches-many.png
similarity index 100%
rename from public/lessons/git/long-running-branches-many.png
rename to public/images/long-running-branches-many.png
diff --git a/public/lessons/agile/mad-libs.jpg b/public/images/mad-libs.jpg
similarity index 100%
rename from public/lessons/agile/mad-libs.jpg
rename to public/images/mad-libs.jpg
diff --git a/public/lessons/agile/make-it-green.png b/public/images/make-it-green.png
similarity index 100%
rename from public/lessons/agile/make-it-green.png
rename to public/images/make-it-green.png
diff --git a/public/lessons/react/make-it-so.jpg b/public/images/make-it-so.jpg
similarity index 100%
rename from public/lessons/react/make-it-so.jpg
rename to public/images/make-it-so.jpg
diff --git a/public/lessons/images/map-filter-reduce-in-emoji.png b/public/images/map-filter-reduce-in-emoji.png
similarity index 100%
rename from public/lessons/images/map-filter-reduce-in-emoji.png
rename to public/images/map-filter-reduce-in-emoji.png
diff --git a/public/lessons/images/matryoshka.jpg b/public/images/matryoshka.jpg
similarity index 100%
rename from public/lessons/images/matryoshka.jpg
rename to public/images/matryoshka.jpg
diff --git a/public/lessons/agile/mentos.jpg b/public/images/mentos.jpg
similarity index 100%
rename from public/lessons/agile/mentos.jpg
rename to public/images/mentos.jpg
diff --git a/public/lessons/responsive_layout/mobile-device-simulation.png b/public/images/mobile-device-simulation.png
similarity index 100%
rename from public/lessons/responsive_layout/mobile-device-simulation.png
rename to public/images/mobile-device-simulation.png
diff --git a/public/images/mozilla-docs-icon.svg b/public/images/mozilla-docs-icon.svg
index d3530adb..cfbe16bb 100644
--- a/public/images/mozilla-docs-icon.svg
+++ b/public/images/mozilla-docs-icon.svg
@@ -1 +1 @@
-
+
\ No newline at end of file
diff --git a/public/lessons/responsive_layout/navigation-bar-example-screenshot.png b/public/images/navigation-bar-example-screenshot.png
similarity index 100%
rename from public/lessons/responsive_layout/navigation-bar-example-screenshot.png
rename to public/images/navigation-bar-example-screenshot.png
diff --git a/public/images/new-repository.png b/public/images/new-repository.png
new file mode 100644
index 00000000..a5548fe4
Binary files /dev/null and b/public/images/new-repository.png differ
diff --git a/public/images/node-train.png b/public/images/node-train.png
new file mode 100644
index 00000000..1615a2ac
Binary files /dev/null and b/public/images/node-train.png differ
diff --git a/public/projects/mock_screenshots/none-1.png b/public/images/none-1.png
similarity index 100%
rename from public/projects/mock_screenshots/none-1.png
rename to public/images/none-1.png
diff --git a/public/projects/mock_screenshots/none-2.png b/public/images/none-2.png
similarity index 100%
rename from public/projects/mock_screenshots/none-2.png
rename to public/images/none-2.png
diff --git a/public/lessons/ux/norman-door-pull-728x410.jpg b/public/images/norman-door-pull-728x410.jpg
similarity index 100%
rename from public/lessons/ux/norman-door-pull-728x410.jpg
rename to public/images/norman-door-pull-728x410.jpg
diff --git a/public/images/numbers.jpg b/public/images/numbers.jpg
new file mode 100644
index 00000000..f34670f2
Binary files /dev/null and b/public/images/numbers.jpg differ
diff --git a/public/lessons/images/one-infinite-loop.jpg b/public/images/one-infinite-loop.jpg
similarity index 100%
rename from public/lessons/images/one-infinite-loop.jpg
rename to public/images/one-infinite-loop.jpg
diff --git a/public/lessons/javascript/one-way-mirror.gif b/public/images/one-way-mirror.gif
similarity index 100%
rename from public/lessons/javascript/one-way-mirror.gif
rename to public/images/one-way-mirror.gif
diff --git a/public/lessons/images/ouroboros.jpg b/public/images/ouroboros.jpg
similarity index 100%
rename from public/lessons/images/ouroboros.jpg
rename to public/images/ouroboros.jpg
diff --git a/public/lessons/images/pancakes.jpg b/public/images/pancakes.jpg
similarity index 100%
rename from public/lessons/images/pancakes.jpg
rename to public/images/pancakes.jpg
diff --git a/public/lessons/agile/planning_loops.svg b/public/images/planning_loops.svg
similarity index 100%
rename from public/lessons/agile/planning_loops.svg
rename to public/images/planning_loops.svg
diff --git a/public/lessons/react/react-component-lifecycle.png b/public/images/react-component-lifecycle.png
similarity index 100%
rename from public/lessons/react/react-component-lifecycle.png
rename to public/images/react-component-lifecycle.png
diff --git a/public/images/react-component-tree.svg b/public/images/react-component-tree.svg
new file mode 100644
index 00000000..33ab0a08
--- /dev/null
+++ b/public/images/react-component-tree.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/images/react-twitter-components.jpg b/public/images/react-twitter-components.jpg
new file mode 100644
index 00000000..5c5c69ed
Binary files /dev/null and b/public/images/react-twitter-components.jpg differ
diff --git a/public/lessons/agile/zen/real-programmers.png b/public/images/real-programmers.png
similarity index 100%
rename from public/lessons/agile/zen/real-programmers.png
rename to public/images/real-programmers.png
diff --git a/public/lessons/agile/zen/refactoring-book.jpg b/public/images/refactoring-book.jpg
similarity index 100%
rename from public/lessons/agile/zen/refactoring-book.jpg
rename to public/images/refactoring-book.jpg
diff --git a/public/projects/mock_screenshots/right-1.png b/public/images/right-1.png
similarity index 100%
rename from public/projects/mock_screenshots/right-1.png
rename to public/images/right-1.png
diff --git a/public/projects/mock_screenshots/right-2.png b/public/images/right-2.png
similarity index 100%
rename from public/projects/mock_screenshots/right-2.png
rename to public/images/right-2.png
diff --git a/public/projects/mock_screenshots/right-3.png b/public/images/right-3.png
similarity index 100%
rename from public/projects/mock_screenshots/right-3.png
rename to public/images/right-3.png
diff --git a/public/images/rip-flash.png b/public/images/rip-flash.png
new file mode 100644
index 00000000..7b4eefe3
Binary files /dev/null and b/public/images/rip-flash.png differ
diff --git a/public/lessons/tricks_of_the_trade/rubber-duck.jpg b/public/images/rubber-duck.jpg
similarity index 100%
rename from public/lessons/tricks_of_the_trade/rubber-duck.jpg
rename to public/images/rubber-duck.jpg
diff --git a/public/lessons/cs/simon.jpg b/public/images/simon.jpg
similarity index 100%
rename from public/lessons/cs/simon.jpg
rename to public/images/simon.jpg
diff --git a/public/lessons/client_side_coding/simple-map-leaflet.png b/public/images/simple-map-leaflet.png
similarity index 100%
rename from public/lessons/client_side_coding/simple-map-leaflet.png
rename to public/images/simple-map-leaflet.png
diff --git a/public/lessons/git/simplest-workflow.jpg b/public/images/simplest-workflow.jpg
similarity index 100%
rename from public/lessons/git/simplest-workflow.jpg
rename to public/images/simplest-workflow.jpg
diff --git a/public/lessons/javascript/snack-apple.svg b/public/images/snack-apple.svg
similarity index 100%
rename from public/lessons/javascript/snack-apple.svg
rename to public/images/snack-apple.svg
diff --git a/public/lessons/javascript/snack-fruit.svg b/public/images/snack-fruit.svg
similarity index 100%
rename from public/lessons/javascript/snack-fruit.svg
rename to public/images/snack-fruit.svg
diff --git a/public/lessons/agile/zen/spinning-yin-yang.gif b/public/images/spinning-yin-yang.gif
similarity index 100%
rename from public/lessons/agile/zen/spinning-yin-yang.gif
rename to public/images/spinning-yin-yang.gif
diff --git a/public/projects/sriracha.jpg b/public/images/sriracha.jpg
similarity index 100%
rename from public/projects/sriracha.jpg
rename to public/images/sriracha.jpg
diff --git a/public/lessons/images/stack.png b/public/images/stack.png
similarity index 100%
rename from public/lessons/images/stack.png
rename to public/images/stack.png
diff --git a/public/lessons/agile/zen/stone-sand.png b/public/images/stone-sand.png
similarity index 100%
rename from public/lessons/agile/zen/stone-sand.png
rename to public/images/stone-sand.png
diff --git a/public/lessons/javascript/tap.gif b/public/images/tap.gif
similarity index 100%
rename from public/lessons/javascript/tap.gif
rename to public/images/tap.gif
diff --git a/public/lessons/images/tech_support_cheat_sheet.png b/public/images/tech_support_cheat_sheet.png
similarity index 100%
rename from public/lessons/images/tech_support_cheat_sheet.png
rename to public/images/tech_support_cheat_sheet.png
diff --git a/public/lessons/images/terminal-and-browser-win.png b/public/images/terminal-and-browser-win.png
similarity index 100%
rename from public/lessons/images/terminal-and-browser-win.png
rename to public/images/terminal-and-browser-win.png
diff --git a/public/lessons/images/terminal-and-browser.png b/public/images/terminal-and-browser.png
similarity index 100%
rename from public/lessons/images/terminal-and-browser.png
rename to public/images/terminal-and-browser.png
diff --git a/public/projects/tic-tac-toe-9x9.png b/public/images/tic-tac-toe-9x9.png
similarity index 100%
rename from public/projects/tic-tac-toe-9x9.png
rename to public/images/tic-tac-toe-9x9.png
diff --git a/public/projects/tic-tac-toe-web.png b/public/images/tic-tac-toe-web.png
similarity index 100%
rename from public/projects/tic-tac-toe-web.png
rename to public/images/tic-tac-toe-web.png
diff --git a/public/projects/tic_tac_toe.svg b/public/images/tic_tac_toe.svg
similarity index 100%
rename from public/projects/tic_tac_toe.svg
rename to public/images/tic_tac_toe.svg
diff --git a/public/lessons/git/topic-branches-git.png b/public/images/topic-branches-git.png
similarity index 100%
rename from public/lessons/git/topic-branches-git.png
rename to public/images/topic-branches-git.png
diff --git a/public/lessons/git/topic-branches-merged.png b/public/images/topic-branches-merged.png
similarity index 100%
rename from public/lessons/git/topic-branches-merged.png
rename to public/images/topic-branches-merged.png
diff --git a/public/lessons/agile/tracker-workflow.png b/public/images/tracker-workflow.png
similarity index 100%
rename from public/lessons/agile/tracker-workflow.png
rename to public/images/tracker-workflow.png
diff --git a/public/images/tracks-lessons-slides.png b/public/images/tracks-lessons-slides.png
index 937381bc..39b4b033 100644
Binary files a/public/images/tracks-lessons-slides.png and b/public/images/tracks-lessons-slides.png differ
diff --git a/public/lessons/cs/traffic-light.jpg b/public/images/traffic-light.jpg
similarity index 100%
rename from public/lessons/cs/traffic-light.jpg
rename to public/images/traffic-light.jpg
diff --git a/public/images/train.png b/public/images/train.png
new file mode 100644
index 00000000..1615a2ac
Binary files /dev/null and b/public/images/train.png differ
diff --git a/public/lessons/images/truthiness.png b/public/images/truthiness.png
similarity index 100%
rename from public/lessons/images/truthiness.png
rename to public/images/truthiness.png
diff --git a/public/lessons/images/tty.jpg b/public/images/tty.jpg
similarity index 100%
rename from public/lessons/images/tty.jpg
rename to public/images/tty.jpg
diff --git a/public/projects/umbrella-today-1.png b/public/images/umbrella-today-1.png
similarity index 100%
rename from public/projects/umbrella-today-1.png
rename to public/images/umbrella-today-1.png
diff --git a/public/projects/umbrella-today-2.png b/public/images/umbrella-today-2.png
similarity index 100%
rename from public/projects/umbrella-today-2.png
rename to public/images/umbrella-today-2.png
diff --git a/public/lessons/www/url_path.png b/public/images/url_path.png
similarity index 100%
rename from public/lessons/www/url_path.png
rename to public/images/url_path.png
diff --git a/public/lessons/ux/user-experience-design-process.png b/public/images/user-experience-design-process.png
similarity index 100%
rename from public/lessons/ux/user-experience-design-process.png
rename to public/images/user-experience-design-process.png
diff --git a/public/images/vscode-debugger.png b/public/images/vscode-debugger.png
new file mode 100644
index 00000000..736f6097
Binary files /dev/null and b/public/images/vscode-debugger.png differ
diff --git a/public/lessons/images/warehouse.jpg b/public/images/warehouse.jpg
similarity index 100%
rename from public/lessons/images/warehouse.jpg
rename to public/images/warehouse.jpg
diff --git a/public/lessons/images/wargames-terminal.jpg b/public/images/wargames-terminal.jpg
similarity index 100%
rename from public/lessons/images/wargames-terminal.jpg
rename to public/images/wargames-terminal.jpg
diff --git a/public/projects/yelpington-all.png b/public/images/yelpington-all.png
similarity index 100%
rename from public/projects/yelpington-all.png
rename to public/images/yelpington-all.png
diff --git a/public/projects/yelpington-screenshot.png b/public/images/yelpington-screenshot.png
similarity index 100%
rename from public/projects/yelpington-screenshot.png
rename to public/images/yelpington-screenshot.png
diff --git a/public/images/yo-dawg-callbacks.png b/public/images/yo-dawg-callbacks.png
index b518daba..9635c0d7 100644
Binary files a/public/images/yo-dawg-callbacks.png and b/public/images/yo-dawg-callbacks.png differ
diff --git a/public/lessons/agile/zen/yoda-clear-your-mind.gif b/public/images/yoda-clear-your-mind.gif
similarity index 100%
rename from public/lessons/agile/zen/yoda-clear-your-mind.gif
rename to public/images/yoda-clear-your-mind.gif
diff --git a/public/lessons/agile/zen/zen-bow-zen-arrow.jpg b/public/images/zen-bow-zen-arrow.jpg
similarity index 100%
rename from public/lessons/agile/zen/zen-bow-zen-arrow.jpg
rename to public/images/zen-bow-zen-arrow.jpg
diff --git a/public/projects/zork-west-of-house.jpg b/public/images/zork-west-of-house.jpg
similarity index 100%
rename from public/projects/zork-west-of-house.jpg
rename to public/images/zork-west-of-house.jpg
diff --git a/public/js/app.js b/public/js/app.js
index e69de29b..5ca4f024 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -0,0 +1,8 @@
+window.addEventListener('DOMContentLoaded', (e) => {
+ if (window.hljs) {
+ hljs.configure({
+ languages: []
+ });
+ hljs.initHighlightingOnLoad();
+ }
+});
diff --git a/public/lessons/a_taste_of_javascript/a_taste_of_javascript.md b/public/lessons/a_taste_of_javascript/a_taste_of_javascript.md
index fd841b5b..ea02bccc 100644
--- a/public/lessons/a_taste_of_javascript/a_taste_of_javascript.md
+++ b/public/lessons/a_taste_of_javascript/a_taste_of_javascript.md
@@ -99,7 +99,7 @@ Specifically, *source code* is a series of instructions that tell a computer wha
* a recipe is a collection of *ingredients* and *instructions*
-![Grandma's Cookie Recipe](../images/cookie-recipe.gif)
+![Grandma's Cookie Recipe](/images/cookie-recipe.gif)
* a program is a collection of *data* (ingredients) and *code* (instructions)
@@ -174,7 +174,7 @@ function clicked() {
Computers used to not have screens! They were connected to devices like this:
-![tty](../images/tty.jpg)
+![tty](/images/tty.jpg)
The Terminal app is a direct descendant of a TeleType printer or TTY.
@@ -198,7 +198,7 @@ See [this twitter thread](https://twitter.com/b0rk/status/980825751456047104) fo
* ...and if your window is too short then the top lines will *scroll away* and you will miss them
* Make it look like this:
-![terminal next to browser](../images/terminal-and-browser.png)
+![terminal next to browser](/images/terminal-and-browser.png)
# Lab: Interactive Calculator
@@ -216,7 +216,7 @@ See [this twitter thread](https://twitter.com/b0rk/status/980825751456047104) fo
# Node is a JavaScript Engine
-![Diagram: Node Train: Command Line](https://docs.google.com/drawings/d/e/2PACX-1vSKCgLe4wp1JroIot-SsVP-TKqHsySU-06oOGe3zYWBZ4jOc77quoRH2XhyNKBBuLx4IgbLim2NZLqK/pub?w=953&h=522)
+![Diagram: Node Train: Command Line](/images/train.png)
An "engine" is a type of program that either [*executes* or *empowers*](https://en.wikipedia.org/wiki/Software_engine) other programs.
@@ -241,10 +241,14 @@ From inside `node`, if you want to get back to the shell...
# Basic Commands (Mac / Unix / Bash)
-* `pwd` ("print working dir") -- shows the name of the current directory
-* `ls` ("list") -- shows the contents of the current directory
-* `mkdir` ("make dir") -- creates a new subdirectory inside the current directory
-* `cd` ("change dir") -- move into a different directory
+| Command | Purpose | Description |
+| :-- | :-- | :-- |
+| `pwd` | Print working directory | shows the name of the current directory |
+| `cd` | Change Directory | move into a different directory |
+| `ls` | List sub | shows the contents of the current directory |
+| `mkdir` | Make directory | creates a new subdirectory inside the current directory |
+| `touch` | Make a file | creates an empty file with a name and file type |
+| `rm` | Remove a file | deletes a file from the file system |
> Windows shells have slightly different commands; if these commands don't work for you, ask a TA how to use "bash" instead.
@@ -292,13 +296,12 @@ Hello, World!
2. Open this directory in your text editor
3. Create a file named `hello.js` using the *File > New* menu
4. Inside this file, put the following source code:
-
- console.log("Hello, World!");
-
+ - `console.log("Hello, World!");`
5. Save the file
6. Switch back to the terminal (using Alt-Tab or Cmd-Tab or clicking)
(If you are using VS Code, you can click **Terminal → New Terminal** for the built-in terminal panel)
-7. Run this file using `node hello.js`
+7. Run this file using:
+ - `node hello.js`
What happens? Is this what you expected?
@@ -307,14 +310,16 @@ What happens? Is this what you expected?
1. Inside your `code` directory, create a file named `countdown.js`
2. Inside this file, put the following source code:
- let count = 10;
-
- while (count > 0) {
- console.log(count + '...');
- count = count - 1;
- }
-
- console.log('Blastoff!');
+```javascript
+let count = 10;
+
+while (count > 0) {
+ console.log(count + '...');
+ count = count - 1;
+}
+
+console.log('Blastoff!');
+```
3. Save the file
4. In your terminal, run `node countdown.js`
@@ -328,12 +333,16 @@ What happens? Is this what you expected?
* Remember the cooking analogy? The code is the instructions; now let's allow the user (you!) to change the ingredients
* Change line 1 to the following:
- let count = parseInt(process.argv[2])
+```javascript
+let count = parseInt(process.argv[2])
+```
* run the program with new inputs from the command line like this:
- node countdown 5
- node countdown 100
+```shell
+$ node countdown 5
+$ node countdown 100
+```
# ARGV
@@ -341,10 +350,10 @@ What happens? Is this what you expected?
* `process.argv` is an *array* containing the *command-line arguments*
* For example, on my system, if I type `node countdown 99`, `argv` contains...
-| index | meaning | value |
-|---|---|---|
-| 0 | location of the NodeJS engine | `'/usr/local/Cellar/node/11.10.0/bin/node'` |
-| 1 | location of the current program | `'/Users/alex/code/countdown'` |
-| 2 | "first" command-line argument | `'99'` |
+| index | meaning | value |
+| :-- | :-- | :-- |
+| 0 | location of the NodeJS engine | `'/usr/local/Cellar/node/11.10.0/bin/node'` |
+| 1 | location of the current program | `'/Users/alex/code/countdown'` |
+| 2 | "first" command-line argument | `'99'` |
* Computers (usually) start counting at zero, so `process.argv[2]` gets the third item from the array `process.argv`
diff --git a/public/lessons/agile/acceptance_testing.md b/public/lessons/agile/acceptance_testing.md
index abce69ae..5a4142fa 100644
--- a/public/lessons/agile/acceptance_testing.md
+++ b/public/lessons/agile/acceptance_testing.md
@@ -16,7 +16,7 @@ Where does Acceptance Testing fit in with other forms of automated tests?
# Why test?
-the point of all automated testing is feedback
+The point of all automated testing is feedback
> If a test fails in the woods, does anyone hear it fail?
@@ -155,7 +155,7 @@ When Cucumber works it's amazingly great, but most teams find it slows them down
* as screenshots & videos for later viewing
* as DOM copies for later debugging (!!)
-see more at the [Cypress Lesson](/lessons/javascript/cypress)
+see more at the [Cypress Lesson](/lessons/javascript-track/cypress)
# Cypress
@@ -165,7 +165,17 @@ see more at the [Cypress Lesson](/lessons/javascript/cypress)
* more detailed assertions are written in [Mocha](https://docs.cypress.io/guides/references/bundled-tools.html#Mocha) + [Chai](https://www.chaijs.com/api/bdd/)
* (very similar to Jasmine and Jest -- but [not identical](https://medium.com/@NicholasBoll/using-jest-matchers-in-cypress-5e8e7281f5dd) )
-see more at the [Cypress Lesson](/lessons/javascript/cypress)
+see more at the [Cypress Lesson](../javascript/cypress)
+
+# Lab: Let's Test Our Projects
+
+In an ideal world all code would be tested. Unfortunately due to time constraints, and the fact that few programmers actually enjoy writing tests they usually are the first thing to be cut from a project. Let's write some end to end tests for our remock project.
+
+Go ahead and cd over to the directory that your remock project lives in then install Cypress using the command `npm install cypress` Beware! Cypress can take a while to install.
+
+Once Cypress is installed go into the `fixtures` directory Cypress created for you, and create a file named `test.spec.js`
+
+In that file write tests for each of the stories on the [Remock Project](https://bootcamp.burlingtoncodeacademy.com/projects/remock)
# Good Ideas
diff --git a/public/lessons/agile/agile.rb b/public/lessons/agile/agile.rb
index 6ecfb19a..551cf830 100644
--- a/public/lessons/agile/agile.rb
+++ b/public/lessons/agile/agile.rb
@@ -37,17 +37,5 @@ class Track
end
lesson name: "planning" # Agile Planning: Build, Measure, Predict, Repeat
- lesson name: "flavors" # agile flavors (methodologies): Scrum, XP, Kanban, Lean
-
- lesson name: "lean_product_design" # based on The Lean Startup
- lesson name: "scrum"
- lesson name: "kanban"
- lesson name: "extreme_programming_xp"
-
-
- lesson name: "flow_and_maker_time" do
- link href: 'https://www.ted.com/talks/mihaly_csikszentmihalyi_on_flow'
- link href: 'http://www.paulgraham.com/makersschedule.html'
- end
end
end
diff --git a/public/lessons/agile/inceptions.md b/public/lessons/agile/inceptions.md
index 049e2ccd..a74186ef 100644
--- a/public/lessons/agile/inceptions.md
+++ b/public/lessons/agile/inceptions.md
@@ -1,7 +1,7 @@
#
-![inception](inception.jpg)
+![inception](/images/inception.jpg)
# What is an Inception?
@@ -128,7 +128,7 @@ How do we want to work?
# Elevator Pitch
-Play the ![Mad Libs](./mad-libs.jpg) Pitch Game!
+Play the ![Mad Libs](/images/mad-libs.jpg) Pitch Game!
> An elevator pitch is a concise, clear, persuasive explanation of a product that can be told in the time it would take to ride an elevator.
@@ -141,7 +141,7 @@ Then select a spokesperson to share your result with the group. If time allows,
# Elevator Pitch Example
-![elevator pitch](elevator-pitch.png)
+![elevator pitch](/images/elevator-pitch.png)
(from )
diff --git a/public/lessons/agile/pair_programming.md b/public/lessons/agile/pair_programming.md
index 6aefc145..a59166e9 100644
--- a/public/lessons/agile/pair_programming.md
+++ b/public/lessons/agile/pair_programming.md
@@ -10,14 +10,6 @@ One problem
...notwithstanding remote pairing tools and face-to-face pairing desks)
-# Pairing is like Rally Racing
-
-One driver, one navigator
-
-
-
-Listen to how engaged the navigator is. They are focused on what's coming next, but they are **not** idly speculating. E.g. circa 4min in
-
# Pair Programming Benefits
> Two heads are better than one!
@@ -108,7 +100,7 @@ _Docendo discimus_ - "by teaching we learn"
> It's better to have them and not need them, than to need them and not have them.
-![mentos](mentos.jpg)
+![mentos](/images/mentos.jpg)
# Do...
diff --git a/public/lessons/agile/planning.md b/public/lessons/agile/planning.md
index 2269b4f8..f07d6203 100644
--- a/public/lessons/agile/planning.md
+++ b/public/lessons/agile/planning.md
@@ -1,6 +1,6 @@
# Planning in XP
-![planning loops](planning_loops.svg)
+![planning loops](/images/planning_loops.svg)
(from )
@@ -66,7 +66,7 @@ There are other types of stories and tasks...
# Story Lifecycle
-![tracker story lifecycle](./tracker-workflow.png)
+![tracker story lifecycle](/images/tracker-workflow.png)
(this diagram is from Pivotal Tracker but the workflow applies to most Agile processes and tools)
diff --git a/public/lessons/agile/refactoring.md b/public/lessons/agile/refactoring.md
index f0ea0f2b..b706024a 100644
--- a/public/lessons/agile/refactoring.md
+++ b/public/lessons/agile/refactoring.md
@@ -1,6 +1,6 @@
# The Zen of Refactoring
-![buddha](./zen/buddha-statue.jpg)
+![buddha](/images/buddha-statue.jpg)
Refactoring is the process of restructuring existing computer code -- changing its *factors* -- without changing its behavior. You probably knew that. But did you know it’s also a meditation technique? Come improve your practice of mindful coding.
@@ -22,12 +22,11 @@ After these slides, we’ll start with some actual production code, make sure it
> mostly an excuse for pretty pictures and hippie jokes
-![zen](./zen/don-zen.gif)
+![zen](/images/don-zen.gif)
> disclaimer: This presentation uses some
> spiritual imagery but is not intended to
> parody any religion or culture
-> (except American New Age Hippies)
# What is Refactoring?
@@ -61,15 +60,13 @@ debugging
# Why refactor?
-![yoda](zen/yoda-clear-your-mind.gif)
-
-(Yoda ≈ Buddha)
+![yoda](/images/yoda-clear-your-mind.gif)
# Refactor to understand
clarity calm insight knowledge understanding
-![pool](zen/hand-pool.gif)
+![pool](/images/hand-pool.gif)
See the code for what it is, not what you think it is, or what you want it to be
@@ -77,7 +74,7 @@ See the code for what it is, not what you think it is, or what you want it to be
DRY
-![sand](zen/stone-sand.png)
+![sand](/images/stone-sand.png)
# Refactor to increase code clarity
@@ -134,11 +131,11 @@ tests are an extension of code
# Reversible
-![reversible](./zen/spinning-yin-yang.gif)
+![reversible](/images/spinning-yin-yang.gif)
# Mechanical
-![grievous.gif](./zen/grievous.gif)
+![grievous.gif](/images/grievous.gif)
# Brief
@@ -150,7 +147,7 @@ I choose my text editor based on how well it refactors my code
(Other programmers may have different criteria.)
-![real programmers use](zen/real-programmers.png)
+![real programmers use](/images/real-programmers.png)
@@ -326,13 +323,13 @@ don't confuse *method chaining* (often good) with *feature envy* (usually bad))
## Method Chaining
-```
+```js
string.split(' ').map((s)=>s.toUpperCase()).join(' ')
```
## Feature Envy
-```
+```js
course.students[0].phone.sendText('hi')
```
@@ -343,7 +340,7 @@ course.students[0].phone.sendText('hi')
# The Book
-![refactoring-fowler](./zen/refactoring-book.jpg)
+![refactoring-fowler](/images/refactoring-book.jpg)
diff --git a/public/lessons/agile/retrospectives.md b/public/lessons/agile/retrospectives.md
index 6c50514d..6032cb89 100644
--- a/public/lessons/agile/retrospectives.md
+++ b/public/lessons/agile/retrospectives.md
@@ -27,7 +27,7 @@ At regular intervals, the team meets to discuss
# The Bible
-![Agile Retrospectives book cover](./agile-retrospectives.jpg)
+![Agile Retrospectives book cover](/images/agile-retrospectives.jpg)
diff --git a/public/lessons/agile/test_driven.md b/public/lessons/agile/test_driven.md
index 9ea2b617..01c41a94 100644
--- a/public/lessons/agile/test_driven.md
+++ b/public/lessons/agile/test_driven.md
@@ -1,16 +1,6 @@
-# Test-Driven
+# Test Driven Development
-by Alex Chaffee
-
-alexch @ gmail.com
-
-# Intended Audience
-
-* Developers or QA Engineers
-* Familiar with Unit Testing (optional)
-* Want more detail on Automated Testing in general
-* Want to know the case for Test-Driven Development
-* Want to know style tips and gotchas for Testing and TDD
+The basic principle of TDD is that you write your tests first, and then you write code to make that test past. You never write code you haven't already written a test for.
# Part I: Basic Techniques
@@ -27,7 +17,7 @@ alexch @ gmail.com
# Make it green, then make it clean
-![Make it green](make-it-green.png)
+![Make it green](/images/make-it-green.png)
# Addicted to green
@@ -128,6 +118,7 @@ alexch @ gmail.com
* Monitoring
# A Good Test Is...
+
* Automated
* Isolated
* Repeatable
@@ -163,8 +154,6 @@ alexch @ gmail.com
# When do you test?
-# When do you test?
-
* Before checkin
* After update
* Before deploy
@@ -500,6 +489,7 @@ expect( function(){ parser.parse(bogus); } )
* Quite brittle; often thrown away after the refactoring is done
# Pair Programming
+
* A pair's job is to keep you focused
* "Wait, let's write a test first."
* "Wait, let's refactor first."
@@ -507,6 +497,7 @@ expect( function(){ parser.parse(bogus); } )
* "Can I drive?"
# Ping-Pong Pairing
+
* One pair writes a test
* The other pair makes it pass and writes the next test
* Repeat
@@ -524,13 +515,16 @@ expect( function(){ parser.parse(bogus); } )
* If your regression test is high-level (e.g. Selenium), you probably want a failing unit test too
# Do Over
-* Often the best thing to do is throw away your work and start again
+
+Often the best thing to do is throw away your work and start again
# Leave One For Tomorrow
+
* At the end of the day, write a failing test and leave it there for tomorrow
* Based on writer's trick: start a sentence and leave it unfinished
# The Need For Speed
+
* Tests are only valuable if they're run all the time
* If they're slow, people will not want to run them all the time
* So keep them fast!
@@ -663,19 +657,18 @@ In Jasmine (built in, see [the docs](https://jasmine.github.io/2.0/introduction.
* Both are useful at times
# Inside-out
+
* Start with domain objects
* Next layer of tests
# Outside-in
+
* Start with customer story or user interface
* Makes you think like a user
* Tests capture these requirements
* Lower layers implemented with
# Outside-in design, inside-out development
+
* Write a bunch of UI-level tests
* Leave them there while you test-drive inside-out
-
-# Part IV: Q&A
-
-Thanks!
diff --git a/public/lessons/bootstrap/bootstrap.rb b/public/lessons/bootstrap/bootstrap.rb
index d29b08e3..ddf2d0c3 100644
--- a/public/lessons/bootstrap/bootstrap.rb
+++ b/public/lessons/bootstrap/bootstrap.rb
@@ -46,6 +46,5 @@ class Track
topic name: "bootstrap-components"
end
- lesson name: "/responsive_layout/css_frameworks"
end
end
diff --git a/public/lessons/bootstrap/bootstrap_components.md b/public/lessons/bootstrap/bootstrap_components.md
index b53b62a1..b4248df9 100644
--- a/public/lessons/bootstrap/bootstrap_components.md
+++ b/public/lessons/bootstrap/bootstrap_components.md
@@ -111,7 +111,7 @@ Components need:
* Carousels tend to me a more intricate and complicated Bootstrap component, so lets break down the relatively simple markup below:
-```
+```html
diff --git a/public/lessons/bootstrap/bootstrap_webpage.md b/public/lessons/bootstrap/bootstrap_webpage.md
index 967c48ec..a278b880 100644
--- a/public/lessons/bootstrap/bootstrap_webpage.md
+++ b/public/lessons/bootstrap/bootstrap_webpage.md
@@ -6,7 +6,7 @@ Lets get started with Bootstrap by writing our first web page.
* We can obtain this by a number of different methods outlined on their website.
* The easiest and quickest method is to link to the files in our document `` from their CDN.
-```
+```html
@@ -23,7 +23,7 @@ https://getbootstrap.com/docs/4.0/getting-started/introduction/
# Basic Bootstrap Web Page Template
-```
+```html
diff --git a/public/lessons/career/career.rb b/public/lessons/career/career.rb
index dac8f1cd..719494bf 100644
--- a/public/lessons/career/career.rb
+++ b/public/lessons/career/career.rb
@@ -5,39 +5,6 @@ class Track
name: "career",
description: "To make coding a career requires a very particular set of skills. In this track, we discuss ways to connect with the community of employers, mentors, partners, job-seekers, and other fellow travelers along the Old Code Road. How to communicate your skills and interests? What new skills could make you more attractive to employers, improve your revenue, or be more fun? How can you improve your workplace? How do you contribute to open-source projects? What about public speaking? Are coding interviews really as grueling as they sound? What are the secrets to success?"
) do
-
- lesson name: "linked_in"
- lesson name: "resume_building" do
- link href: "https://medium.freecodecamp.org/how-to-write-a-great-resume-for-software-engineers-75d514dd8322"
- end
-
- lesson name: "coding_interviews" do
- link href: "https://technology.cloverhealth.com/how-to-interview-entry-level-software-engineers-daaecf9db97"
- link href: "https://imranontech.com/2007/01/10/why-logic-puzzles-make-good-interview-questions/"
- link href: "https://www.keyvalues.com/culture-queries",
- name: "questions to ask in your job interview",
- description: "A good job interview goes both ways. This site helps you think about questions a job seeker should ask about the company."
- link href: "https://github.com/mzbat/mirr/",
- name: "Mock Interview and Resume Review Workshop"
- end
-
- lesson name: "money" # freelance vs salary, negotiating, etc
- lesson name: "public_speaking"
-
- lesson name: "craftsmanship" do
- link href: "https://www.artima.com/intv/craft.html",
- name: "Matz on Craftsmanship",
- description: "A Conversation with Yukihiro Matsumoto, Part IV"
- link href: "https://www.artima.com/intv/craft2.html",
- name: "Matz on Craftsmanship (cont.)",
- description: "A Conversation with Yukihiro Matsumoto, Part IV (continued)"
- link href: "http://manifesto.softwarecraftsmanship.org/"
- end
- lesson name: "contributing_to_open_source"
-
- link href: 'https://hackernoon.com/how-i-landed-my-post-bootcamp-software-developer-job-in-just-seven-weeks-7b213c1bb867'
-
- lesson name: 'freelancing_and_consulting'
lesson name: 'where_to_go_next'
end
diff --git a/public/lessons/client_side_coding/ajax.md b/public/lessons/client_side_coding/ajax.md
index f16efefa..2c6ac100 100644
--- a/public/lessons/client_side_coding/ajax.md
+++ b/public/lessons/client_side_coding/ajax.md
@@ -204,7 +204,7 @@ fetch('https://jsonplaceholder.typicode.com/posts/1')
# JSON (JavaScript Object Notation)
-See a more comprehensive JSON lesson here: [JSON lesson](/lessons/javascript/json)
+See a more comprehensive JSON lesson here: [JSON lesson](/lessons/javascript-track/json)
### Example
@@ -246,3 +246,14 @@ fetch('/city-market.json')
console.log(myObject);
});
```
+
+# Mini Project: Fake Blog
+
+In this lab you will create a blog front end with users, and posts pulled from jsonplaceholder.typicode.com containing several different sections:
+
+* On the home page there should be a sidebar with a list of authors
+* When an author's name is clicked it should send you to a page with all the posts by that author.
+* On the homepage there should be a list of all blog posts, displayed by title
+* When a post is clicked it should take you to a dedicated page for that post with the author's name, the title of the post, and the body
+
+> Hint: Create template pages for authors and posts, then use query parameters, or url fragments to determine what data to fetch. This will make it so you don't need 100 very similar pages for each post.
diff --git a/public/lessons/client_side_coding/browser_debugging.md b/public/lessons/client_side_coding/browser_debugging.md
new file mode 100644
index 00000000..17d02594
--- /dev/null
+++ b/public/lessons/client_side_coding/browser_debugging.md
@@ -0,0 +1,67 @@
+# Browser Tools
+
+If you're running a program through your browser most modern browsers (i.e. Chrome, or FireFox) have built in debugging tools you can use!
+
+# Step 1: Accessing the Dev Tools
+
+In Chrome:
+
+* `ctrl` + `shift` + `i` for a Windows machine
+
+ * **or** right click and select `inspect` from the drop-down menu
+
+* `cmd` + `option` + `i` for a Mac
+
+ * **or** `option` + click and select `inspect` from the drop-down menu
+
+In FireFox:
+
+* `ctrl` + `shift` + `c` for a Windows machine
+
+ * **or** right click and select `Inspect Element` from the drop-down menu
+
+* `cmd` + `option` + `c` for a Mac
+
+ * **or** `option` + click and select `Inspect Element` from the drop-down menu
+
+# Step 2a: Add Breakpoints in Chrome
+
+* In the dev tools, navigate to the `Sources` tab (to the immediate right of the `console` tab)
+
+* Select the file you want to debug
+
+* Click on the line number where you want to add your breakpoint
+
+>Note: If you're unsure where your error is coming from you can add a break point at the top of your code and step through your whole program line by line
+
+# Step 2a breakdown
+
+![chrome debugger example](/images/chrome-debugger.png)
+
+# Step 2b: Add Breakpoints in FireFox
+
+* In the dev tools, navigate to the `Debugger` tab (to the immediate right of the `console` tab)
+
+* Select the file you want to debug from the `Sources` section
+
+* Click on the line number where you want to add your breakpoint
+
+# Step 2b breakdown
+
+![firefox debugger example](/images/firefox-debugger.png)
+
+# Step 3: Run your Code
+
+Once you've added a breakpoint run your code, and step through the section by clicking the `step over` button or pressing `f10`.
+
+If you've stepped through your code, and are still having issues finding where the errors are coming, or you find yourself traversing through previously unknown code there are several things you may want to try:
+
+* Disable extensions
+
+* Run in 'incognito' mode to make sure you're not caching bad code
+
+* Try running the code in a different browser
+
+* Try running it in a 'pristine' browser (a fresh install with no extensions or settings changes)
+
+>Note: If your code runs on page load, you will need to refresh the page before the debugger takes effect.
diff --git a/public/lessons/client_side_coding/client_side_coding.rb b/public/lessons/client_side_coding/client_side_coding.rb
index 914aa45c..42636616 100644
--- a/public/lessons/client_side_coding/client_side_coding.rb
+++ b/public/lessons/client_side_coding/client_side_coding.rb
@@ -18,7 +18,9 @@ class Track
project name: "tic_tac_toe_www"
project name: "hangman"
- # lesson name: "dom"
+ lesson name: "dom"
+
+ lesson name: "browser_debugging"
lesson name: "embedding",
description: 'how to use Web APIs and embedded widgets to serve maps, videos, surveys, and other content from around the Web inside your own sites' do
@@ -26,6 +28,8 @@ class Track
link href: "https://www.theodinproject.com/courses/html5-and-css3/lessons/embedding-images-and-video"
end
+ lesson name: "/javascript_intro/event_listeners"
+
lesson name: "jquery" do
topic name: "jquery"
topic name: "jquery-selectors"
@@ -50,8 +54,7 @@ class Track
end
lesson name: "calling_apis",
- display_name: "Calling APIs from JavaScript",
- description: "jQuery.ajax(), XMLHttpRequest, Fetch" do
+ display_name: "Calling APIs from JavaScript" do
topic name: "postman"
topic name: "apis"
link href: 'https://www.codecademy.com/tracks/parse'
@@ -64,15 +67,6 @@ class Track
project name: "umbrella_today"
end
- # more advanced mapping
- lesson name: "geolocation" do
- link href: "https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/Using_geolocation"
- end
-
- lesson name: "geocoding" do
- link href: "https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/Using_geolocation"
- end
-
lesson name: "interactive_mapping" do
topic name: "leaflet"
topic name: "geocoding"
@@ -92,17 +86,7 @@ class Track
link href: "https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage"
end
- # probably should move all these lessons to later tracks
+ lesson name: "media"
- lesson name: "canvas"
- lesson name: "svg"
-
- lesson name: "security" do
- link name: "XSS"
- link name: "CSRF"
- link href: "https://www.quora.com/What-is-the-difference-between-XSS-and-CSRF-from-their-execution-perspective"
- link href: "https://blog.plan99.net/its-time-to-kill-the-web-974a9fe80c89#7a16",
- name: "Web apps are impossible to secure"
- end
end
end
diff --git a/public/lessons/client_side_coding/dom.md b/public/lessons/client_side_coding/dom.md
index a4c800cd..74c1e9d1 100644
--- a/public/lessons/client_side_coding/dom.md
+++ b/public/lessons/client_side_coding/dom.md
@@ -39,7 +39,7 @@ window.location === document.location
// => true
```
-# `window` is magic
+# The `window`
* `window.location = "http://google.com"`
* makes the browser load a new page
@@ -60,24 +60,16 @@ window.parseInt('123') // thing
```
# Locating HTML Elements
+
* the hard way
* traverse the document tree using DOM Node methods
* the somewhat easier way
* `document.getElementsByTagName('p')[0]`
* the easy way
* `document.getElementById('article')`
-* the awesome way
- * `$('#article')`
- * jQuery + CSS Selectors FTW!
-
-# $?
-
-* dollar sign, like underscore, is a valid symbol name
-* jQuery (and some other libraries) define `$` as a function that's like a souped-up `getElementById`
- * unfortunately, the object `$` returns is not an Element, but a wrapper
- * somewhat different API
# Adding HTML
+
* brute force (raw HTML strings)
```javascript
@@ -87,117 +79,30 @@ var message = document.getElementById('message');
message.innerHTML = "bye!";
```
-# Altering HTML Elements
+* programmatically with JS
-* Look at DOM reference
+```js
-# the style property
+let target = document.getElementById('someElement')
-* acts like a hash with properties for most CSS attributes
-* CSS uses dashes; JavaScript uses camelCase
+let paragraph = document.createElement('p')
+paragraph.textContent = "I’ve seen things you people wouldn’t believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time, like tears in rain."
- div.style.backgroundColor = "#FF0000";
-
-# the "px" problem
-
-* CSS position and layout attributes need a unit
-* the default is **not** "px"
- * except sometimes it works
- * which is worse than never working
-
- div.style.width = "10px";
-
-* here's a handy helper method
-
-```javascript
-Number.prototype.px = function() {
- return "" + this + "px";
-}
-
-(5).px(); // "5px"
-x = 10;
-x.px(); // "10px"
+target.appendChild(paragraph)
```
-* here's a trick for reading "px" values
-
-```javascript
-parseInt(h1.style.width)
-```
-
-
-# setTimeout
-
-* You pass in a function (let's call it F) and a number (call it N)
-* Execution returns *immediately*
-* F gets called approximately N milliseconds later
- * not exact, but close enough for simple animation
-* F is known as a **callback**
- * because the system calls it back at some later point
- * callbacks are used all over the place in JavaScript
- * events, Jasmine tests, jQuery, node.js, ...
-
-# Wait a second... did you say ANIMATION???!?!
-
-* Animating HTML is very exciting
-
-```javascript
-function slide(element) {
- element.style.position = "fixed";
- var x = 0;
- function step() {
- if (x > 1000) {
- // stop the animation
- return;
- } else {
- element.style.left = x.px();
- x += 10;
- // schedule the next animation
- setTimeout(step, 100);
- }
- }
- step(); // start animation
-}
-```
-
-Scoping note: `step` is available inside the function itself because we defined it with a name, not anonymously.
-
-see [animate.html](../javascript/animate.html) for a live example
-
-# jQuery Animation
-
-* jQuery has some fun methods to animate CSS attributes
-*
-
-```javascript
-$("#logo").animate({
- backgroundColor: "#aa0000"
-}, 1000 );
-```
-
- * You choose the attribute(s) and their final value, plus the duration of the entire effect
- * jQuery calculates and interpolates the details
-* jQuery UI has lots more
- * , not
+# Altering HTML Elements
-# Testing Animation
+* Target an element through a DOM query and assign it to a variable
+* Use the reference to the element to manipulate existing properties
+ * Or add entirely new properties
-* Use a "Mock Clock"
- * replace `setTimeout` with a different function during tests
- * this function keeps track of what would be called when
- * then "ticks" forward when asked
- * you can simulate speeding up and slowing down time
-* In Jasmine:
+# the style property
-```javascript
-beforeEach(function() {
- jasmine.Clock.useMock();
-});
-//... call the code that calls setTimeout
-jasmine.Clock.tick(500); // advance 500 msec
-```
+* acts like a hash with properties for most CSS attributes
+* CSS uses dashes; JavaScript uses camelCase
- * see thread [How to test timers?](http://groups.google.com/group/jasmine-js/browse_thread/thread/f987956c624840d1/73b3ff5391244b19)
+ div.style.backgroundColor = "#FF0000";
# Events
@@ -209,64 +114,11 @@ jasmine.Clock.tick(500); // advance 500 msec
* "listener" is just another name for "callback" (for events)
* also called "handler"
-# How do I hook thee up? Let me count the ways.
-
-> How do I love thee? Let me count the ways.
-
-> I love thee to the depth and breadth and height
-
-> My soul can reach, when feeling out of sight
-
-> For the ends of Being and ideal Grace.
-
-> - Elizabeth Barrett Browning (1806-1861)
-
## Event Name Gotcha
* the name of the property is **not** camelCase
* the property name starts with "on" but the event name does **not** include "on"
-## Event Binding
-
-1. assign a *string* to the onwhatever property in HTML
-
-
hi
-
-2. assign a function to the onwhatever property in JS
-
-
hi
-
-
- * gotcha: can only attach a single listener
-
-3. call the `addEventListener` method in JS
-
- div.addEventListener('click', function() {
- alert("hi");
- });
-
- * gotcha: in IE, you must use `attachEvent` instead
-
-4. use jQuery's `bind` method
-
- $('#hi').bind('click', function() {
- alert("hi");
- });
-
-4. use jQuery's convenience method for standard event types
-
- $('#hi').click(function() {
- alert("hi");
- });
-
- * gotcha: if you call `click()` with no parameters, it *triggers* a click
-
# `return false`
* if the event listener returns false, all further processing stops
@@ -276,7 +128,8 @@ jasmine.Clock.tick(500); // advance 500 msec
* Mouse
* mousedown, mouseup, click
- * mouseover
+ * mouseover, dblclick
+ * and many more. There are a ton of mouse events. A ridiculous number really.
* Keyboard
* keydown, keypress, keyup
* Window
@@ -286,27 +139,18 @@ jasmine.Clock.tick(500); // advance 500 msec
* resize, scroll, contextmenu
* Form
* focus, blur
- * blur is the stupidest name ever in the history of stupid
- * should have been "unfocus" or "losefocus"
+ * "blur" should probably have been "unfocus," but we're stuck with it now
* change, select
* submit, reset
-# Headless DOM
-
-* TODO: headless horseman image
-* [env.js](http://www.envjs.com/) is a simulated browser environment written in JavaScript
-* good for automated testing (e.g. continuous integration box)
-
# References
+
* DOM
*
*
* [the Style object](http://www.w3schools.com/jsref/dom_obj_style.asp)
- *
+ *
* [DOM objects and methods](http://www.howtocreate.co.uk/tutorials/javascript/domstructure) - "all properties, collections and methods of the W3C DOM that can be reliably used in all major DOM browsers"
-* Animation
- *
- *
* Events
*
*
diff --git a/public/lessons/client_side_coding/embedding.md b/public/lessons/client_side_coding/embedding.md
index 8bb3c7b7..c97b3ac5 100644
--- a/public/lessons/client_side_coding/embedding.md
+++ b/public/lessons/client_side_coding/embedding.md
@@ -1,6 +1,17 @@
-# Embedding
+# Embedding Media
-Embedding is the process of including *media* from other sources into your web sites.
+[Embedding](/lessons/www-track/embedding-media) is the process of including *media* from other sources into your web sites.
+
+"other documents" can include:
+
+ * media files
+ * images, sound, video
+ * other HTML (pages or snippets)
+ * advertisements
+ * maps, graphs, charts
+ * search box e.g. [Google custom search](https://cse.google.com/)
+
+"embedding" is sometimes also called "including" or "transcluding"
# Interactive Embedding
@@ -10,26 +21,123 @@ For instance, you could programmatically pause and play an embedded audio clip,
Or, if the user moves their location on an embedded Google Map, your app could be notified and find the city name and look up restaurants in that area on [Yelp's API](https://www.yelp.com/developers/documentation/v3).
-> This lesson focuses on *interactive* embedding:
-> using JavaScript to pass messages between your page's scripts and the embedded media.
-> The [Embedding Media](/lessons/www/embedding-media) lesson covers *static* embedding:
+> This lesson focuses on *static* embedding:
> displaying media and allowing the user to interact with it directly.
+> The [Interactive Embedding](/lessons/client-side-js-track/embedding) lesson focuses on *interactive* embedding:
+> using JavaScript to pass messages between your page's
+> scripts and the embedded media.
+
+# Embedding Images
+
+`` is the original embed
+
+[MDN: img](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img)
+
+# Where does the media come from?
+
+* Usually images are served from the same web server as HTML.
+* Some web sites host images or other media for free or a small cost
+ * *images*: flickr.com, imgur.com, 500px.com, etc.
+ * *video*: YouTube.com, Vimeo.com, Wistia.com, etc.
+ * *audio*: SoundCloud.com, etc.
+* a [CDN](https://en.wikipedia.org/wiki/Content_delivery_network#Notable_content_delivery_service_providers) hosts all sorts of media for you for $$$
+ * Amazon AWS / CloudFront, CloudFlare, Akamai...
+
+# Embedding IFrames
+
+`