├── assets ├── alert.png ├── example.png ├── nodejs.png ├── annotated.png ├── index.html.png ├── lhl-logo.png ├── new-file.png ├── no-styles.png ├── hello-world.png ├── open-folder.png ├── server-test.png ├── annotated-alert.png ├── client-folder.png ├── download-chrome.png ├── example-cropped.png ├── hello-browser.png ├── install-express.png ├── terminal-test.png ├── working-alert.png └── download-brackets.png ├── _book ├── images │ └── lhl-logo.png ├── gitbook │ ├── images │ │ ├── favicon.ico │ │ └── apple-touch-icon-precomposed-152.png │ ├── fonts │ │ └── fontawesome │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ ├── gitbook-plugin-search │ │ ├── search.css │ │ ├── search-engine.js │ │ ├── search.js │ │ └── lunr.min.js │ ├── gitbook-plugin-lunr │ │ ├── search-lunr.js │ │ └── lunr.min.js │ ├── gitbook-plugin-sharing │ │ └── buttons.js │ ├── gitbook-plugin-highlight │ │ └── ebook.css │ └── gitbook-plugin-fontsettings │ │ ├── fontsettings.js │ │ └── website.css ├── GLOSSARY.html └── content │ ├── part1 │ ├── index.html │ └── dev-tools.html │ ├── final │ └── index.html │ ├── setup │ ├── index.html │ ├── chrome.html │ └── github.html │ └── part2 │ └── index.html ├── content ├── setup │ ├── chrome.md │ ├── nodejs.md │ ├── brackets.md │ ├── README.md │ ├── github.md │ └── cloud9.md ├── final │ └── README.md ├── part1 │ ├── README.md │ ├── dev-tools.md │ ├── final-css.md │ ├── css.md │ └── html.md ├── part2 │ ├── README.md │ ├── node.md │ ├── express.md │ ├── socket.io.md │ └── client-js.md └── part3 │ └── README.md ├── GLOSSARY.md ├── SUMMARY.md └── README.md /assets/alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/alert.png -------------------------------------------------------------------------------- /assets/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/example.png -------------------------------------------------------------------------------- /assets/nodejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/nodejs.png -------------------------------------------------------------------------------- /assets/annotated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/annotated.png -------------------------------------------------------------------------------- /assets/index.html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/index.html.png -------------------------------------------------------------------------------- /assets/lhl-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/lhl-logo.png -------------------------------------------------------------------------------- /assets/new-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/new-file.png -------------------------------------------------------------------------------- /assets/no-styles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/no-styles.png -------------------------------------------------------------------------------- /assets/hello-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/hello-world.png -------------------------------------------------------------------------------- /assets/open-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/open-folder.png -------------------------------------------------------------------------------- /assets/server-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/server-test.png -------------------------------------------------------------------------------- /_book/images/lhl-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/_book/images/lhl-logo.png -------------------------------------------------------------------------------- /assets/annotated-alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/annotated-alert.png -------------------------------------------------------------------------------- /assets/client-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/client-folder.png -------------------------------------------------------------------------------- /assets/download-chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/download-chrome.png -------------------------------------------------------------------------------- /assets/example-cropped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/example-cropped.png -------------------------------------------------------------------------------- /assets/hello-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/hello-browser.png -------------------------------------------------------------------------------- /assets/install-express.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/install-express.png -------------------------------------------------------------------------------- /assets/terminal-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/terminal-test.png -------------------------------------------------------------------------------- /assets/working-alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/working-alert.png -------------------------------------------------------------------------------- /assets/download-brackets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/assets/download-brackets.png -------------------------------------------------------------------------------- /_book/gitbook/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/_book/gitbook/images/favicon.ico -------------------------------------------------------------------------------- /_book/gitbook/fonts/fontawesome/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/_book/gitbook/fonts/fontawesome/FontAwesome.otf -------------------------------------------------------------------------------- /_book/gitbook/fonts/fontawesome/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/_book/gitbook/fonts/fontawesome/fontawesome-webfont.eot -------------------------------------------------------------------------------- /_book/gitbook/fonts/fontawesome/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/_book/gitbook/fonts/fontawesome/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff -------------------------------------------------------------------------------- /_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /_book/gitbook/images/apple-touch-icon-precomposed-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jugonzal/gitbook-node-chat-tutorial/HEAD/_book/gitbook/images/apple-touch-icon-precomposed-152.png -------------------------------------------------------------------------------- /content/setup/chrome.md: -------------------------------------------------------------------------------- 1 | # Google Chrome 2 | 3 | Different Web browsers provide different tools for doing Web development. The examples in this workshop will be using Google Chrome. You can [download it from Google](https://www.google.com/chrome/browser/desktop/index.html). 4 | 5 | ![](/assets/download-chrome.png) 6 | 7 | -------------------------------------------------------------------------------- /content/setup/nodejs.md: -------------------------------------------------------------------------------- 1 | # Node.js 2 | 3 | Node.js is a program for running JavaScript code on the server-side. Because we'll be coding a Web server today, we might as well write it in JavaScript because that's the language we code the client-side browser code in. 4 | 5 | Get it from [nodejs.org](https://nodejs.org/). 6 | 7 | ![nodejs.org](/assets/nodejs.png) -------------------------------------------------------------------------------- /content/setup/brackets.md: -------------------------------------------------------------------------------- 1 | # Brackets 2 | 3 | Brackets is a free code editor from Adobe. Basically code editors are word processors that only work on plain text files, but they can provide other cool features if they know what programming languages you're using. 4 | 5 | Download Brackets from [brackets.io](http://brackets.io/). 6 | 7 | ![](/assets/download-brackets.png) 8 | 9 | -------------------------------------------------------------------------------- /content/final/README.md: -------------------------------------------------------------------------------- 1 | # Final Thoughts 2 | 3 | This demonstration was a bold attempt at showing you how easy it is to get started with Web development, and that seemingly complex apps can be prototyped relatively quickly with modern software technology and approach. 4 | 5 | Thank you for spending your Saturday with us; I hope you enjoyed it and that you have wonderful weekend! 6 | -------------------------------------------------------------------------------- /content/part1/README.md: -------------------------------------------------------------------------------- 1 | # Part I 2 | 3 | ## HTML and CSS 4 | 5 | While this workshop is meant to teach you Javascript we have prepared a short sequence of exercises that will give you basic concepts about building the front-end to your web application. 6 | 7 | * [HTML](html.md) 8 | * [Dev Tools](dev-tools.md) 9 | * [CSS](css.md) 10 | * [CSS \(Example\)](final-css.md) 11 | 12 | After that, it is time to dive into [JavaScript](../part2/README.md) 13 | -------------------------------------------------------------------------------- /content/part2/README.md: -------------------------------------------------------------------------------- 1 | # Part II 2 | 3 | ## JavaScript: jQuery, Node, Express, and Web Sockets 4 | 5 | Having spent sometime preparing the look and feel of our web application, it is time we make it do something. This is where we dive into Javascript to code the behaviour. 6 | 7 | * [Client Side](client-js.md) 8 | * [Node](node.md) 9 | * [Express](express.md) 10 | * [Socket IO](socket.io.md) 11 | 12 | If you still have some time, here are some advanced exercises to keep you going: [Enhancements \(Stretch\)](../part3/README.md) 13 | 14 | -------------------------------------------------------------------------------- /GLOSSARY.md: -------------------------------------------------------------------------------- 1 | # devs 2 | Short form for developers. 3 | 4 | # coders 5 | Alias for devs/developers. 6 | 7 | # dependency 8 | Any software (tool or third party code) that our project needs in order to function. 9 | 10 | # a hack 11 | Using a technology in a way that is was not intended, but nonetheless works. 12 | 13 | # IDE 14 | Integrated Development Environment; everything you need to develop software in one interface, split into multiple sections usually. 15 | 16 | # library 17 | A package of code that performs a specific function and can be used by other code. 18 | 19 | # third party 20 | Someone or some team other than ourselves or our team that wrote some code that we're using on our project. Can be open source or proprietary. 21 | -------------------------------------------------------------------------------- /content/setup/README.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | Since we only have a few hours to get you up to speed on being a Javascript Developer, you would benefit from completing these steps before you arrive to the Workshop. 4 | 5 | Don't worry if you run into any issues. Our mentors will be ready to help you get set up upon your arrival. 6 | 7 | * You'll need a modern browser: [Chrome](chrome.md) 8 | * If you don't have a text editor where you can code we recommend [Brackets](brackets.md) 9 | * We'll share some code during the Workshop. Having an account on [GitHub](github.md) will speed things up. 10 | * You will develop Web server using Javascript. Install [Node.js](nodejs.md) 11 | * If you can't install Node, you can still participate but will need [Cloud9](cloud9.md) 12 | 13 | And once you are done, move on to learn about [HTML & CSS](../part1/README.md) 14 | 15 | 16 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [Introduction](README.md) 4 | * [Setup](content/setup/README.md) 5 | * [Chrome](content/setup/chrome.md) 6 | * [GitHub](content/setup/github.md) 7 | * [Brackets](content/setup/brackets.md) 8 | * [Node.js](content/setup/nodejs.md) 9 | * [Cloud9](content/setup/cloud9.md) 10 | * [Part I - HTML & CSS](content/part1/README.md) 11 | * [HTML](content/part1/html.md) 12 | * [Dev Tools](content/part1/dev-tools.md) 13 | * [CSS](content/part1/css.md) 14 | * [CSS \(Example\)](content/part1/final-css.md) 15 | * [Part II - JavaScript](content/part2/README.md) 16 | * [Client Side](content/part2/client-js.md) 17 | * [Node](content/part2/node.md) 18 | * [Express](content/part2/express.md) 19 | * [Socket IO](content/part2/socket.io.md) 20 | * [Part III - Enhancements \(Stretch\)](content/part3/README.md) 21 | * [Final Thoughts](content/final/README.md) 22 | 23 | -------------------------------------------------------------------------------- /content/setup/github.md: -------------------------------------------------------------------------------- 1 | # GitHub 2 | 3 | [GitHub](https://github.com/) is where a huge amount of open source code resides. Almost every software developer (whether they are Web, mobile, desktop or other) has a GitHub account these days. It also has some great developer workflow features. 4 | 5 | You will need to sign up for a GitHub account. If you already have one, please sign in. 6 | 7 | # Git 8 | 9 | GitHub is centered around an open source Version Control System (VCS) called Git. 10 | 11 | It's like Dropbox for coders. We need to make sure our project codebase is synced to a central server not only for backup purposes but also to share with other devs working on the same project. 12 | 13 | It gives us a lot more control than Dropbox though, and is not nearly as easy to use. That said, it's probably the most popular VCS today and continues to grow at a rapid pace, thanks to services like GitHub especially. 14 | 15 | If you were developing today's app on your own machine, you'd be installing Git. We've saved you that trouble, so no action required here. 16 | -------------------------------------------------------------------------------- /_book/gitbook/gitbook-plugin-search/search.css: -------------------------------------------------------------------------------- 1 | /* 2 | This CSS only styled the search results section, not the search input 3 | It defines the basic interraction to hide content when displaying results, etc 4 | */ 5 | #book-search-results .search-results { 6 | display: none; 7 | } 8 | #book-search-results .search-results ul.search-results-list { 9 | list-style-type: none; 10 | padding-left: 0; 11 | } 12 | #book-search-results .search-results ul.search-results-list li { 13 | margin-bottom: 1.5rem; 14 | padding-bottom: 0.5rem; 15 | /* Highlight results */ 16 | } 17 | #book-search-results .search-results ul.search-results-list li p em { 18 | background-color: rgba(255, 220, 0, 0.4); 19 | font-style: normal; 20 | } 21 | #book-search-results .search-results .no-results { 22 | display: none; 23 | } 24 | #book-search-results.open .search-results { 25 | display: block; 26 | } 27 | #book-search-results.open .search-noresults { 28 | display: none; 29 | } 30 | #book-search-results.no-results .search-results .has-results { 31 | display: none; 32 | } 33 | #book-search-results.no-results .search-results .no-results { 34 | display: block; 35 | } 36 | -------------------------------------------------------------------------------- /content/part1/dev-tools.md: -------------------------------------------------------------------------------- 1 | # Dev Tools 2 | 3 | With your ugly white page open, right click somewhere on the page (anywhere, really) and you'll notice an inspect element option. 4 | 5 | ![screenshot](http://d.pr/i/1cDvi/54xBeDeo+) 6 | 7 | Clicking that unlocks a most powerful yet kind-of secret feature that all major browsers have: **Dev Tools** (aka a Web Inspector). 8 | 9 | ![screenshot](http://d.pr/i/OARU/5dcHWvdE+) 10 | 11 | Hover over the HTML source code shown and notice that you can not only use it to inspect the page, but you can also edit it right there (double click the code) to see how it affects the page. 12 | 13 | Our browser gives us a live editor! Why? It's specifically there for developers to inspect _any_ page on the internet, to see how its HTML (and other things) are written. 14 | 15 | By the way, any changes you make through this editor are just experiments and won't actually "stick". If you refresh the page the changes go away. They don't save into your source code directly. 16 | 17 | Play around with it a bit more to get the hang of the "Elements" tab in the Dev Tools. 18 | 19 | Then select (click) the `` tag and on the right side you'll see something like this. 20 | 21 | ![screenshot](http://d.pr/i/1fEWN/3GyGKCU7+) 22 | 23 | And what if I double click inside those weird sideways mustaches and type in the following. 24 | 25 | ![screenshot](http://d.pr/i/sIzF/lZuPX9hb+) 26 | 27 | That, my friend, was CSS. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Logo](/assets/lhl-logo.png) 2 | 3 | # Introduction 4 | 5 | Hello and thank you for joining us for this JavaScript Essentials Workshop. 6 | 7 | My name is Juan Gonzalez and I am your Lighthouse Labs instructor today. 8 | 9 | My background is in software development, focusing on Web technologies. I started programming at a young age, selling my first piece of code at age 16 and eventually building very large web systems for large companies. 10 | 11 | For the past 10 years I have also been involved in some very interesting startups. 12 | 13 | ## The goal 14 | 15 | Today's goal is to get acquainted with JavaScript-based Web programming by creating a simple chat application. We'll use modern tools \(Node.js, Web Sockets, etc.\) and touch upon many different technologies. 16 | 17 | The objective is not to fully understand every line of code, but to understand server-client architecture and to be inspired by how much can be created with so little code. 18 | 19 | ## Pair programming 20 | 21 | You're encouraged to buddy up with one other person. That said, both of you should ideally do the setup work individually on your own laptops. 22 | 23 | ## The product 24 | 25 | The finished app that we'll be building in just a few hours today will look and feel much like this. 26 | 27 | ![Example](/assets/example-cropped.png) 28 | 29 | Let's get started with some [Setup](content/setup/README.md) or if you feel you can go faster here is a [Summary](SUMMARY.md) of all we'll cover. 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /content/part2/node.md: -------------------------------------------------------------------------------- 1 | # Node (JavaScript on the server)! 2 | 3 | So far we've been building a website with some static content and a bit of client-side interactivity. 4 | 5 | It's time to take it up a notch and graduate to "Web application" status. Server-side app logic is what separates a site from an app. 6 | 7 | ## Step 1 8 | 9 | Move all the "client" side files into their own folder called **client**. 10 | 11 | ![Client folder](/assets/client-folder.png) 12 | 13 | ## Step 2 14 | 15 | Now let's add another JavaScript file to be run on the server side which will power the logic for our chat application. Call it **server.js** and put it at the top level (at the same level as the **client** folder.) 16 | 17 | In it, put this one test line of code, to print a message to the screen so we know that it is working. 18 | 19 | ```javascript 20 | console.log('hello from our node script!'); 21 | ``` 22 | 23 | ![Server test](/assets/server-test.png) 24 | 25 | ## Step 3 26 | 27 | Let's run it. Open up the **Terminal** app on MacOS or **cmd.exe** on Windows to get to a command prompt. 28 | 29 | Next you'll have to change the working directory to the one where your project files are. In the example below I used the commands: 30 | 31 | ``` 32 | cd Lighthouse\ Labs 33 | ``` 34 | 35 | Then to run the file I did the command: 36 | 37 | ``` 38 | node server.js 39 | ``` 40 | 41 | The output should look like this. 42 | 43 | ``` 44 | hello from our node script! 45 | ``` 46 | 47 | And there's our message, nice! 48 | 49 | -------------------------------------------------------------------------------- /_book/gitbook/gitbook-plugin-search/search-engine.js: -------------------------------------------------------------------------------- 1 | require([ 2 | 'gitbook', 3 | 'jquery' 4 | ], function(gitbook, $) { 5 | // Global search objects 6 | var engine = null; 7 | var initialized = false; 8 | 9 | // Set a new search engine 10 | function setEngine(Engine, config) { 11 | initialized = false; 12 | engine = new Engine(config); 13 | 14 | init(config); 15 | } 16 | 17 | // Initialize search engine with config 18 | function init(config) { 19 | if (!engine) throw new Error('No engine set for research. Set an engine using gitbook.research.setEngine(Engine).'); 20 | 21 | return engine.init(config) 22 | .then(function() { 23 | initialized = true; 24 | gitbook.events.trigger('search.ready'); 25 | }); 26 | } 27 | 28 | // Launch search for query q 29 | function query(q, offset, length) { 30 | if (!initialized) throw new Error('Search has not been initialized'); 31 | return engine.search(q, offset, length); 32 | } 33 | 34 | // Get stats about search 35 | function getEngine() { 36 | return engine? engine.name : null; 37 | } 38 | 39 | function isInitialized() { 40 | return initialized; 41 | } 42 | 43 | // Initialize gitbook.search 44 | gitbook.search = { 45 | setEngine: setEngine, 46 | getEngine: getEngine, 47 | query: query, 48 | isInitialized: isInitialized 49 | }; 50 | }); -------------------------------------------------------------------------------- /content/setup/cloud9.md: -------------------------------------------------------------------------------- 1 | # Cloud9.io 2 | 3 | Cloud9 is amazing. It is for developers what Google docs is for MS Office. BTW if you still use MS Word and Excel instead of Google docs/drive for your spreadsheets and documents, you're living in the 2000s. All the cool kids are living in 2010s. 4 | 5 | Anyway, so what is Cloud9? I'm not surprised you're asking. There are many devs out there that don't know about c9 just yet... Just like how MS Office is still widely used. 6 | 7 | Here's the thing... it takes a lot of time and effort to setup your computer for writing software. A whole bunch of libraries and tools to install, and it's especially hard to make sure every developer on the same team has the exact same versions for all the dependencies. 8 | 9 | This is big hurdle especially when getting started with code. Cloud9 gives us a pre-configured machine in the cloud as well as a really slick IDE right in the browser. As long as you have internet, you can immediately start coding like a _Real Developer_™. 10 | 11 | ## Sign up 12 | 13 | So with that said, go ahead and [sign up for a c9 account on their website](https://c9.io/web/sign-up/free). _Use your github profile_ to sign up: 14 | 15 | ![screenshot](http://d.pr/i/T611/3KkIT0na+) 16 | 17 | Once you've done that, create a new workspace titled "chat-app". You can keep it public and select "Custom" as the type. 18 | 19 | ![screenshot](http://d.pr/i/9z1n/3MvoUudv+) 20 | 21 | At this point c9 will open a new browser tab and launch the editor. You're all set to start working on our app! -------------------------------------------------------------------------------- /content/part3/README.md: -------------------------------------------------------------------------------- 1 | # Enhancements as Challenges (Stretch) 2 | 3 | You may have noticed some bugs and broken features with this app. 4 | 5 | ## 1. Initial field - Part I 6 | 7 | The name/initial input field (the first input box) is not being used at all. Modify the `app.js` so that it sends (emits) the text as something like `"KV says: hello"` where `"KV"` is from the first input field (with `id="you"`) and `"hello"` is from the message field. 8 | 9 | ## 2. Initial field - Part II 10 | 11 | The name/initial input field is actually meant to be 2 letter initials only. Make it so only a maximum of two characters can be entered into that field. 12 | 13 | Hint: Google "html input field maximum length" for a convenient HTML attribute that can be added to your HTML file. 14 | 15 | ## 3. List of Messages 16 | 17 | It would be nice to see the message history on the server anytime you join the chat room. Unfortunately, we don't keep/store a message history on the server at all. 18 | 19 | One way to do this is to create an empty [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) that stores the messages. 20 | 21 | Then, whenever a message is received on the server, it can [push](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) (append) that message string into the array. 22 | 23 | Then whenever a user (new socket) connects to the server, (on `connection`) the server could iterate over all the messages in the array and `emit` them to that new client/socket. 24 | -------------------------------------------------------------------------------- /content/part1/final-css.md: -------------------------------------------------------------------------------- 1 | # Example CSS 2 | 3 | There is no "one right solution" to CSS. There are many approaches to solving the same thing (admittedly in some cases there are some better than others) not to mention all the creative freedom you get with it. 4 | 5 | That said, if you are looking for one possible CSS file so that you can move on, scroll on down! 6 | 7 | ```css 8 | body { 9 | background-color: white; 10 | color: #303030; 11 | font-family: 'Helvetica Neue', Arial, sans-serif; 12 | font-size: 15px; 13 | margin: 20px; 14 | } 15 | 16 | main { 17 | background-color: #f0f0f0; 18 | border-radius: 6px; 19 | box-shadow: 3px 3px 12px #c8c8c8; 20 | margin: 20px auto; 21 | max-width: 450px; 22 | padding: 20px; 23 | } 24 | 25 | ol { 26 | list-style: none; 27 | margin-bottom: 20px; 28 | margin-top: 0; 29 | padding: 0; 30 | } 31 | 32 | li { 33 | padding: 10px; 34 | } 35 | 36 | li:nth-child(odd) { 37 | background-color: #e3e3e3; 38 | border-radius: 6px; 39 | } 40 | 41 | form { 42 | background-color: lightsteelblue; 43 | border-radius: 6px; 44 | margin: 0; 45 | padding: 10px; 46 | } 47 | 48 | button { 49 | background-color: cornflowerblue; 50 | border: none; 51 | border-radius: 3px; 52 | color: white; 53 | font-size: 15px; 54 | font-weight: bold; 55 | padding: 5px 10px; 56 | text-transform: uppercase; 57 | } 58 | 59 | input { 60 | border: none; 61 | border-radius: 3px; 62 | font-size: 15px; 63 | padding: 5px; 64 | } 65 | 66 | #initials { 67 | width: 40px; 68 | } 69 | 70 | #message { 71 | width: 315px; 72 | } 73 | ``` 74 | -------------------------------------------------------------------------------- /_book/gitbook/gitbook-plugin-lunr/search-lunr.js: -------------------------------------------------------------------------------- 1 | require([ 2 | 'gitbook', 3 | 'jquery' 4 | ], function(gitbook, $) { 5 | // Define global search engine 6 | function LunrSearchEngine() { 7 | this.index = null; 8 | this.store = {}; 9 | this.name = 'LunrSearchEngine'; 10 | } 11 | 12 | // Initialize lunr by fetching the search index 13 | LunrSearchEngine.prototype.init = function() { 14 | var that = this; 15 | var d = $.Deferred(); 16 | 17 | $.getJSON(gitbook.state.basePath+'/search_index.json') 18 | .then(function(data) { 19 | // eslint-disable-next-line no-undef 20 | that.index = lunr.Index.load(data.index); 21 | that.store = data.store; 22 | d.resolve(); 23 | }); 24 | 25 | return d.promise(); 26 | }; 27 | 28 | // Search for a term and return results 29 | LunrSearchEngine.prototype.search = function(q, offset, length) { 30 | var that = this; 31 | var results = []; 32 | 33 | if (this.index) { 34 | results = $.map(this.index.search(q), function(result) { 35 | var doc = that.store[result.ref]; 36 | 37 | return { 38 | title: doc.title, 39 | url: doc.url, 40 | body: doc.summary || doc.body 41 | }; 42 | }); 43 | } 44 | 45 | return $.Deferred().resolve({ 46 | query: q, 47 | results: results.slice(0, length), 48 | count: results.length 49 | }).promise(); 50 | }; 51 | 52 | // Set gitbook research 53 | gitbook.events.bind('start', function(e, config) { 54 | var engine = gitbook.search.getEngine(); 55 | if (!engine) { 56 | gitbook.search.setEngine(LunrSearchEngine, config); 57 | } 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /content/part2/express.md: -------------------------------------------------------------------------------- 1 | # Express for our web server 2 | 3 | So far we've created a Node script that prints something out to the terminal, which is great. Instead of doing that though, we need it to do something real. 4 | 5 | In our case, we're building a web server, more specifically a _chat 'server'_. So we need to listen for incoming HTTP requests and then send down the HTML, CSS and JavaScript that we wrote earlier for our chat client. 6 | 7 | While Node comes with basic HTTP handling support, a very (probably the most) popular 3rd party library (called "modules" in the Node community) named **Express** is used by most developers writing Web servers in Node. We shall use it too! 8 | 9 | ## Step 1 10 | 11 | Let's make sure our folder is ready to work with other libraries. We do this by initializing our folder: 12 | 13 | ``` 14 | npm init -y 15 | ``` 16 | 17 | Once this command runs, you will simple notice a new file `package.json` in your folder. Let's install and save the Express library into our project by running this command from the command line that we have open. 18 | 19 | ``` 20 | npm install express 21 | ``` 22 | 23 | This downloads some code using the Node Package Manager (NPM) that we can use to make our lives easier. 24 | 25 | ![Install Express](/assets/install-express.png) 26 | 27 | Now we can start using it. Type out the following JavaScript code into the **server.js** file. 28 | 29 | ```javascript 30 | var express = require('express'); 31 | var app = express(); 32 | 33 | var http = require('http'); 34 | var server = http.Server(app); 35 | 36 | app.use(express.static('client')); 37 | 38 | server.listen(8080, function() { 39 | console.log('Chat server running'); 40 | }); 41 | ``` 42 | 43 | ### Explanation 44 | 45 | So a bunch of new code and syntax was just introduced there. Let's attempt to break it down. 46 | 47 | The first few lines are just loading external modules. We then tell the Express app to server all static content from the **client** folder. 48 | 49 | When all the setup work is done, we then tell the server to listen in on a certain port (in this case 8080.) 50 | 51 | So for now it's a simple web server serving only static (HTML, CSS and JavaScript) files to any HTTP/Web traffic coming its way. 52 | 53 | Let's try it out by running it using the same command as before. 54 | 55 | ``` 56 | node server.js 57 | ``` 58 | 59 | Now visit in your Web browser. It will bring up the chat app page just like before, with no new functionality. The send button should be working as before, too! 60 | -------------------------------------------------------------------------------- /_book/gitbook/gitbook-plugin-sharing/buttons.js: -------------------------------------------------------------------------------- 1 | require(['gitbook', 'jquery'], function(gitbook, $) { 2 | var SITES = { 3 | 'facebook': { 4 | 'label': 'Facebook', 5 | 'icon': 'fa fa-facebook', 6 | 'onClick': function(e) { 7 | e.preventDefault(); 8 | window.open('http://www.facebook.com/sharer/sharer.php?s=100&p[url]='+encodeURIComponent(location.href)); 9 | } 10 | }, 11 | 'twitter': { 12 | 'label': 'Twitter', 13 | 'icon': 'fa fa-twitter', 14 | 'onClick': function(e) { 15 | e.preventDefault(); 16 | window.open('http://twitter.com/home?status='+encodeURIComponent(document.title+' '+location.href)); 17 | } 18 | }, 19 | 'google': { 20 | 'label': 'Google+', 21 | 'icon': 'fa fa-google-plus', 22 | 'onClick': function(e) { 23 | e.preventDefault(); 24 | window.open('https://plus.google.com/share?url='+encodeURIComponent(location.href)); 25 | } 26 | }, 27 | 'weibo': { 28 | 'label': 'Weibo', 29 | 'icon': 'fa fa-weibo', 30 | 'onClick': function(e) { 31 | e.preventDefault(); 32 | window.open('http://service.weibo.com/share/share.php?content=utf-8&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)); 33 | } 34 | }, 35 | 'instapaper': { 36 | 'label': 'Instapaper', 37 | 'icon': 'fa fa-instapaper', 38 | 'onClick': function(e) { 39 | e.preventDefault(); 40 | window.open('http://www.instapaper.com/text?u='+encodeURIComponent(location.href)); 41 | } 42 | }, 43 | 'vk': { 44 | 'label': 'VK', 45 | 'icon': 'fa fa-vk', 46 | 'onClick': function(e) { 47 | e.preventDefault(); 48 | window.open('http://vkontakte.ru/share.php?url='+encodeURIComponent(location.href)); 49 | } 50 | } 51 | }; 52 | 53 | 54 | 55 | gitbook.events.bind('start', function(e, config) { 56 | var opts = config.sharing; 57 | 58 | // Create dropdown menu 59 | var menu = $.map(opts.all, function(id) { 60 | var site = SITES[id]; 61 | 62 | return { 63 | text: site.label, 64 | onClick: site.onClick 65 | }; 66 | }); 67 | 68 | // Create main button with dropdown 69 | if (menu.length > 0) { 70 | gitbook.toolbar.createButton({ 71 | icon: 'fa fa-share-alt', 72 | label: 'Share', 73 | position: 'right', 74 | dropdown: [menu] 75 | }); 76 | } 77 | 78 | // Direct actions to share 79 | $.each(SITES, function(sideId, site) { 80 | if (!opts[sideId]) return; 81 | 82 | gitbook.toolbar.createButton({ 83 | icon: site.icon, 84 | label: site.text, 85 | position: 'right', 86 | onClick: site.onClick 87 | }); 88 | }); 89 | }); 90 | }); 91 | -------------------------------------------------------------------------------- /content/part1/css.md: -------------------------------------------------------------------------------- 1 | # CSS 2 | 3 | If HTML is the bread and butter of a web page, then CSS is our butter knife. 4 | 5 | Why is CSS the knife? Well, it controls _what goes where_. Using CSS we declare how we'd like the content (HTML) to be presented. 6 | 7 | CSS stands for Cascading Stylesheets. The key word here is "style", referring to the way something _looks_. 8 | 9 | ## Step 1 10 | 11 | Let's prepare our HTML document to _link_ a stylesheet (**.css**) file to it. 12 | 13 | Add the following HTML tag to the top of your **index.html** file and save it. 14 | 15 | ```html 16 | 17 | ``` 18 | 19 | When the HTML file is loaded again, it will ask the browser to fetch another file (called **style.css**) from the Web server and apply its rules to our HTML page. 20 | 21 | ## Step 2 22 | 23 | Oops, we don't even have that file in our project, let's add it the same way we created the **index.html** file. 24 | 25 | Make sure to call it **style.css** exactly as it is in the tag. 26 | 27 | ## Step 3 28 | 29 | Inside the empty CSS file, add the code provided below. I would suggest that you type this out and do it incrementally (save and refresh the page to see the change after each major section instead of typing it all out at once.) 30 | 31 | Note that if no changes are reflected in the webpage (upon refreshing the page) then please confirm that your `` tag is correct. Still a problem? Ask for help from your peers or a mentor. 32 | 33 | ```css 34 | body { 35 | background-color: white; 36 | color: #303030; 37 | font-family: 'Helvetica Neue', Arial, sans-serif; 38 | margin: 20px; 39 | } 40 | 41 | main { 42 | background-color: #f0f0f0; 43 | margin: 20px auto; 44 | max-width: 450px; 45 | padding: 20px; 46 | } 47 | ``` 48 | 49 | ## Step 4 50 | 51 | I'm _not_ going to explain to you what this code is doing and how it's working. Discuss among yourself and try and use your powers of reasoning, critical thinking and experimentation to solve the mysteries of CSS syntax. Look for patterns to help identify conventions and rules. HTML has its own completely different set of rules from CSS, but all languages have rules, and computer languages need strict rules. Use this to your benefit to reason toward conclusions. 52 | 53 | Also, feel free to Google terms like "[CSS background color](https://google.com/?q=CSS+background+color)". 54 | 55 | The end result should look a little bit closer to what we're trying to get to. 56 | 57 | ## Step 5 - A challenge 58 | 59 | Add a few "list items" (for example `
  • DV says: hey
  • `) inside of the `
      ` element so that you have some fake messages that can be styled. Add at least four of these. They can be removed later when we get into JavaScript. 60 | 61 | Now use CSS to try and make the page look closer to this. 62 | 63 | ![Example](/assets/example.png) 64 | 65 | If you have time to spare, give it your own unique look. 66 | 67 | ### Properties 68 | 69 | Here is a list of CSS properties that you may want to try. 70 | 71 | * `width` 72 | * `background-color` 73 | * `padding` 74 | * `margin` 75 | * `border` 76 | * `border-radius` 77 | * `font-size` 78 | 79 | Feel free to Google them along with the keyword "CSS" to learn by example. StackOverflow, w3schools and MDN are all great resources that you'll likely end up on naturally. They tend to be highest in results. 80 | 81 | You'll likely need a few more CSS properties. Take your time. :) 82 | -------------------------------------------------------------------------------- /_book/gitbook/gitbook-plugin-highlight/ebook.css: -------------------------------------------------------------------------------- 1 | pre, 2 | code { 3 | /* http://jmblog.github.io/color-themes-for-highlightjs */ 4 | /* Tomorrow Comment */ 5 | /* Tomorrow Red */ 6 | /* Tomorrow Orange */ 7 | /* Tomorrow Yellow */ 8 | /* Tomorrow Green */ 9 | /* Tomorrow Aqua */ 10 | /* Tomorrow Blue */ 11 | /* Tomorrow Purple */ 12 | } 13 | pre .hljs-comment, 14 | code .hljs-comment, 15 | pre .hljs-title, 16 | code .hljs-title { 17 | color: #8e908c; 18 | } 19 | pre .hljs-variable, 20 | code .hljs-variable, 21 | pre .hljs-attribute, 22 | code .hljs-attribute, 23 | pre .hljs-tag, 24 | code .hljs-tag, 25 | pre .hljs-regexp, 26 | code .hljs-regexp, 27 | pre .hljs-deletion, 28 | code .hljs-deletion, 29 | pre .ruby .hljs-constant, 30 | code .ruby .hljs-constant, 31 | pre .xml .hljs-tag .hljs-title, 32 | code .xml .hljs-tag .hljs-title, 33 | pre .xml .hljs-pi, 34 | code .xml .hljs-pi, 35 | pre .xml .hljs-doctype, 36 | code .xml .hljs-doctype, 37 | pre .html .hljs-doctype, 38 | code .html .hljs-doctype, 39 | pre .css .hljs-id, 40 | code .css .hljs-id, 41 | pre .css .hljs-class, 42 | code .css .hljs-class, 43 | pre .css .hljs-pseudo, 44 | code .css .hljs-pseudo { 45 | color: #c82829; 46 | } 47 | pre .hljs-number, 48 | code .hljs-number, 49 | pre .hljs-preprocessor, 50 | code .hljs-preprocessor, 51 | pre .hljs-pragma, 52 | code .hljs-pragma, 53 | pre .hljs-built_in, 54 | code .hljs-built_in, 55 | pre .hljs-literal, 56 | code .hljs-literal, 57 | pre .hljs-params, 58 | code .hljs-params, 59 | pre .hljs-constant, 60 | code .hljs-constant { 61 | color: #f5871f; 62 | } 63 | pre .ruby .hljs-class .hljs-title, 64 | code .ruby .hljs-class .hljs-title, 65 | pre .css .hljs-rules .hljs-attribute, 66 | code .css .hljs-rules .hljs-attribute { 67 | color: #eab700; 68 | } 69 | pre .hljs-string, 70 | code .hljs-string, 71 | pre .hljs-value, 72 | code .hljs-value, 73 | pre .hljs-inheritance, 74 | code .hljs-inheritance, 75 | pre .hljs-header, 76 | code .hljs-header, 77 | pre .hljs-addition, 78 | code .hljs-addition, 79 | pre .ruby .hljs-symbol, 80 | code .ruby .hljs-symbol, 81 | pre .xml .hljs-cdata, 82 | code .xml .hljs-cdata { 83 | color: #718c00; 84 | } 85 | pre .css .hljs-hexcolor, 86 | code .css .hljs-hexcolor { 87 | color: #3e999f; 88 | } 89 | pre .hljs-function, 90 | code .hljs-function, 91 | pre .python .hljs-decorator, 92 | code .python .hljs-decorator, 93 | pre .python .hljs-title, 94 | code .python .hljs-title, 95 | pre .ruby .hljs-function .hljs-title, 96 | code .ruby .hljs-function .hljs-title, 97 | pre .ruby .hljs-title .hljs-keyword, 98 | code .ruby .hljs-title .hljs-keyword, 99 | pre .perl .hljs-sub, 100 | code .perl .hljs-sub, 101 | pre .javascript .hljs-title, 102 | code .javascript .hljs-title, 103 | pre .coffeescript .hljs-title, 104 | code .coffeescript .hljs-title { 105 | color: #4271ae; 106 | } 107 | pre .hljs-keyword, 108 | code .hljs-keyword, 109 | pre .javascript .hljs-function, 110 | code .javascript .hljs-function { 111 | color: #8959a8; 112 | } 113 | pre .hljs, 114 | code .hljs { 115 | display: block; 116 | background: white; 117 | color: #4d4d4c; 118 | padding: 0.5em; 119 | } 120 | pre .coffeescript .javascript, 121 | code .coffeescript .javascript, 122 | pre .javascript .xml, 123 | code .javascript .xml, 124 | pre .tex .hljs-formula, 125 | code .tex .hljs-formula, 126 | pre .xml .javascript, 127 | code .xml .javascript, 128 | pre .xml .vbscript, 129 | code .xml .vbscript, 130 | pre .xml .css, 131 | code .xml .css, 132 | pre .xml .hljs-cdata, 133 | code .xml .hljs-cdata { 134 | opacity: 0.5; 135 | } 136 | -------------------------------------------------------------------------------- /content/part1/html.md: -------------------------------------------------------------------------------- 1 | # HTML 2 | 3 | HTML is the most fundamental language used on the Web. With it, we add information into documents that explain how they are linked together — that's how the Web works! 4 | 5 | Now let's use it to build our app. 6 | 7 | ## Step 1 8 | 9 | Create a folder on your computer to put the files for this project. A good name for the folder might be **Lighthouse Labs**. Then go to **File > Open Folder...** and select your new folder. 10 | 11 | ![Open Folder](/assets/open-folder.png) 12 | 13 | You should now see an empty workspace ready for us to create our project in. 14 | 15 | Create an new file in your project called **index.html** by right clicking the grey area on the left hand side. 16 | 17 | ![New File](/assets/new-file.png) 18 | 19 | ![index.html](/assets/index.html.png) 20 | 21 | Open the file and add the following html code into it. 22 | 23 | ```html 24 |

      hello, world

      25 | ``` 26 | 27 | It should look like this. 28 | 29 | ![hello, world](/assets/hello-world.png) 30 | 31 | Save the file and then navigate to your project folder and choose to open the **index.html** file in your Web browser. You'll get something like this. 32 | 33 | ![Hello, Chrome](/assets/hello-browser.png) 34 | 35 | And that's it — you just built a Web page! 36 | 37 | ## Step 2 38 | 39 | Let's build out the "markup" (structure) of our web page so it looks more like our goal, which is something like this. 40 | 41 | ![example](/assets/example.png) 42 | 43 | Here's a description of the what it contains. 44 | 45 | 1. A main area 46 | 2. Inside that there is the message history box 47 | 3. Inside the message history box is a list of messages 48 | 4. Below that is a form containing two input fields and a "Send" button. The first input field is for the initials of the person sending the message and the second is the message itself. 49 | 50 | The initial HTML for this can be something like the following. Replace the content of **index.html** with this code. Please type it out instead of using copy and paste. 51 | 52 | ```html 53 |
      54 |
        55 |
      56 |
      57 | 58 | 59 | 60 |
      61 |
      62 | ``` 63 | 64 | Note a few important properties of HTML here. 65 | 66 | ### Tags define elements 67 | 68 | Tags look like `` and they have *meaning*. Examples of tags are `

      ` which means "paragraph" and `

      ` means a "first level heading". 69 | 70 | Most tags need an accompanying closing tag, for example `

      ` or `

      ` after the text that goes inside the paragraph or heading. 71 | 72 | ### Nesting 73 | 74 | We indent our code when that content is *inside* a tag (between opening and closing tags) so that it's easy to understand what code is inside other code. 75 | 76 | ### IDs 77 | 78 | We give `id`'s to certain elements so that they can be quickly referenced later. 79 | 80 | This `id="something"` key-value pair that is part of an HTML tag is called an HTML attribute. Elements can have zero or more attributes. Attributes are cool and come in handy later. 81 | 82 | ## Step 3 83 | 84 | Let's save and refresh the browser tab where the **index.html** file is open. It will hopefully look a lot like our final product. 85 | 86 | ![No style](/assets/no-styles.png) 87 | 88 | Hm...not quite. Why does it appear this way and not like the example? 89 | 90 | We have provided the browser with a good understanding of the *structure* of our Web page, but not how to present it. The presentation rules are defined using another language called CSS. 91 | 92 | ## Questions? 93 | 94 | If you have any questions about the above, flag me or another mentor so that we can answer any questions you may have. 95 | 96 | Otherwise, it's time to move on to the next section. 97 | -------------------------------------------------------------------------------- /content/part2/socket.io.md: -------------------------------------------------------------------------------- 1 | # Socket.IO for Real-time messaging 2 | 3 | Now it's time to add the last missing, yet crucial piece to our app: _chat functionality_! 4 | 5 | To do this, we will leverage yet another 3rd party Node module. It's called Socket.io. 6 | 7 | Check it out here: . 8 | 9 | Socket.io will leverage a more core technology that browsers give us called Web Sockets. 10 | 11 | What's nice about Socket.io is that it will let us write similar JS code on both the client (browser) side and at the server (Node) side. 12 | 13 | ## Step 1 14 | 15 | Run the following command in the terminal window to install it on the server. 16 | 17 | `npm install socket.io` 18 | 19 | ![screenshot](http://d.pr/i/17YCR/5L1xyxJ3+) 20 | 21 | ## Step 2 22 | 23 | Now let's add some code in `server.js` that will use this library. This code block should be placed before/above `server.listen`. 24 | 25 | ```javascript 26 | var io = require('socket.io')(server); 27 | 28 | io.on('connection', function (socket) { 29 | socket.on('message', function (msg) { 30 | io.emit('message', msg); 31 | }); 32 | }); 33 | ``` 34 | 35 | ## Step 3 36 | 37 | Next, we need to add similar logic to the client app. 38 | 39 | Open the `index.html` file and modify the `script` tags below so that we also reference and make use of Socket.IO. We can do this by adding one more script tag before our `app.js`script tag, so that it looks like this down there. 40 | 41 | ```html 42 | 43 | 44 | 45 | ``` 46 | 47 | ## Step 4 48 | 49 | Open `app.js`, our client-side JS code file and let's add some code to send and receive messages from the browser. 50 | 51 | Add the following code to the very top of the file. 52 | 53 | ```javascript 54 | var socket = io(); 55 | ``` 56 | 57 | This is saying that `socket` is now a reference to the SocketIO library. 58 | 59 | ## Step 5 60 | 61 | In that same file, replace the `alert` line from before with the following code: 62 | 63 | ```javascript 64 | socket.emit('message', text); 65 | $('#message').val(''); 66 | ``` 67 | 68 | The code above says to emit the textual message to the server instead of performing our temporary `alert` behavior. The second line in the code simply clears the input so that another message can be typed by the same user. 69 | 70 | We're not done yet, we need to listen for messages that are received from the server and append them into the message list. Add the following code at the bottom of the file: 71 | 72 | ```javascript 73 | socket.on('message', function (msg) { 74 | $('
    1. ').text(msg).appendTo('#history'); 75 | }); 76 | ``` 77 | 78 | This part tells the browser that any time a message is received from the real time web socket connection with the server, create a new `
    2. ` (list item) HTML element and append it to the messages `
        ` (container). 79 | 80 | ## Final code for app.js 81 | 82 | The `app.js` file should look like this. 83 | 84 | ```javascript 85 | var socket = io(); 86 | 87 | $('form').on('submit',function () { 88 | var text = $('#message').val(); 89 | 90 | socket.emit('message', text); 91 | $('#message').val(''); 92 | 93 | return false; 94 | }); 95 | 96 | socket.on('message', function (msg) { 97 | $('
      1. ').text(msg).appendTo('#history'); 98 | }); 99 | ``` 100 | 101 | ## Final code for server.js 102 | 103 | The `server.js` file should look like this: 104 | 105 | ```javascript 106 | var express = require('express'); 107 | var app = express(); 108 | 109 | var http = require('http'); 110 | var server = http.Server(app); 111 | 112 | app.use(express.static('client')); 113 | 114 | var io = require('socket.io')(server); 115 | 116 | var database = []; 117 | 118 | io.on('connection', function (socket) { 119 | socket.on('message', function (msg) { 120 | database.push(msg); 121 | io.emit('message', msg); 122 | console.log(database); 123 | }); 124 | }); 125 | 126 | server.listen(8080, 'localhost', function () { 127 | var addr = server.address(); 128 | console.log("Chat server running at", addr.address + ":" + addr.port); 129 | }); 130 | ``` 131 | 132 | ## Whoa, it works! 133 | 134 | Make sure all your files are saved, and the Node server is still running, and give it a shot. 135 | 136 | That's right, it works! That's all it took. The basic chat functionality works. Have your peer go to the same URL that you're on and you guys should be able to communicate! 137 | 138 | Note: newcomers to the chat room can't see any previous messages (message history). We would have to implement that functionality for it to work that way. 139 | 140 | ## Screenshot 141 | 142 | ![screenshot](http://d.pr/i/15CQJ/4WxT350g+) 143 | -------------------------------------------------------------------------------- /content/part2/client-js.md: -------------------------------------------------------------------------------- 1 | # JavaScript in the Browser 2 | 3 | Let's add some behaviour to your webpage so it actually does something useful. That's where JavaScript comes in. 4 | 5 | ## Step 1 6 | 7 | Much like with the CSS, we need to link our new **.js** code with our web page, our **.html** file. 8 | 9 | Add the following tags to the *bottom* of the HTML file. 10 | 11 | ```html 12 | 13 | 14 | ``` 15 | 16 | Now whenever you refresh/load the web page, it will reference two separate JS files for the browser to download (at the end), one of which is external (3rd party) to our application. This 3rd party library called jQuery is there to make life easier. We don't **need** it, but with it we can write less code. This is why most websites use jQuery or other libraries like it. 17 | 18 | ## Step 2 19 | 20 | The second file **app.js** needs to exist in our workspace, so let's create it just like you created **style.css** earlier. 21 | 22 | It will be empty at first, but let's add the following code into it. 23 | 24 | ```javascript 25 | alert('hello from the JS file'); 26 | ``` 27 | 28 | Save the file and refresh the HTML file in your browser. When the page loads you should see an alert pop up that says your message. 29 | 30 | ![Alert](/assets/alert.png) 31 | 32 | `alert` is a built in function that all browsers support, even though they may look slightly different on each browser. I'm guessing it's not your first time seeing one, so now you know how they happen. 33 | 34 | Any time you call a function in JS you have to use parentheses `()` after it, and within the brackets you put in data that you want to give the function. Programming functions are much like math functions. They take in values and can do some crunching and give you back a computed value, or in this case, give you back some behaviour like popup that message you passed into it. 35 | 36 | Every single predefined JavaScript function has documentation, so we can look up details about how they work. [Case in point](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert). 37 | 38 | Very soon, we'll create our own function while using other functions. It's going to get a bit more real, so hold on to your suspenders! 39 | 40 | ## Step 3 41 | 42 | **Remove the `alert` code** and let's get down to business. We want to make it so when our `
        ` is submitted (via enter key or by clicking the send button) we read the text content of the input field (with `id="message"` in the HTML file) and do something with it. For now let's just `alert` it. 43 | 44 | ```javascript 45 | $('form').on('submit',function () { 46 | var text = $('#message').val(); 47 | alert(text); 48 | return false; 49 | }); 50 | ``` 51 | 52 | Remember, type that out yourself. Don't copy paste it. Assuming you started and closed all the brackets, quotes, and semicolons correctly, it should add some interesting behaviour to the page. 53 | 54 | Save the file, and refresh the HTML page. Put some text into the second field and hit Enter or click Send. You should see it echoed back to you in an alert message. If not, review or otherwise seek help. 55 | 56 | ![Working alert](/assets/working-alert.png) 57 | 58 | ### Explanation 59 | 60 | The code above isn't doing too much, but it does need to be reviewed before we move on. 61 | 62 | First, we use **jQuery** using the `$` function, telling it that we want to target all `form` elements on the page. There is only one form element on the page and it is the one at the bottom which contains both input fields and the button. 63 | 64 | Note how we don't use the `<`angle`>` brackets when targeting elements here, just like with CSS. Angle brackets are solely used to *define* tags in the HTML page. 65 | 66 | We then call/invoke another function called `on` on that returned form element, saying that we want to be notified anytime that a very specific *event* takes place. In this case the event we care about is `submit`. 67 | 68 | Asking to be notified when a given event takes place and waiting for it to happen is a very popular programming paradigm called **event-driven programming** Once the event takes place, we will be notified via our own custom function. That's right, `on` is a function that accepts another function as a parameter. Read that again. Look at the code. Remember that we pass in data into functions within the parentheses `()`. They're not on the same line, but they are there. 69 | 70 | This part may be a bit confusing but perhaps this annotated code can help you see it better. 71 | 72 | ![Annotated code](/assets/annotated.png) 73 | 74 | Otherwise, call over a mentor for explanation. 75 | 76 | Inside our function, the rest of the code is indented so that we know that it is within that function, just like we nest HTML tags with indentation. Make sure your code is indented correctly because improper indentation is a big source of confusion. 77 | 78 | This inside code is capturing the text value of the HTML element with the ID `message` and then passing it to `alert` so that we can see it. 79 | 80 | Lastly, the `return false` is there to tell the browser to cancel the original form submission logic (which is to attempt sending the form to the server, with loading spinner and everything.) This is common practice when adding custom behaviour to forms like we are doing here. 81 | -------------------------------------------------------------------------------- /_book/gitbook/gitbook-plugin-search/search.js: -------------------------------------------------------------------------------- 1 | require([ 2 | 'gitbook', 3 | 'jquery' 4 | ], function(gitbook, $) { 5 | var MAX_RESULTS = 15; 6 | var MAX_DESCRIPTION_SIZE = 500; 7 | 8 | var usePushState = (typeof history.pushState !== 'undefined'); 9 | 10 | // DOM Elements 11 | var $body = $('body'); 12 | var $bookSearchResults; 13 | var $searchInput; 14 | var $searchList; 15 | var $searchTitle; 16 | var $searchResultsCount; 17 | var $searchQuery; 18 | 19 | // Throttle search 20 | function throttle(fn, wait) { 21 | var timeout; 22 | 23 | return function() { 24 | var ctx = this, args = arguments; 25 | if (!timeout) { 26 | timeout = setTimeout(function() { 27 | timeout = null; 28 | fn.apply(ctx, args); 29 | }, wait); 30 | } 31 | }; 32 | } 33 | 34 | function displayResults(res) { 35 | $bookSearchResults.addClass('open'); 36 | 37 | var noResults = res.count == 0; 38 | $bookSearchResults.toggleClass('no-results', noResults); 39 | 40 | // Clear old results 41 | $searchList.empty(); 42 | 43 | // Display title for research 44 | $searchResultsCount.text(res.count); 45 | $searchQuery.text(res.query); 46 | 47 | // Create an
      2. element for each result 48 | res.results.forEach(function(res) { 49 | var $li = $('
      3. ', { 50 | 'class': 'search-results-item' 51 | }); 52 | 53 | var $title = $('

        '); 54 | 55 | var $link = $('', { 56 | 'href': gitbook.state.basePath + '/' + res.url, 57 | 'text': res.title 58 | }); 59 | 60 | var content = res.body.trim(); 61 | if (content.length > MAX_DESCRIPTION_SIZE) { 62 | content = content.slice(0, MAX_DESCRIPTION_SIZE).trim()+'...'; 63 | } 64 | var $content = $('

        ').html(content); 65 | 66 | $link.appendTo($title); 67 | $title.appendTo($li); 68 | $content.appendTo($li); 69 | $li.appendTo($searchList); 70 | }); 71 | } 72 | 73 | function launchSearch(q) { 74 | // Add class for loading 75 | $body.addClass('with-search'); 76 | $body.addClass('search-loading'); 77 | 78 | // Launch search query 79 | throttle(gitbook.search.query(q, 0, MAX_RESULTS) 80 | .then(function(results) { 81 | displayResults(results); 82 | }) 83 | .always(function() { 84 | $body.removeClass('search-loading'); 85 | }), 1000); 86 | } 87 | 88 | function closeSearch() { 89 | $body.removeClass('with-search'); 90 | $bookSearchResults.removeClass('open'); 91 | } 92 | 93 | function launchSearchFromQueryString() { 94 | var q = getParameterByName('q'); 95 | if (q && q.length > 0) { 96 | // Update search input 97 | $searchInput.val(q); 98 | 99 | // Launch search 100 | launchSearch(q); 101 | } 102 | } 103 | 104 | function bindSearch() { 105 | // Bind DOM 106 | $searchInput = $('#book-search-input input'); 107 | $bookSearchResults = $('#book-search-results'); 108 | $searchList = $bookSearchResults.find('.search-results-list'); 109 | $searchTitle = $bookSearchResults.find('.search-results-title'); 110 | $searchResultsCount = $searchTitle.find('.search-results-count'); 111 | $searchQuery = $searchTitle.find('.search-query'); 112 | 113 | // Launch query based on input content 114 | function handleUpdate() { 115 | var q = $searchInput.val(); 116 | 117 | if (q.length == 0) { 118 | closeSearch(); 119 | } 120 | else { 121 | launchSearch(q); 122 | } 123 | } 124 | 125 | // Detect true content change in search input 126 | // Workaround for IE < 9 127 | var propertyChangeUnbound = false; 128 | $searchInput.on('propertychange', function(e) { 129 | if (e.originalEvent.propertyName == 'value') { 130 | handleUpdate(); 131 | } 132 | }); 133 | 134 | // HTML5 (IE9 & others) 135 | $searchInput.on('input', function(e) { 136 | // Unbind propertychange event for IE9+ 137 | if (!propertyChangeUnbound) { 138 | $(this).unbind('propertychange'); 139 | propertyChangeUnbound = true; 140 | } 141 | 142 | handleUpdate(); 143 | }); 144 | 145 | // Push to history on blur 146 | $searchInput.on('blur', function(e) { 147 | // Update history state 148 | if (usePushState) { 149 | var uri = updateQueryString('q', $(this).val()); 150 | history.pushState({ path: uri }, null, uri); 151 | } 152 | }); 153 | } 154 | 155 | gitbook.events.on('page.change', function() { 156 | bindSearch(); 157 | closeSearch(); 158 | 159 | // Launch search based on query parameter 160 | if (gitbook.search.isInitialized()) { 161 | launchSearchFromQueryString(); 162 | } 163 | }); 164 | 165 | gitbook.events.on('search.ready', function() { 166 | bindSearch(); 167 | 168 | // Launch search from query param at start 169 | launchSearchFromQueryString(); 170 | }); 171 | 172 | function getParameterByName(name) { 173 | var url = window.location.href; 174 | name = name.replace(/[\[\]]/g, '\\$&'); 175 | var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)', 'i'), 176 | results = regex.exec(url); 177 | if (!results) return null; 178 | if (!results[2]) return ''; 179 | return decodeURIComponent(results[2].replace(/\+/g, ' ')); 180 | } 181 | 182 | function updateQueryString(key, value) { 183 | value = encodeURIComponent(value); 184 | 185 | var url = window.location.href; 186 | var re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi'), 187 | hash; 188 | 189 | if (re.test(url)) { 190 | if (typeof value !== 'undefined' && value !== null) 191 | return url.replace(re, '$1' + key + '=' + value + '$2$3'); 192 | else { 193 | hash = url.split('#'); 194 | url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, ''); 195 | if (typeof hash[1] !== 'undefined' && hash[1] !== null) 196 | url += '#' + hash[1]; 197 | return url; 198 | } 199 | } 200 | else { 201 | if (typeof value !== 'undefined' && value !== null) { 202 | var separator = url.indexOf('?') !== -1 ? '&' : '?'; 203 | hash = url.split('#'); 204 | url = hash[0] + separator + key + '=' + value; 205 | if (typeof hash[1] !== 'undefined' && hash[1] !== null) 206 | url += '#' + hash[1]; 207 | return url; 208 | } 209 | else 210 | return url; 211 | } 212 | } 213 | }); 214 | -------------------------------------------------------------------------------- /_book/gitbook/gitbook-plugin-fontsettings/fontsettings.js: -------------------------------------------------------------------------------- 1 | require(['gitbook', 'jquery'], function(gitbook, $) { 2 | // Configuration 3 | var MAX_SIZE = 4, 4 | MIN_SIZE = 0, 5 | BUTTON_ID; 6 | 7 | // Current fontsettings state 8 | var fontState; 9 | 10 | // Default themes 11 | var THEMES = [ 12 | { 13 | config: 'white', 14 | text: 'White', 15 | id: 0 16 | }, 17 | { 18 | config: 'sepia', 19 | text: 'Sepia', 20 | id: 1 21 | }, 22 | { 23 | config: 'night', 24 | text: 'Night', 25 | id: 2 26 | } 27 | ]; 28 | 29 | // Default font families 30 | var FAMILIES = [ 31 | { 32 | config: 'serif', 33 | text: 'Serif', 34 | id: 0 35 | }, 36 | { 37 | config: 'sans', 38 | text: 'Sans', 39 | id: 1 40 | } 41 | ]; 42 | 43 | // Return configured themes 44 | function getThemes() { 45 | return THEMES; 46 | } 47 | 48 | // Modify configured themes 49 | function setThemes(themes) { 50 | THEMES = themes; 51 | updateButtons(); 52 | } 53 | 54 | // Return configured font families 55 | function getFamilies() { 56 | return FAMILIES; 57 | } 58 | 59 | // Modify configured font families 60 | function setFamilies(families) { 61 | FAMILIES = families; 62 | updateButtons(); 63 | } 64 | 65 | // Save current font settings 66 | function saveFontSettings() { 67 | gitbook.storage.set('fontState', fontState); 68 | update(); 69 | } 70 | 71 | // Increase font size 72 | function enlargeFontSize(e) { 73 | e.preventDefault(); 74 | if (fontState.size >= MAX_SIZE) return; 75 | 76 | fontState.size++; 77 | saveFontSettings(); 78 | } 79 | 80 | // Decrease font size 81 | function reduceFontSize(e) { 82 | e.preventDefault(); 83 | if (fontState.size <= MIN_SIZE) return; 84 | 85 | fontState.size--; 86 | saveFontSettings(); 87 | } 88 | 89 | // Change font family 90 | function changeFontFamily(configName, e) { 91 | if (e && e instanceof Event) { 92 | e.preventDefault(); 93 | } 94 | 95 | var familyId = getFontFamilyId(configName); 96 | fontState.family = familyId; 97 | saveFontSettings(); 98 | } 99 | 100 | // Change type of color theme 101 | function changeColorTheme(configName, e) { 102 | if (e && e instanceof Event) { 103 | e.preventDefault(); 104 | } 105 | 106 | var $book = gitbook.state.$book; 107 | 108 | // Remove currently applied color theme 109 | if (fontState.theme !== 0) 110 | $book.removeClass('color-theme-'+fontState.theme); 111 | 112 | // Set new color theme 113 | var themeId = getThemeId(configName); 114 | fontState.theme = themeId; 115 | if (fontState.theme !== 0) 116 | $book.addClass('color-theme-'+fontState.theme); 117 | 118 | saveFontSettings(); 119 | } 120 | 121 | // Return the correct id for a font-family config key 122 | // Default to first font-family 123 | function getFontFamilyId(configName) { 124 | // Search for plugin configured font family 125 | var configFamily = $.grep(FAMILIES, function(family) { 126 | return family.config == configName; 127 | })[0]; 128 | // Fallback to default font family 129 | return (!!configFamily)? configFamily.id : 0; 130 | } 131 | 132 | // Return the correct id for a theme config key 133 | // Default to first theme 134 | function getThemeId(configName) { 135 | // Search for plugin configured theme 136 | var configTheme = $.grep(THEMES, function(theme) { 137 | return theme.config == configName; 138 | })[0]; 139 | // Fallback to default theme 140 | return (!!configTheme)? configTheme.id : 0; 141 | } 142 | 143 | function update() { 144 | var $book = gitbook.state.$book; 145 | 146 | $('.font-settings .font-family-list li').removeClass('active'); 147 | $('.font-settings .font-family-list li:nth-child('+(fontState.family+1)+')').addClass('active'); 148 | 149 | $book[0].className = $book[0].className.replace(/\bfont-\S+/g, ''); 150 | $book.addClass('font-size-'+fontState.size); 151 | $book.addClass('font-family-'+fontState.family); 152 | 153 | if(fontState.theme !== 0) { 154 | $book[0].className = $book[0].className.replace(/\bcolor-theme-\S+/g, ''); 155 | $book.addClass('color-theme-'+fontState.theme); 156 | } 157 | } 158 | 159 | function init(config) { 160 | // Search for plugin configured font family 161 | var configFamily = getFontFamilyId(config.family), 162 | configTheme = getThemeId(config.theme); 163 | 164 | // Instantiate font state object 165 | fontState = gitbook.storage.get('fontState', { 166 | size: config.size || 2, 167 | family: configFamily, 168 | theme: configTheme 169 | }); 170 | 171 | update(); 172 | } 173 | 174 | function updateButtons() { 175 | // Remove existing fontsettings buttons 176 | if (!!BUTTON_ID) { 177 | gitbook.toolbar.removeButton(BUTTON_ID); 178 | } 179 | 180 | // Create buttons in toolbar 181 | BUTTON_ID = gitbook.toolbar.createButton({ 182 | icon: 'fa fa-font', 183 | label: 'Font Settings', 184 | className: 'font-settings', 185 | dropdown: [ 186 | [ 187 | { 188 | text: 'A', 189 | className: 'font-reduce', 190 | onClick: reduceFontSize 191 | }, 192 | { 193 | text: 'A', 194 | className: 'font-enlarge', 195 | onClick: enlargeFontSize 196 | } 197 | ], 198 | $.map(FAMILIES, function(family) { 199 | family.onClick = function(e) { 200 | return changeFontFamily(family.config, e); 201 | }; 202 | 203 | return family; 204 | }), 205 | $.map(THEMES, function(theme) { 206 | theme.onClick = function(e) { 207 | return changeColorTheme(theme.config, e); 208 | }; 209 | 210 | return theme; 211 | }) 212 | ] 213 | }); 214 | } 215 | 216 | // Init configuration at start 217 | gitbook.events.bind('start', function(e, config) { 218 | var opts = config.fontsettings; 219 | 220 | // Generate buttons at start 221 | updateButtons(); 222 | 223 | // Init current settings 224 | init(opts); 225 | }); 226 | 227 | // Expose API 228 | gitbook.fontsettings = { 229 | enlargeFontSize: enlargeFontSize, 230 | reduceFontSize: reduceFontSize, 231 | setTheme: changeColorTheme, 232 | setFamily: changeFontFamily, 233 | getThemes: getThemes, 234 | setThemes: setThemes, 235 | getFamilies: getFamilies, 236 | setFamilies: setFamilies 237 | }; 238 | }); 239 | 240 | 241 | -------------------------------------------------------------------------------- /_book/gitbook/gitbook-plugin-fontsettings/website.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Theme 1 3 | */ 4 | .color-theme-1 .dropdown-menu { 5 | background-color: #111111; 6 | border-color: #7e888b; 7 | } 8 | .color-theme-1 .dropdown-menu .dropdown-caret .caret-inner { 9 | border-bottom: 9px solid #111111; 10 | } 11 | .color-theme-1 .dropdown-menu .buttons { 12 | border-color: #7e888b; 13 | } 14 | .color-theme-1 .dropdown-menu .button { 15 | color: #afa790; 16 | } 17 | .color-theme-1 .dropdown-menu .button:hover { 18 | color: #73553c; 19 | } 20 | /* 21 | * Theme 2 22 | */ 23 | .color-theme-2 .dropdown-menu { 24 | background-color: #2d3143; 25 | border-color: #272a3a; 26 | } 27 | .color-theme-2 .dropdown-menu .dropdown-caret .caret-inner { 28 | border-bottom: 9px solid #2d3143; 29 | } 30 | .color-theme-2 .dropdown-menu .buttons { 31 | border-color: #272a3a; 32 | } 33 | .color-theme-2 .dropdown-menu .button { 34 | color: #62677f; 35 | } 36 | .color-theme-2 .dropdown-menu .button:hover { 37 | color: #f4f4f5; 38 | } 39 | .book .book-header .font-settings .font-enlarge { 40 | line-height: 30px; 41 | font-size: 1.4em; 42 | } 43 | .book .book-header .font-settings .font-reduce { 44 | line-height: 30px; 45 | font-size: 1em; 46 | } 47 | .book.color-theme-1 .book-body { 48 | color: #704214; 49 | background: #f3eacb; 50 | } 51 | .book.color-theme-1 .book-body .page-wrapper .page-inner section { 52 | background: #f3eacb; 53 | } 54 | .book.color-theme-2 .book-body { 55 | color: #bdcadb; 56 | background: #1c1f2b; 57 | } 58 | .book.color-theme-2 .book-body .page-wrapper .page-inner section { 59 | background: #1c1f2b; 60 | } 61 | .book.font-size-0 .book-body .page-inner section { 62 | font-size: 1.2rem; 63 | } 64 | .book.font-size-1 .book-body .page-inner section { 65 | font-size: 1.4rem; 66 | } 67 | .book.font-size-2 .book-body .page-inner section { 68 | font-size: 1.6rem; 69 | } 70 | .book.font-size-3 .book-body .page-inner section { 71 | font-size: 2.2rem; 72 | } 73 | .book.font-size-4 .book-body .page-inner section { 74 | font-size: 4rem; 75 | } 76 | .book.font-family-0 { 77 | font-family: Georgia, serif; 78 | } 79 | .book.font-family-1 { 80 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 81 | } 82 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal { 83 | color: #704214; 84 | } 85 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal a { 86 | color: inherit; 87 | } 88 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, 89 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2, 90 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h3, 91 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h4, 92 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h5, 93 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { 94 | color: inherit; 95 | } 96 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h1, 97 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h2 { 98 | border-color: inherit; 99 | } 100 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal h6 { 101 | color: inherit; 102 | } 103 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal hr { 104 | background-color: inherit; 105 | } 106 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal blockquote { 107 | border-color: inherit; 108 | } 109 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre, 110 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code { 111 | background: #fdf6e3; 112 | color: #657b83; 113 | border-color: #f8df9c; 114 | } 115 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal .highlight { 116 | background-color: inherit; 117 | } 118 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table th, 119 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table td { 120 | border-color: #f5d06c; 121 | } 122 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr { 123 | color: inherit; 124 | background-color: #fdf6e3; 125 | border-color: #444444; 126 | } 127 | .book.color-theme-1 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { 128 | background-color: #fbeecb; 129 | } 130 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal { 131 | color: #bdcadb; 132 | } 133 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal a { 134 | color: #3eb1d0; 135 | } 136 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, 137 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2, 138 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h3, 139 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h4, 140 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h5, 141 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { 142 | color: #fffffa; 143 | } 144 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h1, 145 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h2 { 146 | border-color: #373b4e; 147 | } 148 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal h6 { 149 | color: #373b4e; 150 | } 151 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal hr { 152 | background-color: #373b4e; 153 | } 154 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal blockquote { 155 | border-color: #373b4e; 156 | } 157 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre, 158 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code { 159 | color: #9dbed8; 160 | background: #2d3143; 161 | border-color: #2d3143; 162 | } 163 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal .highlight { 164 | background-color: #282a39; 165 | } 166 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table th, 167 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table td { 168 | border-color: #3b3f54; 169 | } 170 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr { 171 | color: #b6c2d2; 172 | background-color: #2d3143; 173 | border-color: #3b3f54; 174 | } 175 | .book.color-theme-2 .book-body .page-wrapper .page-inner section.normal table tr:nth-child(2n) { 176 | background-color: #35394b; 177 | } 178 | .book.color-theme-1 .book-header { 179 | color: #afa790; 180 | background: transparent; 181 | } 182 | .book.color-theme-1 .book-header .btn { 183 | color: #afa790; 184 | } 185 | .book.color-theme-1 .book-header .btn:hover { 186 | color: #73553c; 187 | background: none; 188 | } 189 | .book.color-theme-1 .book-header h1 { 190 | color: #704214; 191 | } 192 | .book.color-theme-2 .book-header { 193 | color: #7e888b; 194 | background: transparent; 195 | } 196 | .book.color-theme-2 .book-header .btn { 197 | color: #3b3f54; 198 | } 199 | .book.color-theme-2 .book-header .btn:hover { 200 | color: #fffff5; 201 | background: none; 202 | } 203 | .book.color-theme-2 .book-header h1 { 204 | color: #bdcadb; 205 | } 206 | .book.color-theme-1 .book-body .navigation { 207 | color: #afa790; 208 | } 209 | .book.color-theme-1 .book-body .navigation:hover { 210 | color: #73553c; 211 | } 212 | .book.color-theme-2 .book-body .navigation { 213 | color: #383f52; 214 | } 215 | .book.color-theme-2 .book-body .navigation:hover { 216 | color: #fffff5; 217 | } 218 | /* 219 | * Theme 1 220 | */ 221 | .book.color-theme-1 .book-summary { 222 | color: #afa790; 223 | background: #111111; 224 | border-right: 1px solid rgba(0, 0, 0, 0.07); 225 | } 226 | .book.color-theme-1 .book-summary .book-search { 227 | background: transparent; 228 | } 229 | .book.color-theme-1 .book-summary .book-search input, 230 | .book.color-theme-1 .book-summary .book-search input:focus { 231 | border: 1px solid transparent; 232 | } 233 | .book.color-theme-1 .book-summary ul.summary li.divider { 234 | background: #7e888b; 235 | box-shadow: none; 236 | } 237 | .book.color-theme-1 .book-summary ul.summary li i.fa-check { 238 | color: #33cc33; 239 | } 240 | .book.color-theme-1 .book-summary ul.summary li.done > a { 241 | color: #877f6a; 242 | } 243 | .book.color-theme-1 .book-summary ul.summary li a, 244 | .book.color-theme-1 .book-summary ul.summary li span { 245 | color: #877f6a; 246 | background: transparent; 247 | font-weight: normal; 248 | } 249 | .book.color-theme-1 .book-summary ul.summary li.active > a, 250 | .book.color-theme-1 .book-summary ul.summary li a:hover { 251 | color: #704214; 252 | background: transparent; 253 | font-weight: normal; 254 | } 255 | /* 256 | * Theme 2 257 | */ 258 | .book.color-theme-2 .book-summary { 259 | color: #bcc1d2; 260 | background: #2d3143; 261 | border-right: none; 262 | } 263 | .book.color-theme-2 .book-summary .book-search { 264 | background: transparent; 265 | } 266 | .book.color-theme-2 .book-summary .book-search input, 267 | .book.color-theme-2 .book-summary .book-search input:focus { 268 | border: 1px solid transparent; 269 | } 270 | .book.color-theme-2 .book-summary ul.summary li.divider { 271 | background: #272a3a; 272 | box-shadow: none; 273 | } 274 | .book.color-theme-2 .book-summary ul.summary li i.fa-check { 275 | color: #33cc33; 276 | } 277 | .book.color-theme-2 .book-summary ul.summary li.done > a { 278 | color: #62687f; 279 | } 280 | .book.color-theme-2 .book-summary ul.summary li a, 281 | .book.color-theme-2 .book-summary ul.summary li span { 282 | color: #c1c6d7; 283 | background: transparent; 284 | font-weight: 600; 285 | } 286 | .book.color-theme-2 .book-summary ul.summary li.active > a, 287 | .book.color-theme-2 .book-summary ul.summary li a:hover { 288 | color: #f4f4f5; 289 | background: #252737; 290 | font-weight: 600; 291 | } 292 | -------------------------------------------------------------------------------- /_book/GLOSSARY.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | · GitBook 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |

        66 |
        67 | 68 | 69 | 72 | 73 | 74 | 341 | 342 | 343 |
        344 | 345 |
        346 | 347 |
        348 | 349 | 350 | 351 | 360 | 361 | 362 | 363 | 364 |
        365 |
        366 | 367 |
        368 |
        369 | 370 |
        371 | 372 |

        devs

        Short form for developers.

        coders

        Alias for devs/developers.

        dependency

        Any software (tool or third party code) that our project needs in order to function.

        a hack

        Using a technology in a way that is was not intended, but nonetheless works.

        IDE

        Integrated Development Environment; everything you need to develop software in one interface, split into multiple sections usually.

        library

        A package of code that performs a specific function and can be used by other code.

        third party

        Someone or some team other than ourselves or our team that wrote some code that we're using on our project. Can be open source or proprietary.

        373 | 374 |
        375 | 376 |
        377 |
        378 |
        379 | 380 |

        results matching ""

        381 |
          382 | 383 |
          384 |
          385 | 386 |

          No results matching ""

          387 | 388 |
          389 |
          390 |
          391 | 392 |
          393 |
          394 | 395 |
          396 | 397 | 398 | 399 | 400 | 401 | 402 |
          403 | 404 | 410 |
          411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | -------------------------------------------------------------------------------- /_book/content/part1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Part I - HTML & CSS · GitBook 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
          70 |
          71 | 72 | 73 | 76 | 77 | 78 | 345 | 346 | 347 |
          348 | 349 |
          350 | 351 |
          352 | 353 | 354 | 355 | 364 | 365 | 366 | 367 | 368 |
          369 |
          370 | 371 |
          372 |
          373 | 374 |
          375 | 376 |

          Part I

          HTML and CSS

          377 | 378 |
          379 | 380 |
          381 |
          382 |
          383 | 384 |

          results matching ""

          385 |
            386 | 387 |
            388 |
            389 | 390 |

            No results matching ""

            391 | 392 |
            393 |
            394 |
            395 | 396 |
            397 |
            398 | 399 |
            400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 |
            415 | 416 | 422 |
            423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | -------------------------------------------------------------------------------- /_book/content/final/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Final Thoughts · GitBook 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
            68 |
            69 | 70 | 71 | 74 | 75 | 76 | 343 | 344 | 345 |
            346 | 347 |
            348 | 349 |
            350 | 351 | 352 | 353 | 362 | 363 | 364 | 365 | 366 |
            367 |
            368 | 369 |
            370 |
            371 | 372 |
            373 | 374 |

            Final Thoughts

            This demonstration was a bold attempt at showing you how easy it is to get started with Web development, and that seemingly complex apps can be prototyped relatively quickly with modern software technology and approach.

            Thank you for spending your Saturday with us; I hope you enjoyed it and that you have wonderful weekend!

            375 | 376 |
            377 | 378 |
            379 |
            380 |
            381 | 382 |

            results matching ""

            383 |
              384 | 385 |
              386 |
              387 | 388 |

              No results matching ""

              389 | 390 |
              391 |
              392 |
              393 | 394 |
              395 |
              396 | 397 |
              398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 |
              409 | 410 | 416 |
              417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | -------------------------------------------------------------------------------- /_book/content/setup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Setup · GitBook 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
              70 |
              71 | 72 | 73 | 76 | 77 | 78 | 345 | 346 | 347 |
              348 | 349 |
              350 | 351 |
              352 | 353 | 354 | 355 | 364 | 365 | 366 | 367 | 368 |
              369 |
              370 | 371 |
              372 |
              373 | 374 |
              375 | 376 |

              Setup

              This section contains instructions to sign up for the accounts you need to create in order to build your app.

              All you need is a laptop, a browser and a Wi-Fi connection.

              377 | 378 |
              379 | 380 |
              381 |
              382 |
              383 | 384 |

              results matching ""

              385 |
                386 | 387 |
                388 |
                389 | 390 |

                No results matching ""

                391 | 392 |
                393 |
                394 |
                395 | 396 |
                397 |
                398 | 399 |
                400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 |
                415 | 416 | 422 |
                423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | -------------------------------------------------------------------------------- /_book/content/part2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Part II - JavaScript · GitBook 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
                70 |
                71 | 72 | 73 | 76 | 77 | 78 | 345 | 346 | 347 |
                348 | 349 |
                350 | 351 |
                352 | 353 | 354 | 355 | 364 | 365 | 366 | 367 | 368 |
                369 |
                370 | 371 |
                372 |
                373 | 374 |
                375 | 376 |

                Part II

                JavaScript: jQuery, Node, Express, and Web Sockets

                377 | 378 |
                379 | 380 |
                381 |
                382 |
                383 | 384 |

                results matching ""

                385 |
                  386 | 387 |
                  388 |
                  389 | 390 |

                  No results matching ""

                  391 | 392 |
                  393 |
                  394 |
                  395 | 396 |
                  397 |
                  398 | 399 |
                  400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 |
                  415 | 416 | 422 |
                  423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | -------------------------------------------------------------------------------- /_book/content/setup/chrome.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chrome · GitBook 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
                  70 |
                  71 | 72 | 73 | 76 | 77 | 78 | 345 | 346 | 347 |
                  348 | 349 |
                  350 | 351 |
                  352 | 353 | 354 | 355 | 364 | 365 | 366 | 367 | 368 |
                  369 |
                  370 | 371 |
                  372 |
                  373 | 374 |
                  375 | 376 |

                  Google Chrome

                  You'll need a modern web browser to use Cloud9. Google Chrome is a good choice for Web development. You can download it from Google.

                  377 | 378 |
                  379 | 380 |
                  381 |
                  382 |
                  383 | 384 |

                  results matching ""

                  385 |
                    386 | 387 |
                    388 |
                    389 | 390 |

                    No results matching ""

                    391 | 392 |
                    393 |
                    394 |
                    395 | 396 |
                    397 |
                    398 | 399 |
                    400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 |
                    415 | 416 | 422 |
                    423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | -------------------------------------------------------------------------------- /_book/gitbook/gitbook-plugin-lunr/lunr.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.12 3 | * Copyright (C) 2015 Oliver Nightingale 4 | * MIT Licensed 5 | * @license 6 | */ 7 | !function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.5.12",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(t){return arguments.length&&null!=t&&void 0!=t?Array.isArray(t)?t.map(function(t){return t.toLowerCase()}):t.toString().trim().toLowerCase().split(/[\s\-]+/):[]},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,o=0;n>o;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return o;t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o]}return r===t?o:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];i>1;)t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return r>t?o:t>r?o+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,l=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),l=1,u=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);l=1/Math.log(c)}return r>-1&&i.insert(r,a*s*l),Object.keys(h.tokenStore.get(o)).forEach(function(t){u.add(t)}),n.union(u)},new t.SortedSet);o.push(l)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,l="^("+o+")?"+i,u=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,y=/^(.+?)(ed|ing)$/,g=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+o+i+"[^aeiouwxy]$"),T=function(n){var i,o,r,s,a,h,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=y,s.test(n)){var T=s.exec(n);s=u,s.test(T[1])&&(s=g,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,l=x,a.test(n)?n+="e":h.test(n)?(s=g,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+e[o])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=g,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return e&&t.stopWordFilter.stopWords[e]!==e?e:void 0},t.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){var e=t.replace(/^\W+/,"").replace(/\W+$/,"");return""===e?void 0:e},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;no;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return o;t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o]}return r===t?o:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];i>1;)t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return r>t?o:t>r?o+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,l=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),l=1,u=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);l=1/Math.log(c)}return r>-1&&i.insert(r,a*s*l),Object.keys(h.tokenStore.get(o)).forEach(function(t){u.add(t)}),n.union(u)},new t.SortedSet);o.push(l)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,l="^("+o+")?"+i,u=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,y=/^(.+?)(ed|ing)$/,g=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+o+i+"[^aeiouwxy]$"),T=function(n){var i,o,r,s,a,h,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=y,s.test(n)){var T=s.exec(n);s=u,s.test(T[1])&&(s=g,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,l=x,a.test(n)?n+="e":h.test(n)?(s=g,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+e[o])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=g,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return e&&t.stopWordFilter.stopWords[e]!==e?e:void 0},t.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){var e=t.replace(/^\W+/,"").replace(/\W+$/,"");return""===e?void 0:e},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n 3 | 4 | 5 | Github · GitBook 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
                    70 |
                    71 | 72 | 73 | 76 | 77 | 78 | 345 | 346 | 347 |
                    348 | 349 |
                    350 | 351 |
                    352 | 353 | 354 | 355 | 364 | 365 | 366 | 367 | 368 |
                    369 |
                    370 | 371 |
                    372 |
                    373 | 374 |
                    375 | 376 |

                    GitHub

                    GitHub is where a huge amount of open source code resides. Almost every software developer (whether they are Web, mobile, desktop or other) has a GitHub account these days. It also has some great developer workflow features.

                    You will need to sign up for a GitHub account. If you already have one, please sign in.

                    Git

                    GitHub is centered around an open source Version Control System (VCS) called Git.

                    It's like Dropbox for coders. We need to make sure our project codebase is synced to a central server not only for backup purposes but also to share with other devs working on the same project.

                    It gives us a lot more control than Dropbox though, and is not nearly as easy to use. That said, it's probably the most popular VCS today and continues to grow at a rapid pace, thanks to services like GitHub especially.

                    If you were developing today's app on your own machine, you'd be installing Git. We've saved you that trouble, so no action required here.

                    377 | 378 |
                    379 | 380 |
                    381 |
                    382 |
                    383 | 384 |

                    results matching ""

                    385 |
                      386 | 387 |
                      388 |
                      389 | 390 |

                      No results matching ""

                      391 | 392 |
                      393 |
                      394 |
                      395 | 396 |
                      397 |
                      398 | 399 |
                      400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 |
                      415 | 416 | 422 |
                      423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | -------------------------------------------------------------------------------- /_book/content/part1/dev-tools.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Dev Tools · GitBook 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
                      70 |
                      71 | 72 | 73 | 76 | 77 | 78 | 345 | 346 | 347 |
                      348 | 349 |
                      350 | 351 |
                      352 | 353 | 354 | 355 | 364 | 365 | 366 | 367 | 368 |
                      369 |
                      370 | 371 |
                      372 |
                      373 | 374 |
                      375 | 376 |

                      Dev Tools

                      With your ugly white page open, right click somewhere on the page (anywhere, really) and you'll notice an inspect element option.

                      screenshot

                      Clicking that unlocks a most powerful yet kind-of secret feature that all major browsers have: Dev Tools (aka a Web Inspector).

                      screenshot

                      Hover over the HTML source code shown and notice that you can not only use it to inspect the page, but you can also edit it right there (double click the code) to see how it affects the page.

                      Our browser gives us a live editor! Why? It's specifically there for developers to inspect any page on the internet, to see how its HTML (and other things) are written.

                      By the way, any changes you make through this editor are just experiments and won't actually "stick". If you refresh the page the changes go away. They don't save into your source code directly.

                      Play around with it a bit more to get the hang of the "Elements" tab in the Dev Tools.

                      Then select (click) the <body> tag and on the right side you'll see something like this.

                      screenshot

                      And what if I double click inside those weird sideways mustaches and type in the following.

                      screenshot

                      That, my friend, was CSS.

                      377 | 378 |
                      379 | 380 |
                      381 |
                      382 |
                      383 | 384 |

                      results matching ""

                      385 |
                        386 | 387 |
                        388 |
                        389 | 390 |

                        No results matching ""

                        391 | 392 |
                        393 |
                        394 |
                        395 | 396 |
                        397 |
                        398 | 399 |
                        400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 |
                        415 | 416 | 422 |
                        423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | --------------------------------------------------------------------------------