32 |
33 |
34 |
35 |
43 |
44 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/fend-feed-reader/jasmine/lib/jasmine-2.1.2/boot.js:
--------------------------------------------------------------------------------
1 | /**
2 | Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
3 |
4 | If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
5 |
6 | The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
7 |
8 | [jasmine-gem]: http://github.com/pivotal/jasmine-gem
9 | */
10 |
11 | (function() {
12 |
13 | /**
14 | * ## Require & Instantiate
15 | *
16 | * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
17 | */
18 | window.jasmine = jasmineRequire.core(jasmineRequire);
19 |
20 | /**
21 | * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
22 | */
23 | jasmineRequire.html(jasmine);
24 |
25 | /**
26 | * Create the Jasmine environment. This is used to run all specs in a project.
27 | */
28 | var env = jasmine.getEnv();
29 |
30 | /**
31 | * ## The Global Interface
32 | *
33 | * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
34 | */
35 | var jasmineInterface = jasmineRequire.interface(jasmine, env);
36 |
37 | /**
38 | * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
39 | */
40 | if (typeof window == "undefined" && typeof exports == "object") {
41 | extend(exports, jasmineInterface);
42 | } else {
43 | extend(window, jasmineInterface);
44 | }
45 |
46 | /**
47 | * ## Runner Parameters
48 | *
49 | * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
50 | */
51 |
52 | var queryString = new jasmine.QueryString({
53 | getWindowLocation: function() { return window.location; }
54 | });
55 |
56 | var catchingExceptions = queryString.getParam("catch");
57 | env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
58 |
59 | /**
60 | * ## Reporters
61 | * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
62 | */
63 | var htmlReporter = new jasmine.HtmlReporter({
64 | env: env,
65 | onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
66 | getContainer: function() { return document.body; },
67 | createElement: function() { return document.createElement.apply(document, arguments); },
68 | createTextNode: function() { return document.createTextNode.apply(document, arguments); },
69 | timer: new jasmine.Timer()
70 | });
71 |
72 | /**
73 | * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
74 | */
75 | env.addReporter(jasmineInterface.jsApiReporter);
76 | env.addReporter(htmlReporter);
77 |
78 | /**
79 | * Filter which specs will be run by matching the start of the full name against the `spec` query param.
80 | */
81 | var specFilter = new jasmine.HtmlSpecFilter({
82 | filterString: function() { return queryString.getParam("spec"); }
83 | });
84 |
85 | env.specFilter = function(spec) {
86 | return specFilter.matches(spec.getFullName());
87 | };
88 |
89 | /**
90 | * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
91 | */
92 | window.setTimeout = window.setTimeout;
93 | window.setInterval = window.setInterval;
94 | window.clearTimeout = window.clearTimeout;
95 | window.clearInterval = window.clearInterval;
96 |
97 | /**
98 | * ## Execution
99 | *
100 | * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
101 | */
102 | var currentWindowOnload = window.onload;
103 |
104 | window.onload = function() {
105 | if (currentWindowOnload) {
106 | currentWindowOnload();
107 | }
108 | htmlReporter.initialize();
109 | env.execute();
110 | };
111 |
112 | /**
113 | * Helper function for readability above.
114 | */
115 | function extend(destination, source) {
116 | for (var property in source) destination[property] = source[property];
117 | return destination;
118 | }
119 |
120 | }());
121 |
--------------------------------------------------------------------------------
/fend-feed-reader/jasmine/lib/jasmine-2.1.2/jasmine_favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-feed-reader/jasmine/lib/jasmine-2.1.2/jasmine_favicon.png
--------------------------------------------------------------------------------
/fend-feed-reader/jasmine/spec/feedreader.js:
--------------------------------------------------------------------------------
1 | /* feedreader.js
2 | *
3 | * This is the spec file that Jasmine will read and contains
4 | * all of the tests that will be run against your application.
5 | */
6 |
7 | /* We're placing all of our tests within the $() function,
8 | * since some of these tests may require DOM elements. We want
9 | * to ensure they don't run until the DOM is ready.
10 | */
11 | $(function() {
12 | /* This is our first test suite - a test suite just contains
13 | * a related set of tests. This suite is all about the RSS
14 | * feeds definitions, the allFeeds variable in our application.
15 | */
16 | describe('RSS Feeds', function() {
17 | /* This is our first test - it tests to make sure that the
18 | * allFeeds variable has been defined and that it is not
19 | * empty. Experiment with this before you get started on
20 | * the rest of this project. What happens when you change
21 | * allFeeds in app.js to be an empty array and refresh the
22 | * page?
23 | */
24 | it('are defined', function() {
25 | expect(allFeeds).toBeDefined();
26 | expect(allFeeds.length).not.toBe(0);
27 | });
28 |
29 |
30 | /* Loops through each feed in the allFeeds object and ensures
31 | * it has a URL defined and that the URL is not empty.
32 | */
33 | it('have urls', function() {
34 | allFeeds.forEach(function(feed) {
35 | // Does the feed have a url property?
36 | expect(feed.url).toBeDefined();
37 | // Is it a string?
38 | expect(feed.url).toEqual(jasmine.any(String));
39 | // Is it not empty? (Empty strings are not truthy.)
40 | expect(feed.url).toBeTruthy();
41 | });
42 | });
43 |
44 |
45 | /* Loops through each feed in the allFeeds object and ensures
46 | * it has a name defined and that the name is not empty.
47 | */
48 | it('have names', function() {
49 | allFeeds.forEach(function(feed) {
50 | // Does the feed have a name property?
51 | expect(feed.name).toBeDefined();
52 | // Is it a string?
53 | expect(feed.name).toEqual(jasmine.any(String));
54 | // Is it not empty? (Empty strings are not truthy.)
55 | expect(feed.name).toBeTruthy();
56 | });
57 | });
58 | });
59 |
60 |
61 | describe('The menu', function() {
62 |
63 | /* Ensures the menu element is hidden by default.
64 | */
65 | it('is hidden by default', function() {
66 | // Does the body have the menu-hidden class? (This is the class that toggles the menu.)
67 | expect($('body').hasClass('menu-hidden')).toBe(true);
68 | });
69 |
70 | /* Ensures the menu changes visibility when the menu icon is
71 | * clicked.
72 | */
73 | it('changes visibility when the menu icon is clicked', function() {
74 | // The menu-hidden class on the body determines the menu's visibility.
75 | var initialState = $('body').hasClass('menu-hidden');
76 |
77 | // The element with the menu-icon-link class toggles the menu's visibility when clicked.
78 | $('.menu-icon-link').click();
79 |
80 | // Has the menu's visibility changed?
81 | expect($('body').hasClass('menu-hidden')).not.toBe(initialState);
82 |
83 | $('.menu-icon-link').click();
84 |
85 | // Has the menu's visibility changed back to the initial state?
86 | expect($('body').hasClass('menu-hidden')).toBe(initialState);
87 | });
88 |
89 | });
90 |
91 | describe('Initial Entries', function() {
92 |
93 | // Before each test, load the first feed and wait for it to finish.
94 | beforeEach(function(done) {
95 | loadFeed(0, done);
96 | });
97 |
98 | /* Ensures when the loadFeed function is called and completes
99 | * its work, there is at least a single .entry element within
100 | * the .feed container.
101 | */
102 | it('contains at least one entry', function() {
103 | // Is there at least one element with the entry class in the element with the feed class?
104 | expect($('.feed .entry').length).toBeGreaterThan(0);
105 | });
106 |
107 | });
108 |
109 | describe('New Feed Selection', function() {
110 |
111 | // Before each test, load the first feed and wait for it to finish.
112 | beforeEach(function(done) {
113 | loadFeed(0, done);
114 | });
115 |
116 | /* Ensures when a new feed is loaded by the loadFeed function
117 | * that the content actually changes.
118 | */
119 | it('changes the content', function(done) {
120 | var initialContent = $('.feed').html();
121 |
122 | // Load the second feed...
123 | loadFeed(1, function() {
124 | // Has the content changed?
125 | expect($('.feed').html()).not.toEqual(initialContent);
126 | done();
127 | });
128 | });
129 |
130 | });
131 | }());
132 |
--------------------------------------------------------------------------------
/fend-feed-reader/js/app.js:
--------------------------------------------------------------------------------
1 | /* app.js
2 | *
3 | * This is our RSS feed reader application. It uses the Google
4 | * Feed Reader API to grab RSS feeds as JSON object we can make
5 | * use of. It also uses the Handlebars templating library and
6 | * jQuery.
7 | */
8 |
9 | // The names and URLs to all of the feeds we'd like available.
10 | var allFeeds = [
11 | {
12 | name: 'Udacity Blog',
13 | url: 'http://blog.udacity.com/feed'
14 | }, {
15 | name: 'CSS Tricks',
16 | url: 'http://css-tricks.com/feed'
17 | }, {
18 | name: 'HTML5 Rocks',
19 | url: 'http://feeds.feedburner.com/html5rocks'
20 | }, {
21 | name: 'Linear Digressions',
22 | url: 'http://feeds.feedburner.com/udacity-linear-digressions'
23 | }
24 | ];
25 |
26 | /* This function starts up our application. The Google Feed
27 | * Reader API is loaded asynchonously and will then call this
28 | * function when the API is loaded.
29 | */
30 | function init() {
31 | // Load the first feed we've defined (index of 0).
32 | loadFeed(0);
33 | }
34 |
35 | /* This function performs everything necessary to load a
36 | * feed using the Google Feed Reader API. It will then
37 | * perform all of the DOM operations required to display
38 | * feed entries on the page. Feeds are referenced by their
39 | * index position within the allFeeds array.
40 | * This function all supports a callback as the second parameter
41 | * which will be called after everything has run successfully.
42 | */
43 | function loadFeed(id, cb) {
44 | var feedUrl = allFeeds[id].url,
45 | feedName = allFeeds[id].name;
46 |
47 | $.ajax({
48 | type: "POST",
49 | url: 'https://rsstojson.udacity.com/parseFeed',
50 | data: JSON.stringify({url: feedUrl}),
51 | contentType:"application/json",
52 | success: function (result, status){
53 |
54 | var container = $('.feed'),
55 | title = $('.header-title'),
56 | entries = result.feed.entries,
57 | entriesLen = entries.length,
58 | entryTemplate = Handlebars.compile($('.tpl-entry').html());
59 |
60 | title.html(feedName); // Set the header text
61 | container.empty(); // Empty out all previous entries
62 |
63 | /* Loop through the entries we just loaded via the Google
64 | * Feed Reader API. We'll then parse that entry against the
65 | * entryTemplate (created above using Handlebars) and append
66 | * the resulting HTML to the list of entries on the page.
67 | */
68 | entries.forEach(function(entry) {
69 | container.append(entryTemplate(entry));
70 | });
71 |
72 | if (cb) {
73 | cb();
74 | }
75 | },
76 | error: function (result, status, err){
77 | //run only the callback without attempting to parse result due to error
78 | if (cb) {
79 | cb();
80 | }
81 | },
82 | dataType: "json"
83 | });
84 | }
85 |
86 | /* Google API: Loads the Feed Reader API and defines what function
87 | * to call when the Feed Reader API is done loading.
88 | */
89 | google.load('feeds', '1');
90 | google.setOnLoadCallback(init);
91 |
92 | /* All of this functionality is heavily reliant upon the DOM, so we
93 | * place our code in the $() function to ensure it doesn't execute
94 | * until the DOM is ready.
95 | */
96 | $(function() {
97 | var container = $('.feed'),
98 | feedList = $('.feed-list'),
99 | feedItemTemplate = Handlebars.compile($('.tpl-feed-list-item').html()),
100 | feedId = 0,
101 | menuIcon = $('.menu-icon-link');
102 |
103 | /* Loop through all of our feeds, assigning an id property to
104 | * each of the feeds based upon its index within the array.
105 | * Then parse that feed against the feedItemTemplate (created
106 | * above using Handlebars) and append it to the list of all
107 | * available feeds within the menu.
108 | */
109 | allFeeds.forEach(function(feed) {
110 | feed.id = feedId;
111 | feedList.append(feedItemTemplate(feed));
112 |
113 | feedId++;
114 | });
115 |
116 | /* When a link in our feedList is clicked on, we want to hide
117 | * the menu, load the feed, and prevent the default action
118 | * (following the link) from occurring.
119 | */
120 | feedList.on('click', 'a', function() {
121 | var item = $(this);
122 |
123 | $('body').addClass('menu-hidden');
124 | loadFeed(item.data('id'));
125 | return false;
126 | });
127 |
128 | /* When the menu icon is clicked on, we need to toggle a class
129 | * on the body to perform the hiding/showing of our menu.
130 | */
131 | menuIcon.on('click', function() {
132 | $('body').toggleClass('menu-hidden');
133 | });
134 | }());
135 |
--------------------------------------------------------------------------------
/fend-frogger/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .publish
4 |
--------------------------------------------------------------------------------
/fend-frogger/README.md:
--------------------------------------------------------------------------------
1 | # Escape By Water! (A Frogger Clone)
2 |
3 | This is the **3rd** project in Udacity's [Front-End Web Developer Nanodegree](https://www.udacity.com/course/front-end-web-developer-nanodegree--nd001) program. It provides art assets and a simple game engine that must be used to build a frogger clone. I am required to implement only the basic game, but am encouraged to implement additional features of my choosing.
4 |
5 | **[Play here.](https://tempurturtul.github.io/udacity-fend-projects/projects/fend-frogger/)**
6 |
7 | ## Controls
8 |
9 | - Use the **arrow keys**, the **WASD keys**, or **touches** to move.
10 |
11 | ## Quickstart For Local Development
12 |
13 | - Install [Node](https://nodejs.org/en/) and [Gulp](http://gulpjs.com/).
14 | - Clone the repository, navigate to this project, and install dependencies.
15 | ```
16 | git clone https://github.com/Tempurturtul/udacity-fend-projects.git
17 | cd udacity-fend-projects/fend-frogger/
18 | npm install
19 | ```
20 | - Run the default gulp task to lint and serve source files. *(See `gulpfile.js` for additional tasks.)*
21 | ```
22 | gulp
23 | ```
24 |
--------------------------------------------------------------------------------
/fend-frogger/gulpfile.js:
--------------------------------------------------------------------------------
1 | /* Tasks:
2 | * lint:js (Lint JavaScript.)
3 | * lint:json (Lint JSON.)
4 | * lint (Run all lint tasks and watch for files to re-lint.)
5 | * clean (Delete dist files.)
6 | * build (Build dist files.)
7 | * serve (Serve src files and watch for files to reload.)
8 | * serve:dist (Serve dist files and watch for files to reload.)
9 | * deploy:gh-pages (Deploy dist files to gh-pages.)
10 | * default (Lint and serve.)
11 | */
12 |
13 | var DEST = 'dist';
14 | var JS_OUT = 'app.min.js';
15 | var CSS_OUT = 'style.min.css';
16 |
17 | /* File globs. */
18 | var jsFiles = [
19 | 'gulpfile.js',
20 | 'src/**/*.js'
21 | ];
22 | var jsonFiles = [
23 | 'package.json',
24 | // 'bower.json',
25 | 'src/**/*.json'
26 | ];
27 | var clientJSFiles = [
28 | 'src/client/**/*.js'
29 | ];
30 | var clientCSSFiles = [
31 | 'src/client/**/*.css'
32 | ];
33 | var clientImageFiles = [
34 | 'src/client/**/images/**/*'
35 | ];
36 | var clientHTMLFiles = [
37 | 'src/client/**/*.html'
38 | ];
39 | var clientSoundFiles = [
40 | 'src/client/**/sounds/**/*'
41 | ];
42 | // var bowerFiles = [
43 | // 'bower_components/**/*'
44 | // ];
45 |
46 | /* Gulp and plugins. */
47 | var gulp = require('gulp');
48 | var browserSync = require('browser-sync').create();
49 | var cssnano = require('gulp-cssnano');
50 | var del = require('del');
51 | var ghPages = require('gulp-gh-pages');
52 | var gulpif = require('gulp-if');
53 | var htmlmin = require('gulp-htmlmin');
54 | var imagemin = require('gulp-imagemin');
55 | var jshint = require('gulp-jshint');
56 | var jsonlint = require('gulp-jsonlint');
57 | var merge = require('merge-stream');
58 | var uglify = require('gulp-uglify');
59 | var useref = require('gulp-useref');
60 |
61 | gulp.task('lint:js', function() {
62 | return gulp.src(jsFiles)
63 | .pipe(jshint())
64 | .pipe(jshint.reporter('default'));
65 | });
66 |
67 | gulp.task('lint:json', function() {
68 | return gulp.src(jsonFiles)
69 | .pipe(jsonlint())
70 | .pipe(jsonlint.reporter());
71 | });
72 |
73 | gulp.task('lint', ['lint:js', 'lint:json'], function() {
74 | gulp.watch(jsFiles, ['lint:js']);
75 | gulp.watch(jsonFiles, ['lint:json']);
76 | });
77 |
78 | gulp.task('clean', function() {
79 | return del([DEST]);
80 | });
81 |
82 | gulp.task('build', ['clean'], function() {
83 | return merge(
84 | // gulp.src(bowerFiles)
85 | // .pipe(gulp.dest(DEST + '/bower_components')),
86 | gulp.src(clientImageFiles)
87 | .pipe(imagemin({
88 | progressive: true, // jpg
89 | interlaced: true // gif
90 | }))
91 | .pipe(gulp.dest(DEST)),
92 | gulp.src(clientHTMLFiles)
93 | .pipe(useref())
94 | .pipe(gulpif('*.js', uglify()))
95 | .pipe(gulpif('*.css', cssnano()))
96 | .pipe(gulpif('*.html', htmlmin({
97 | collapseWhitespace: true
98 | })))
99 | .pipe(gulp.dest(DEST)),
100 | gulp.src(clientSoundFiles)
101 | .pipe(gulp.dest(DEST)));
102 | });
103 |
104 | gulp.task('serve', function() {
105 | browserSync.init({
106 | server: {
107 | baseDir: 'src/client'
108 | // routes: {
109 | // '/bower_components': './bower_components'
110 | // }
111 | },
112 | https: false,
113 | notify: false,
114 | minify: false
115 | });
116 |
117 | gulp.watch(clientJSFiles, browserSync.reload);
118 | gulp.watch(clientCSSFiles, browserSync.reload);
119 | gulp.watch(clientHTMLFiles, browserSync.reload);
120 | gulp.watch(clientImageFiles, browserSync.reload);
121 | gulp.watch(clientSoundFiles, browserSync.reload);
122 | });
123 |
124 | gulp.task('serve:dist', function() {
125 | browserSync.init({
126 | server: {
127 | baseDir: DEST
128 | },
129 | https: false,
130 | notify: false,
131 | minify: false
132 | });
133 |
134 | gulp.watch([DEST + '/**/*'], browserSync.reload);
135 | });
136 |
137 | gulp.task('deploy:gh-pages', function() {
138 | return gulp.src(DEST + '/**/*')
139 | .pipe(ghPages());
140 | });
141 |
142 | gulp.task('default', ['lint', 'serve']);
143 |
--------------------------------------------------------------------------------
/fend-frogger/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fend-frogger",
3 | "version": "1.0.0",
4 | "description": "This is the third project in Udacity's Front-End Web Developer Nanodegree program.",
5 | "private": true,
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/Tempurturtul/fend-frogger.git"
9 | },
10 | "author": "Tempurturtul",
11 | "license": "MIT",
12 | "homepage": "https://github.com/Tempurturtul/fend-frogger#readme",
13 | "devDependencies": {
14 | "browser-sync": "^2.10.0",
15 | "del": "^2.2.0",
16 | "gulp": "^3.9.0",
17 | "gulp-cssnano": "^2.0.0",
18 | "gulp-gh-pages": "^0.5.4",
19 | "gulp-htmlmin": "^1.3.0",
20 | "gulp-if": "^2.0.0",
21 | "gulp-imagemin": "^2.4.0",
22 | "gulp-jshint": "^2.0.0",
23 | "gulp-jsonlint": "^1.1.1",
24 | "gulp-uglify": "^1.5.1",
25 | "gulp-useref": "^3.0.3",
26 | "jshint": "^2.8.0",
27 | "merge-stream": "^1.0.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/fend-frogger/src/client/css/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | html,
6 | body {
7 | height: 100%;
8 | margin: 0;
9 | padding: 0;
10 | }
11 |
12 | main {
13 | align-items: center;
14 | display: flex;
15 | justify-content: center;
16 | min-height: 100%;
17 | }
18 |
19 | canvas {
20 | }
21 |
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/Gem Blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/Gem Blue.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/Gem Green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/Gem Green.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/Gem Orange.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/Gem Orange.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/Heart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/Heart.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/Key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/Key.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/Rock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/Rock.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/Selector.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/Selector.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/Star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/Star.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/char-boy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/char-boy.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/char-cat-girl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/char-cat-girl.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/char-horn-girl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/char-horn-girl.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/char-pink-girl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/char-pink-girl.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/char-princess-girl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/char-princess-girl.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/enemy-bug.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/enemy-bug.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/grass-block.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/grass-block.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/stone-block.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/stone-block.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/images/water-block.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/images/water-block.png
--------------------------------------------------------------------------------
/fend-frogger/src/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Escape By Water!
6 |
7 |
8 |
9 |
10 |
11 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/fend-frogger/src/client/js/resources.js:
--------------------------------------------------------------------------------
1 | /* Resources.js
2 | * This is simply an image loading utility. It eases the process of loading
3 | * image files so that they can be used within your game. It also includes
4 | * a simple "caching" layer so it will reuse cached images if you attempt
5 | * to load the same image multiple times.
6 | */
7 | (function() {
8 | var resourceCache = {};
9 | var loading = [];
10 | var readyCallbacks = [];
11 |
12 | /* This is the publicly accessible image loading function. It accepts
13 | * an array of strings pointing to image files or a string for a single
14 | * image. It will then call our private image loading function accordingly.
15 | */
16 | function load(urlOrArr) {
17 | if(urlOrArr instanceof Array) {
18 | /* If the developer passed in an array of images
19 | * loop through each value and call our image
20 | * loader on that image file
21 | */
22 | urlOrArr.forEach(function(url) {
23 | _load(url);
24 | });
25 | } else {
26 | /* The developer did not pass an array to this function,
27 | * assume the value is a string and call our image loader
28 | * directly.
29 | */
30 | _load(urlOrArr);
31 | }
32 | }
33 |
34 | /* This is our private image loader function, it is
35 | * called by the public image loader function.
36 | */
37 | function _load(url) {
38 | if(resourceCache[url]) {
39 | /* If this URL has been previously loaded it will exist within
40 | * our resourceCache array. Just return that image rather
41 | * re-loading the image.
42 | */
43 | return resourceCache[url];
44 | } else {
45 | /* This URL has not been previously loaded and is not present
46 | * within our cache; we'll need to load this image.
47 | */
48 | var img = new Image();
49 | img.onload = function() {
50 | /* Once our image has properly loaded, add it to our cache
51 | * so that we can simply return this image if the developer
52 | * attempts to load this file in the future.
53 | */
54 | resourceCache[url] = img;
55 |
56 | /* Once the image is actually loaded and properly cached,
57 | * call all of the onReady() callbacks we have defined.
58 | */
59 | if(isReady()) {
60 | readyCallbacks.forEach(function(func) { func(); });
61 | }
62 | };
63 |
64 | /* Set the initial cache value to false, this will change when
65 | * the image's onload event handler is called. Finally, point
66 | * the image's src attribute to the passed in URL.
67 | */
68 | resourceCache[url] = false;
69 | img.src = url;
70 | }
71 | }
72 |
73 | /* This is used by developers to grab references to images they know
74 | * have been previously loaded. If an image is cached, this functions
75 | * the same as calling load() on that URL.
76 | */
77 | function get(url) {
78 | return resourceCache[url];
79 | }
80 |
81 | /* This function determines if all of the images that have been requested
82 | * for loading have in fact been properly loaded.
83 | */
84 | function isReady() {
85 | var ready = true;
86 | for(var k in resourceCache) {
87 | if(resourceCache.hasOwnProperty(k) &&
88 | !resourceCache[k]) {
89 | ready = false;
90 | }
91 | }
92 | return ready;
93 | }
94 |
95 | /* This function will add a function to the callback stack that is called
96 | * when all requested images are properly loaded.
97 | */
98 | function onReady(func) {
99 | readyCallbacks.push(func);
100 | }
101 |
102 | /* This object defines the publicly accessible functions available to
103 | * developers by creating a global Resources object.
104 | */
105 | window.Resources = {
106 | load: load,
107 | get: get,
108 | onReady: onReady,
109 | isReady: isReady
110 | };
111 | })();
112 |
--------------------------------------------------------------------------------
/fend-frogger/src/client/js/util.js:
--------------------------------------------------------------------------------
1 | /* util.js
2 | * This file provides utility functions for use by other aspects of the program.
3 | */
4 |
5 | (function(global) {
6 | global.util = {
7 | compareRanges: compareRanges,
8 | randomFromRange: randomFromRange,
9 | storageAvailable: storageAvailable
10 | };
11 |
12 | /**
13 | * Checks the position of range b relative to range a. Returns -1 if range b
14 | * occurs before (less-than) range a, 1 if after, and 0 if there is any
15 | * overlap.
16 | * @param {number[]} a
17 | * @param {number[]} b
18 | * @returns {number} -1 for b before a, 1 for b after a, 0 for overlap.
19 | */
20 | function compareRanges(a, b) {
21 | if (b[1] < a[0]) {
22 | return -1;
23 | } else if (b[0] > a[1]) {
24 | return 1;
25 | } else {
26 | return 0;
27 | }
28 | }
29 |
30 | /**
31 | * Returns random integer between min (included) and max (included).
32 | * @returns {number} A random integer between min and max (inclusive).
33 | */
34 | function randomFromRange(min, max) {
35 | return Math.floor(Math.random() * (max - min + 1)) + min;
36 | }
37 |
38 | /**
39 | * Detects whether localStorage is both supported and available.
40 | * Courtesy of MDN: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
41 | * @param {string} type - The type of storage to check ('localStorage' for example).
42 | * @returns {boolean} True if storage is available, false otherwise.
43 | */
44 | function storageAvailable(type) {
45 | try {
46 | var storage = global.window[type];
47 | var x = '__storage_test__';
48 |
49 | storage.setItem(x, x);
50 | storage.removeItem(x);
51 |
52 | return true;
53 | }
54 | catch(e) {
55 | return false;
56 | }
57 | }
58 | })(this);
59 |
--------------------------------------------------------------------------------
/fend-frogger/src/client/sounds/button-press.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/sounds/button-press.wav
--------------------------------------------------------------------------------
/fend-frogger/src/client/sounds/collectable-pickup.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/sounds/collectable-pickup.wav
--------------------------------------------------------------------------------
/fend-frogger/src/client/sounds/died.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/sounds/died.wav
--------------------------------------------------------------------------------
/fend-frogger/src/client/sounds/won.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-frogger/src/client/sounds/won.wav
--------------------------------------------------------------------------------
/fend-neighborhood-map/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | bower_components
3 | dist
4 | .tmp
5 | .publish
6 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/README.md:
--------------------------------------------------------------------------------
1 | # Neighborhood Map
2 |
3 | This is the **5th** project in Udacity's [Front-End Web Developer Nanodegree](https://www.udacity.com/course/front-end-web-developer-nanodegree--nd001) program.
4 |
5 | **[View here.](https://tempurturtul.github.io/udacity-fend-projects/projects/fend-neighborhood-map/)**
6 |
7 | ## Quickstart
8 |
9 | - Install [Node](https://nodejs.org/en/), [Gulp](http://gulpjs.com/), and [Bower](http://bower.io/).
10 | - Clone the repository, navigate to this project, and install dependencies.
11 | ```
12 | git clone https://github.com/Tempurturtul/udacity-fend-projects.git
13 | cd udacity-fend-projects/fend-neighborhood-map/
14 | npm install
15 | bower install
16 | ```
17 | - Run the default gulp task to serve source files. *(See `gulpfile.js` for additional gulp tasks.)*
18 | ```
19 | gulp
20 | ```
21 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fend-neighborhood-map",
3 | "private": true,
4 | "dependencies": {
5 | "knockout": "3.4.0",
6 | "uuid.js": "^3.3.0",
7 | "knockout-dragdrop": "^2.4.4"
8 | },
9 | "resolutions": {
10 | "knockout": "3.4.0"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fend-neighborhood-map",
3 | "version": "1.0.0",
4 | "description": "This is the fifth project in Udacity's Front-End Web Developer Nanodegree program.",
5 | "private": true,
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/Tempurturtul/fend-neighborhood-map.git"
9 | },
10 | "author": "Tempurturtul",
11 | "license": "MIT",
12 | "homepage": "https://github.com/Tempurturtul/fend-neighborhood-map#readme",
13 | "devDependencies": {
14 | "browser-sync": "^2.11.1",
15 | "del": "^2.2.0",
16 | "gulp": "^3.9.1",
17 | "gulp-cssnano": "^2.1.1",
18 | "gulp-gh-pages": "^0.5.4",
19 | "gulp-htmlmin": "^1.3.0",
20 | "gulp-if": "^2.0.0",
21 | "gulp-imagemin": "^2.4.0",
22 | "gulp-jshint": "^2.0.0",
23 | "gulp-jsonlint": "^1.1.2",
24 | "gulp-plumber": "^1.1.0",
25 | "gulp-replace": "^0.5.4",
26 | "gulp-rev-all": "^0.8.22",
27 | "gulp-uglify": "^1.5.3",
28 | "gulp-uncss": "^1.0.4",
29 | "gulp-useref": "^3.0.5",
30 | "jshint": "^2.9.1",
31 | "merge-stream": "^1.0.0",
32 | "psi": "^2.0.3",
33 | "run-sequence": "^1.1.5"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/image/center.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
74 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/image/checkmark-green.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
50 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/image/checkmark.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
50 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/image/fold-arrow.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
50 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/image/pin.svg:
--------------------------------------------------------------------------------
1 |
2 |
52 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/image/sidebar-button.svg:
--------------------------------------------------------------------------------
1 |
2 |
53 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/image/x-red.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
50 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/image/x.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
50 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/js/app.js:
--------------------------------------------------------------------------------
1 | // Core functionality.
2 |
3 | (function(global) {
4 |
5 | // Initialize the app once all resources are finished loading.
6 | global.window.addEventListener('load', init);
7 |
8 | function init() {
9 | var window = global.window,
10 | document = global.document,
11 | map = global.map,
12 | placeInfo = global.placeInfo,
13 | ko = global.ko,
14 | viewmodels = global.viewmodels,
15 | components = global.components;
16 |
17 | // Try to initialize place info.
18 | try {
19 | placeInfo.init();
20 | }
21 | catch (e) {
22 | console.warn(e.name, ':', e.message);
23 |
24 | // Set the `placeInfo` variable to null if an error was thrown.
25 | placeInfo = null;
26 | }
27 |
28 | // Try to initialize the map.
29 | try {
30 | map.init();
31 | }
32 | catch (e) {
33 | console.error(e.name, ':', e.message);
34 |
35 | // The app isn't functional without the map; replace the document body with an error message.
36 | document.body.classList.remove('loading');
37 | document.body.innerHTML = '
Is it possible that something on your end is blocking requests to maps.googleapis.com?
' +
44 | '' +
45 | '
';
46 |
47 | // Abort initialization.
48 | return;
49 | }
50 |
51 | // The map was successfully initialized.
52 |
53 | // Apply the Knockout bindings.
54 | ko.applyBindings(new viewmodels.Main());
55 |
56 | // Remove the loading class after a brief delay.
57 | window.setTimeout(function() {
58 | document.body.classList.remove('loading');
59 | }, 500);
60 | }
61 |
62 | })(this);
63 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/js/models/folder.js:
--------------------------------------------------------------------------------
1 | // The Folder model.
2 |
3 | (function(global) {
4 |
5 | var ko,
6 | initialized = false;
7 |
8 | global.models = global.models || {};
9 |
10 | global.models.Folder = Folder;
11 |
12 | function init() {
13 | // It's possible for ko to be undefined on the global scope when this IIFE
14 | // is initially invoked due to async script loading.
15 | ko = global.ko;
16 | initialized = true;
17 | }
18 |
19 | function Folder(data) {
20 | if (!initialized) {
21 | init();
22 | }
23 |
24 | data = data || {};
25 |
26 | // The name of the folder.
27 | this.name = ko.observable(data.name || 'New Folder');
28 | // The folder contents (marker and/or marker folder array).
29 | this.contents = ko.observableArray(data.contents || []);
30 | // Whether or not the folder is collapsed.
31 | this.collapsed = ko.observable(data.collapsed || false);
32 | // Whether or not the folder's name is being edited.
33 | this.editing = ko.observable(data.editing || false);
34 | this.visible = ko.observable(data.visible || true);
35 | }
36 |
37 | })(this);
38 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/js/models/marker.js:
--------------------------------------------------------------------------------
1 | // The Marker model.
2 |
3 | (function(global) {
4 |
5 | var ko,
6 | uuid,
7 | initialized = false;
8 |
9 | global.models = global.models || {};
10 |
11 | global.models.Marker = Marker;
12 |
13 | function init() {
14 | // It's possible for ko and UUID to be undefined on the global scope when
15 | // this IIFE is initially invoked due to async script loading.
16 | ko = global.ko;
17 | uuid = global.UUID;
18 | initialized = true;
19 | }
20 |
21 | function Marker(data) {
22 | if (!initialized) {
23 | init();
24 | }
25 |
26 | data = data || {};
27 |
28 | this.id = ko.observable(data.id || uuid.generate());
29 | this.description = ko.observable(data.description || '');
30 | this.position = ko.observable(data.position || {lat: 0, lng: 0});
31 | this.title = ko.observable(data.title || 'New Marker');
32 | this.selected = ko.observable(data.selected || false);
33 | this.visible = ko.observable(data.visible || true);
34 | }
35 |
36 | })(this);
37 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/js/util.js:
--------------------------------------------------------------------------------
1 | // Utility functions.
2 |
3 | (function(global) {
4 |
5 | global.util = {
6 | fullpageForm: fullpageForm,
7 | isElement: isElement
8 | };
9 |
10 | /**
11 | * Creates a full-page form with the given content and calls the given
12 | * callback with an object array containing the IDs, values, and checked
13 | * states of any input elements, then removes the form.
14 | * @param { string | object } message - The string or Node representing the form's message.
15 | * @param { string | object } inputs - A string or Node representing the form's inputs.
16 | * @param { submitCB } submitCB - The form submit callback.
17 | * @param { cancelCB } [cancelCB] - The form cancel callback.
18 | */
19 | function fullpageForm(message, inputs, submitCB, cancelCB) {
20 | // Verify the arguments.
21 |
22 | if (typeof message !== 'string' && !isElement(message)) {
23 | throw new TypeError('Form message must be a String or DOM Element.');
24 | }
25 |
26 | if (typeof inputs !== 'string' && !isElement(inputs)) {
27 | throw new TypeError('Form inputs must be a String or DOM Element.');
28 | }
29 |
30 | /*jshint eqnull:true */
31 | if (typeof submitCB !== 'function' ||
32 | (cancelCB != null && typeof cancelCB !== 'function')) {
33 | throw new TypeError('Form callbacks must be functions (or optionally undefined in the case of the cancel callback).');
34 | }
35 |
36 |
37 | // Create the form.
38 |
39 | var formElem = document.createElement('form');
40 | formElem.classList.add('util-fullpage-form');
41 |
42 | var overlayParentElem = document.createElement('div');
43 | overlayParentElem.classList.add('util-fullpage-form-overlay');
44 | overlayParentElem.appendChild(formElem);
45 |
46 | // Add the message.
47 | if (typeof message === 'string') {
48 | formElem.innerHTML = message;
49 | } else {
50 | formElem.appendChild(message);
51 | }
52 |
53 | // Add the inputs.
54 | var inputsContainerElem = document.createElement('div');
55 |
56 | if (typeof inputs === 'string') {
57 | inputsContainerElem.innerHTML += inputs;
58 | } else {
59 | inputsContainerElem.appendChild(inputs);
60 | }
61 |
62 | formElem.appendChild(inputsContainerElem);
63 |
64 | // Add the standard confirm and cancel buttons.
65 | var controlsContainerElem = document.createElement('div'),
66 | confirmBtnElem = document.createElement('button'),
67 | cancelBtnElem = document.createElement('button');
68 |
69 | confirmBtnElem.type = 'button';
70 | cancelBtnElem.type = 'button';
71 | confirmBtnElem.onclick = submit;
72 | cancelBtnElem.onclick = cancel;
73 | confirmBtnElem.textContent = 'Confirm';
74 | cancelBtnElem.textContent = 'Cancel';
75 |
76 | controlsContainerElem.appendChild(cancelBtnElem);
77 | controlsContainerElem.appendChild(confirmBtnElem);
78 | formElem.appendChild(controlsContainerElem);
79 |
80 | // Add the default styles.
81 | overlayParentElem.style.position = 'fixed';
82 | overlayParentElem.style.top = '0';
83 | overlayParentElem.style.left = '0';
84 | overlayParentElem.style.bottom = '0';
85 | overlayParentElem.style.right = '0';
86 | overlayParentElem.style.background = 'rgba(0,0,0,0.5)';
87 | overlayParentElem.style.padding = '10px';
88 | overlayParentElem.style.display = 'flex';
89 | overlayParentElem.style['justify-content'] = 'center';
90 | overlayParentElem.style['align-items'] = 'center';
91 | overlayParentElem.style['flex-direction'] = 'column';
92 | overlayParentElem.style['text-align'] = 'center';
93 | overlayParentElem.style['z-index'] = '999';
94 |
95 | formElem.style.background = 'white';
96 | formElem.style.border = 'solid 1px black';
97 | formElem.style.color = 'black';
98 | formElem.style.padding = '10px';
99 | formElem.style['max-height'] = '100%';
100 | formElem.style['overflow-y'] = 'scroll';
101 |
102 | controlsContainerElem.style['margin-top'] = '15px';
103 |
104 | cancelBtnElem.style['margin-right'] = '10px';
105 |
106 | // Add the form to the document body.
107 | document.body.appendChild(overlayParentElem);
108 |
109 | function cancel() {
110 | // If a cancel callback was passed, call it with the inputs' values.
111 | if (cancelCB) {
112 | cancelCB(getInputData(inputsContainerElem));
113 | }
114 |
115 | remove();
116 | }
117 |
118 | function getInputData(elem) {
119 | var results = [];
120 |
121 | if (elem.tagName.toLowerCase() === 'input') {
122 | var result = {
123 | id: elem.id,
124 | value: elem.value,
125 | checked: elem.checked
126 | };
127 |
128 | results.push(result);
129 | } else if (elem.children.length) {
130 | for (var i = 0, len = elem.children.length; i < len; i++) {
131 | results = results.concat(getInputData(elem.children[i]));
132 | }
133 | }
134 |
135 | return results;
136 | }
137 |
138 | function remove() {
139 | document.body.removeChild(overlayParentElem);
140 | overlayParentElem = null;
141 | formElem = null;
142 | controlsContainerElem = null;
143 | confirmBtnElem = null;
144 | cancelBtnElem = null;
145 | }
146 |
147 | function submit() {
148 | // Call the submit callback with the inputs' values.
149 | submitCB(getInputData(inputsContainerElem));
150 |
151 | remove();
152 | }
153 | }
154 |
155 | /**
156 | * Returns true if o is a DOM element. (Credit: http://stackoverflow.com/a/384380)
157 | */
158 | function isElement(o){
159 | return typeof HTMLElement === "object" ?
160 | o instanceof HTMLElement : //DOM2
161 | o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName==="string";
162 | }
163 |
164 | })(this);
165 |
--------------------------------------------------------------------------------
/fend-neighborhood-map/src/js/viewmodels/markersForm.js:
--------------------------------------------------------------------------------
1 | // The Markers Form View Model.
2 |
3 | (function(global) {
4 |
5 | global.viewmodels = global.viewmodels || {};
6 |
7 | global.viewmodels.MarkersForm = MarkersForm;
8 |
9 | function MarkersForm(mainViewModel) {
10 | var self = this,
11 | map = global.map,
12 | ko = global.ko,
13 | tracked = []; // Array of objects containing marker ID and KO subscription.
14 |
15 | // Cancels the form.
16 | self.cancel = function() {
17 | // Close the markers form.
18 | close();
19 |
20 | // Clear the pending and tracked arrays.
21 | clearPending();
22 | clearTracked();
23 | };
24 |
25 | // Opens the form.
26 | self.open = function() {
27 | if (!self.visible()) {
28 | self.visible(true);
29 | }
30 | };
31 |
32 | // The pending markers.
33 | self.pending = ko.observableArray([]);
34 |
35 | // Submits the form.
36 | self.submit = function() {
37 | // Close the markers form.
38 | close();
39 |
40 | // Filter the confirmed (visible) markers out of the pending array and into the markers
41 | // array.
42 | self.pending(self.pending().filter(function(pending) {
43 | if (pending.visible()) {
44 | // Move to the main view model's markers array.
45 | mainViewModel.markers.push(pending);
46 | return false;
47 | } else {
48 | return true;
49 | }
50 | }));
51 |
52 | // Clear the pending and tracked arrays.
53 | clearPending();
54 | clearTracked();
55 |
56 | // Save changes.
57 | mainViewModel.saveMarkers();
58 | };
59 |
60 | // Whether or not the form is visible (open).
61 | self.visible = ko.observable(false);
62 |
63 | init();
64 |
65 | /**
66 | * Clears the pending markers.
67 | */
68 | function clearPending() {
69 | var pendingCopy = self.pending().slice();
70 |
71 | pendingCopy.forEach(function(marker) {
72 | mainViewModel.removeMarker(marker); // Removes from containing array as well (self.pending).
73 | });
74 | }
75 |
76 | /**
77 | * Clears the tracked markers.
78 | */
79 | function clearTracked() {
80 | tracked.forEach(function(obj) {
81 | obj.subscription.dispose();
82 | });
83 |
84 | tracked = [];
85 | }
86 |
87 | /**
88 | * Closes the form.
89 | */
90 | function close() {
91 | if (self.visible()) {
92 | self.visible(false);
93 | }
94 | }
95 |
96 | /**
97 | * Initializes the markers form.
98 | */
99 | function init() {
100 | self.pending.subscribe(trackPending);
101 | }
102 |
103 | /**
104 | * Tracks the pending markers.
105 | * @param {object[]} pendingMarkers
106 | */
107 | function trackPending(pendingMarkers) {
108 | // If there are no pending markers, close the form.
109 | if (!pendingMarkers.length) {
110 | clearTracked();
111 | close();
112 | return;
113 | }
114 |
115 | var trackedIDs = tracked.map(function(obj) {
116 | return obj.id;
117 | });
118 |
119 | pendingMarkers.forEach(function(pending) {
120 | // If the marker isn't being tracked...
121 | if (trackedIDs.indexOf(pending.id()) === -1) {
122 | tracked.push({
123 | id: pending.id(),
124 | subscription: pending.visible.subscribe(function(newValue) { updateVisibility(pending.id(), newValue); })
125 | });
126 | }
127 | });
128 | }
129 |
130 | /**
131 | * Updates the visibility of the marker.
132 | * @param {string} id - The marker's ID.
133 | * @param {boolean} newValue - The new visibility value.
134 | */
135 | function updateVisibility(id, newValue) {
136 | map.modifyMarker(id, {visible: newValue});
137 | }
138 | }
139 |
140 | })(this);
141 |
--------------------------------------------------------------------------------
/fend-optimization/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .publish
4 | .tmp
5 |
--------------------------------------------------------------------------------
/fend-optimization/README.md:
--------------------------------------------------------------------------------
1 | # Optimization
2 |
3 | This is the **4th** project in Udacity's [Front-End Web Developer Nanodegree](https://www.udacity.com/course/front-end-web-developer-nanodegree--nd001) program. It provides a portfolio website that must be optimized to achieve a high [PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/) score and steady FPS.
4 |
5 | ## Optimization Process
6 | 1. Concatenated appropriate `.js` and `.css` files.
7 | 1. Minified `.css`, `.js`, `.html`, and images.
8 | 1. Applied `media` and `async` attributes where appropriate.
9 | 1. Moved google analytics scripts to end of body.
10 | 1. Refactored `views/js/main.js`.
11 | 1. Replaced pizzeria thumbnail with a resized image.
12 | 1. Replaced remotely hosted thumbnails with locally hosted versions (allowing image optimization and manipulation of `cache-control` headers).
13 | 1. Set `cache-control` `max-age` to 1 year for appropriate resources.
14 | 1. Applied finger-prints to appropriate resources for cache-busting purposes.
15 | 1. Inlined critical and other appropriate `.css`.
16 | 1. Removed use of google fonts.
17 |
18 | ## Quickstart
19 |
20 | - Install [Node](https://nodejs.org/en/) and [Gulp](http://gulpjs.com/).
21 | - Clone the repository, navigate to this project, and install dependencies.
22 | ```
23 | git clone https://github.com/Tempurturtul/udacity-fend-projects.git
24 | cd udacity-fend-projects/fend-optimization/
25 | npm install
26 | ```
27 | - Run the desired gulp task. *(See `gulpfile.js` for additional tasks.)*
28 | ```
29 | gulp # Lints then serves source files.
30 | gulp build # Builds distribution files.
31 | gulp serve:dest # Serves distribution files.
32 | gulp psi # Displays the PageSpeed Insights report. (Modify the psiPath variable in gulpfile.js to test different pages.)
33 | ```
34 |
35 | ## Known Issues
36 |
37 | - `gulp build` sometimes returns an error related to file streams being manipulated by `gulp-imagemin` closing too early. Resolve by re-running the `gulp build` task.
38 |
--------------------------------------------------------------------------------
/fend-optimization/docs/Optimization Notes:
--------------------------------------------------------------------------------
1 | Optimization Notes
2 |
3 | Basics
4 |
5 | Minify, Compress, Cache
6 | (HTML, CSS, JavaScript)
7 | Minimize use of render blocking resources.
8 | (CSS)
9 | (Inline or use media queries.)
10 | Minimize use of parser blocking resources.
11 | (JS)
12 | (Defer execution or use async attribute.)
13 |
14 | 1. Minimize bytes.
15 | 2. Reduce critical resources.
16 | 3. Shorten CRP length.
17 | (Analyze CRP: number of critical resources, bytes, round trips.)
18 |
19 | Further Detail
20 |
21 | Apply content-specific optimizations first: CSS, JS, and HTML minifiers; then apply GZIP to compress the minified output. (Most servers automatically apply GZIP compression.)
22 | Use HTTP caching. (See HTML5 Boilerplate for sample server config files.)
23 | See following for choosing optimal cache-control policy.
24 | https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching
25 | Use versions or fingerprints in file names to allow on-demand updates (style.0001.css).
26 | Reduce render-blocking CSS by and using media attribute with multiple CSS files.
27 | Ex.:
28 | Use the async attribute to prevent javascript from blocking DOM and CSSOM.
29 | Ex.:
30 |
--------------------------------------------------------------------------------
/fend-optimization/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fend-optimization",
3 | "version": "1.0.0",
4 | "description": "This is the fourth project in Udacity's Front-End Web Developer Nanodegree program.",
5 | "private": true,
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/Tempurturtul/fend-optimization.git"
9 | },
10 | "author": "Tempurturtul",
11 | "license": "MIT",
12 | "homepage": "https://github.com/Tempurturtul/fend-optimization#readme",
13 | "devDependencies": {
14 | "browser-sync": "^2.10.0",
15 | "del": "^2.2.0",
16 | "gulp": "^3.9.0",
17 | "gulp-cssnano": "^2.0.0",
18 | "gulp-gh-pages": "^0.5.4",
19 | "gulp-htmlmin": "^1.3.0",
20 | "gulp-if": "^2.0.0",
21 | "gulp-imagemin": "^2.4.0",
22 | "gulp-jshint": "^2.0.0",
23 | "gulp-jsonlint": "^1.1.1",
24 | "gulp-plumber": "^1.0.1",
25 | "gulp-replace": "^0.5.4",
26 | "gulp-rev-all": "^0.8.22",
27 | "gulp-uglify": "^1.5.1",
28 | "gulp-uncss": "^1.0.4",
29 | "gulp-useref": "^3.0.5",
30 | "jshint": "^2.8.0",
31 | "merge-stream": "^1.0.0",
32 | "psi": "^2.0.2",
33 | "run-sequence": "^1.1.5"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/fend-optimization/src/css/print.css:
--------------------------------------------------------------------------------
1 | @media print {
2 | * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; }
3 | a, a:visited { color: #444 !important; text-decoration: underline; }
4 | a[href]:after { content: " (" attr(href) ")"; }
5 | tr, img { page-break-inside: avoid; }
6 | img { max-width: 100% !important; }
7 | @page { margin: 0.5cm; }
8 | p, h2, h3 { orphans: 3; widows: 3; }
9 | h2, h3{ page-break-after: avoid; }
10 | }
11 |
--------------------------------------------------------------------------------
/fend-optimization/src/css/style.css:
--------------------------------------------------------------------------------
1 | html {
2 | font-size: 100%;
3 | overflow-y: scroll;
4 | -webkit-tap-highlight-color: rgba(0,0,0,0);
5 | -ms-text-size-adjust: 100%;
6 | -webkit-text-size-adjust: none;
7 | }
8 | body { margin: 0; font-size: 14px; line-height: 1.61; font-weight: 400; }
9 | body, button, input, select, textarea { font-family: 'Open Sans', sans-serif; color: #333; }
10 |
11 | a { color: #12C; }
12 | a:visited { color: #61C; }
13 | a:focus { outline: thin dotted; }
14 | a:hover, a:active { color: #c00; outline: 0; }
15 |
16 | b, strong { font-weight: bold; }
17 | pre, code { font-family: monospace, monospace; font-size: 1em; }
18 | ul, ol { margin: 1em 0; padding: 0 0 0 20px; }
19 | img { border: 0; max-width: 100%; }
20 |
21 | body { background: #fff; }
22 | header, footer, .container { max-width: 45em; margin: 0 auto; }
23 |
24 | header { padding: 0 0.5em; color: #C90B0B; }
25 | header img { border-radius: 40px; float: left; }
26 | header p { font-size:1.5em; font-weight: bold; padding-left: 4em;}
27 | header p span { font-size: 0.8em; font-weight: normal;}
28 |
29 | .hero { padding: 2em; background-color: #f8f8f8; font-size:1.2em;
30 | border-bottom: 1px solid #ccc;
31 | border-top: 1px solid #ccc;
32 | }
33 |
34 | .content { padding: 1em 1em; }
35 | .content li { list-style-type: none; font-size: 1.1em;}
36 | li img { float:left; padding-right: 1em; }
37 | li p { font-size: 0.9em; font-style: italic; }
38 |
39 | footer {
40 | padding: 0 0.5em;
41 | border-top: 1px solid #ccc;
42 | }
43 | footer span { float: right; font-style: italic; }
44 |
45 | /* Smartphones (portrait) */
46 | @media only screen and (max-width: 480px) {
47 | body { font-size: 12px;}
48 | header p { padding-left: 4.5em;}
49 | }
50 |
--------------------------------------------------------------------------------
/fend-optimization/src/image/2048-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/image/2048-thumb.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/image/2048.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/image/2048.png
--------------------------------------------------------------------------------
/fend-optimization/src/image/cam_be_like.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/image/cam_be_like.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/image/mobile-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/image/mobile-thumb.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/image/mobilewebdev.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/image/mobilewebdev.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/image/pizzeria-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/image/pizzeria-thumb.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/image/profilepic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/image/profilepic.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/image/webperf-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/image/webperf-thumb.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Freshly Optimized Example Site
7 |
8 |
9 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
85 |
86 |
87 |
88 |
89 |
90 |
Cameron Pittman Course Developer
91 |
92 |
93 |
94 |
95 | I love web development! This is a template for a simple portfolio. I decided to use it to showcase a few Udacity courses I've taken and some teaching work, but you can use it to showcase any kind of project that you want the world to see :) Contact me: me@email.com
96 |
84 | 2048 is awesome! I loved making my own 2048 with Andy and Sarah. Below, I'm showing off a screenshot from the Udacity version of 2048.
85 |
86 |
87 |
88 |
89 |
90 |
91 |
Bacon ipsum dolor sit amet et pork belly porchetta excepteur dolor, laborum laboris magna labore dolore in fugiat beef ribs. Fugiat leberkas nulla do kevin dolore. Flank hamburger dolor swine prosciutto sirloin pig jerky sunt consequat pariatur. Mollit meatloaf nostrud laboris shoulder excepteur velit officia meatball nisi turkey. Nulla jowl spare ribs, et drumstick magna frankfurter.
92 |
93 |
Venison spare ribs dolor tri-tip duis turkey. Ut chicken proident ribeye est flank, sed frankfurter. Kielbasa exercitation ullamco leberkas. Landjaeger turkey culpa, tail short loin consectetur salami venison in corned beef eiusmod qui ad leberkas. Tri-tip adipisicing frankfurter ut sirloin rump consectetur. Chuck sint filet mignon labore eiusmod nulla. Venison shankle pork, consectetur nisi bacon spare ribs anim meatball sausage ball tip labore aute reprehenderit adipisicing.
84 | Developing for mobile is important! If you haven't taken this class, I highly recommend it!
85 |
86 |
87 |
88 |
89 |
Bacon ipsum dolor sit amet et pork belly porchetta excepteur dolor, laborum laboris magna labore dolore in fugiat beef ribs. Fugiat leberkas nulla do kevin dolore. Flank hamburger dolor swine prosciutto sirloin pig jerky sunt consequat pariatur. Mollit meatloaf nostrud laboris shoulder excepteur velit officia meatball nisi turkey. Nulla jowl spare ribs, et drumstick magna frankfurter.
90 |
91 |
92 |
93 |
Venison spare ribs dolor tri-tip duis turkey. Ut chicken proident ribeye est flank, sed frankfurter. Kielbasa exercitation ullamco leberkas. Landjaeger turkey culpa, tail short loin consectetur salami venison in corned beef eiusmod qui ad leberkas. Tri-tip adipisicing frankfurter ut sirloin rump consectetur. Chuck sint filet mignon labore eiusmod nulla. Venison shankle pork, consectetur nisi bacon spare ribs anim meatball sausage ball tip labore aute reprehenderit adipisicing.
84 | Thanks for taking this class! You are awesome for investing time and energy into your future :) We love making classes for you!
85 |
86 |
87 |
88 |
89 |
Thanks to everyone at Udacity and Google who made this class happen! Now for a very true meme and some lorem bacon ipsum.
90 |
91 |
92 |
93 |
Bacon ipsum dolor sit amet et pork belly porchetta excepteur dolor, laborum laboris magna labore dolore in fugiat beef ribs. Fugiat leberkas nulla do kevin dolore. Flank hamburger dolor swine prosciutto sirloin pig jerky sunt consequat pariatur. Mollit meatloaf nostrud laboris shoulder excepteur velit officia meatball nisi turkey. Nulla jowl spare ribs, et drumstick magna frankfurter.
94 |
95 |
Venison spare ribs dolor tri-tip duis turkey. Ut chicken proident ribeye est flank, sed frankfurter. Kielbasa exercitation ullamco leberkas. Landjaeger turkey culpa, tail short loin consectetur salami venison in corned beef eiusmod qui ad leberkas. Tri-tip adipisicing frankfurter ut sirloin rump consectetur. Chuck sint filet mignon labore eiusmod nulla. Venison shankle pork, consectetur nisi bacon spare ribs anim meatball sausage ball tip labore aute reprehenderit adipisicing.
96 |
97 |
98 |
99 |
100 |
101 |
104 |
105 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/fend-optimization/src/views/css/style.css:
--------------------------------------------------------------------------------
1 | /** {
2 | outline: 1px solid red !important;
3 | }*/
4 | * {
5 | -webkit-box-sizing: border-box;
6 | -moz-box-sizing: border-box;
7 | -box-sizing: border-box;
8 | }
9 |
10 | body {
11 | font-family: "Trebuchet MS", Helvetica, sans-serif;
12 | background: black;
13 | }
14 |
15 | input {
16 | background: grey;
17 | font-size: 18px;
18 | }
19 |
20 | form {
21 | display: inline-block;
22 | }
23 |
24 | .centered {
25 | text-align: center;
26 | }
27 |
28 | #pizzaSize {
29 | font-weight: 800;
30 | }
31 |
32 | .mover {
33 | position: fixed;
34 | width: 256px;
35 | z-index: -1;
36 | /* Promote these elements since we plan to animate them. */
37 | will-change: transform;
38 | transform: translateZ(0);
39 | }
40 |
41 | .randomPizzaContainer {
42 | float: left;
43 | display: flex;
44 | }
45 |
46 | .randomPizzaContainer:after {
47 | content: "";
48 | display: table;
49 | clear:both;
50 | }
51 |
52 | .container {
53 | background-color: rgba(240, 60, 60, 0.8);
54 | }
55 |
--------------------------------------------------------------------------------
/fend-optimization/src/views/image/pizza.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/views/image/pizza.png
--------------------------------------------------------------------------------
/fend-optimization/src/views/image/pizzeria-1024x768.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/views/image/pizzeria-1024x768.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/views/image/pizzeria-256x192.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/views/image/pizzeria-256x192.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/views/image/pizzeria-512x384.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/views/image/pizzeria-512x384.jpg
--------------------------------------------------------------------------------
/fend-optimization/src/views/image/pizzeria.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-optimization/src/views/image/pizzeria.jpg
--------------------------------------------------------------------------------
/fend-portfolio/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .publish
4 | .tmp
5 |
--------------------------------------------------------------------------------
/fend-portfolio/README.md:
--------------------------------------------------------------------------------
1 | # Portfolio
2 | This is the **1st** project in Udacity's [Front-End Web Developer Nanodegree](https://www.udacity.com/course/front-end-web-developer-nanodegree--nd001) program.
3 |
4 | **[View here.](https://tempurturtul.github.io/udacity-fend-projects/projects/fend-portfolio/)**
5 |
6 | In this project, I am provided with a design mockup for a portfolio website that I must replicate. The website I create must be responsive, and must provide an overview of each of the portfolio projects that I complete throughout the nanodegree program. It must also adhere to the program's [styleguide](http://udacity.github.io/frontend-nanodegree-styleguide/) and be validated against the [W3C's Validators](http://validator.w3.org/). I am free to personalize the design as I wish.
7 |
8 | ## Quickstart
9 | - Install [Node](https://nodejs.org/en/) and [Gulp](http://gulpjs.com/).
10 | - Clone the repository, navigate to this project, and install dependencies.
11 | ```
12 | git clone https://github.com/Tempurturtul/udacity-fend-projects.git
13 | cd udacity-fend-projects/fend-portfolio/
14 | npm install
15 | ```
16 | - Run the default gulp task to serve source files. *(See `gulpfile.js` for additional tasks.)*
17 | ```
18 | gulp
19 | ```
20 |
--------------------------------------------------------------------------------
/fend-portfolio/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fend-portfolio",
3 | "version": "1.0.0",
4 | "description": "This is the first project in Udacity's Front-End Web Developer Nanodegree program.",
5 | "private": true,
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/Tempurturtul/fend-portfolio.git"
9 | },
10 | "author": "Tempurturtul",
11 | "license": "MIT",
12 | "homepage": "https://github.com/Tempurturtul/fend-portfolio#readme",
13 | "devDependencies": {
14 | "browser-sync": "^2.10.0",
15 | "del": "^2.2.0",
16 | "gulp": "^3.9.0",
17 | "gulp-cssnano": "^2.0.0",
18 | "gulp-gh-pages": "^0.5.4",
19 | "gulp-htmlmin": "^1.3.0",
20 | "gulp-if": "^2.0.0",
21 | "gulp-imagemin": "^2.4.0",
22 | "gulp-jshint": "^2.0.0",
23 | "gulp-jsonlint": "^1.1.1",
24 | "gulp-plumber": "^1.0.1",
25 | "gulp-replace": "^0.5.4",
26 | "gulp-rev-all": "^0.8.22",
27 | "gulp-uglify": "^1.5.1",
28 | "gulp-uncss": "^1.0.4",
29 | "gulp-useref": "^3.0.5",
30 | "jshint": "^2.8.0",
31 | "merge-stream": "^1.0.0",
32 | "psi": "^2.0.2",
33 | "run-sequence": "^1.1.5"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/GitHub-Mark-32px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/GitHub-Mark-32px.png
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/frogger-300x300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/frogger-300x300.png
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/frogger-600x600.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/frogger-600x600.png
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/neighborhood-map-300x300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/neighborhood-map-300x300.png
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/neighborhood-map-600x600.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/neighborhood-map-600x600.png
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/resume-300x300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/resume-300x300.png
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/resume-600x600.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/resume-600x600.png
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/twitch-streamers-300x300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/twitch-streamers-300x300.png
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/twitch-streamers-600x600.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/twitch-streamers-600x600.png
--------------------------------------------------------------------------------
/fend-portfolio/src/content/img/udacity-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-portfolio/src/content/img/udacity-logo.png
--------------------------------------------------------------------------------
/fend-resume/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | bower_components
3 | dist
4 | .publish
5 |
--------------------------------------------------------------------------------
/fend-resume/README.md:
--------------------------------------------------------------------------------
1 | # Resume
2 | This is the **2nd** project in Udacity's [Front-End Web Developer Nanodegree](https://www.udacity.com/course/front-end-web-developer-nanodegree--nd001) program.
3 |
4 | **[View here.](https://tempurturtul.github.io/udacity-fend-projects/projects/fend-resume/)**
5 |
6 | In this project I was required to complete Udacity's [JavaScript Basics](https://www.udacity.com/course/javascript-basics--ud804) course, which covers the construction of the basic resume site using a provided template. I was then allowed to personalize the result.
7 |
8 | I used the [Polymer](https://www.polymer-project.org/) `iron-collapse` component in order to achieve the "Exceeds Specifications" evaluation, and used Gulp and Bower during development to aid my workflow.
9 |
10 | ## Quickstart
11 |
12 | - Install [Node](https://nodejs.org/en/), [Gulp](http://gulpjs.com/), and [Bower](http://bower.io/).
13 | - Clone the repository, navigate to this project, and install dependencies.
14 | ```
15 | git clone https://github.com/Tempurturtul/udacity-fend-projects.git
16 | cd udacity-fend-projects/fend-resume/
17 | npm install
18 | bower install
19 | ```
20 | - Run the default gulp task to serve source files. *(See `gulpfile.js` for additional tasks.)*
21 | ```
22 | gulp
23 | ```
24 |
--------------------------------------------------------------------------------
/fend-resume/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fend-resume",
3 | "private": true,
4 | "ignore": [],
5 | "dependencies": {
6 | "polymer": "Polymer/polymer#^1.2.0",
7 | "iron-collapse": "PolymerElements/iron-collapse#~1.0.5"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/fend-resume/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fend-resume",
3 | "version": "1.1.0",
4 | "description": "This is the second project in Udacity's Front-End Web Developer Nanodegree program.",
5 | "private": true,
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/Tempurturtul/fend-resume.git"
9 | },
10 | "author": "Tempurturtul",
11 | "license": "MIT",
12 | "homepage": "https://github.com/Tempurturtul/fend-resume#readme",
13 | "devDependencies": {
14 | "browser-sync": "^2.10.0",
15 | "del": "^2.2.0",
16 | "gulp": "^3.9.0",
17 | "gulp-cssnano": "^2.0.0",
18 | "gulp-gh-pages": "^0.5.4",
19 | "gulp-htmlmin": "^1.3.0",
20 | "gulp-if": "^2.0.0",
21 | "gulp-imagemin": "^2.4.0",
22 | "gulp-jshint": "^2.0.0",
23 | "gulp-jsonlint": "^1.1.1",
24 | "gulp-plumber": "^1.0.1",
25 | "gulp-replace": "^0.5.4",
26 | "gulp-rev-all": "^0.8.22",
27 | "gulp-uglify": "^1.5.1",
28 | "gulp-uncss": "^1.0.4",
29 | "gulp-useref": "^3.0.5",
30 | "jshint": "^2.8.0",
31 | "merge-stream": "^1.0.0",
32 | "psi": "^2.0.2",
33 | "run-sequence": "^1.1.5"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/fend-resume/src/elements/elements.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-feed-reader-specs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-feed-reader-specs.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-frogger-gameplay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-frogger-gameplay.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-frogger-scores.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-frogger-scores.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-frogger-start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-frogger-start.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-neighborhood-map-clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-neighborhood-map-clear.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-neighborhood-map-delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-neighborhood-map-delete.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-neighborhood-map-info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-neighborhood-map-info.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-neighborhood-map-sidebar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-neighborhood-map-sidebar.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-optimization-game.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-optimization-game.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-optimization-home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-optimization-home.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-optimization-pizzeria.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-optimization-pizzeria.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-portfolio-contact.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-portfolio-contact.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-portfolio-top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-portfolio-top.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-portfolio-work.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-portfolio-work.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-resume-bot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-resume-bot.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-resume-mid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-resume-mid.png
--------------------------------------------------------------------------------
/fend-resume/src/img/fend-resume-top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/fend-resume-top.png
--------------------------------------------------------------------------------
/fend-resume/src/img/junior-dev-blog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/junior-dev-blog.png
--------------------------------------------------------------------------------
/fend-resume/src/img/junior-dev-contact.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/junior-dev-contact.png
--------------------------------------------------------------------------------
/fend-resume/src/img/junior-dev-landing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/junior-dev-landing.png
--------------------------------------------------------------------------------
/fend-resume/src/img/junior-dev-portfolio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/junior-dev-portfolio.png
--------------------------------------------------------------------------------
/fend-resume/src/img/self.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tempurturtul/udacity-fend-projects/d8075f9cce2353fc523956a9056a2fbd5d24847b/fend-resume/src/img/self.png
--------------------------------------------------------------------------------
/fend-resume/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Resume | Feidt
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 |
47 |
48 |
49 |
58 |
59 |
60 |
';
52 |
--------------------------------------------------------------------------------
/projects-index/README.md:
--------------------------------------------------------------------------------
1 | # Projects Index
2 |
3 | Provides an index site for all projects stored one level above this directory (`../`).
4 |
5 | ## Requirements
6 |
7 | - The `src/scripts/main.js` file must be edited so the `sourcePath` variable on line 5 matches the path to the source code for your projects. This path must be fundamentally the same for all projects, minus the project name.
8 | - Example:
9 | ```js
10 | var sourcePath = 'https://github.com/Tempurturtul/{{project-name}}';
11 | ```
12 |
13 | **Additional build script specific requirements:**
14 |
15 | - Bash and \*nix commands (only tested on Ubuntu).
16 | - All directories in `../` must be projects with a directory name equal to the source code repository name for the project.
17 | - All projects with a live version must have a `src/` subdirectory at depth 1 and a `dist/` subdirectory at depth 1 containing all distribution files.
18 |
19 | ## Quickstart
20 |
21 | **Using the build script:**
22 |
23 | 1. Clone this repository next to the projects you wish to provide links to.
24 | ```
25 | cd YOUR_PROJECTS_FOLDER/
26 | git clone https://github.com/Tempurturtul/projects-index.git
27 | ```
28 | 1. Edit the `src/scripts/main.js` file as described in the requirements section.
29 | 1. Navigate to the project directory and change permissions on the bash build script to allow execution.
30 | ```
31 | cd projects-index/
32 | chmod 555 ./build-script
33 | ```
34 | 1. **Make sure you're in the `projects-index/` directory. This is important.**
35 | 1. **Make sure you read the `build-script` file. I make no guarantee that it won't set your device on fire.**
36 | 1. Run the build script.
37 | ```
38 | # YOU READ IT, RIGHT?
39 | ./build-script
40 | ```
41 | 1. Spin up a local server and view in your browser.
42 | ```
43 | # Just an example, do this however you like.
44 | cd src/
45 | python -m SimpleHTTPServer 3000 & sleep 2; firefox -new-tab localhost:3000
46 | ```
47 |
48 | **Without the build script:**
49 |
50 | 1. Clone this repository.
51 | ```
52 | git clone https://github.com/Tempurturtul/projects-index.git
53 | ```
54 | 1. Edit the `src/scripts/main.js` file as described in the requirements section.
55 | 1. Copy your projects' distribution files to `src/projects/YOUR_PROJECT/`.
56 | 1. Create a `src/scripts/projects.js` file with the following contents:
57 | ```js
58 | var projects = [
59 | {
60 | name: 'YOUR_PROJECT',
61 | live: true // or false, depending on the presence of distribution files.
62 | },
63 | {
64 | name: 'YOUR_OTHER_PROJECT',
65 | live: true // or false...
66 | },
67 | // ...
68 | ];
69 | ```
70 | 1. Spin up a local server and view in your browser.
71 | ```
72 | # Just an example, do this however you like.
73 | cd src/
74 | python -m SimpleHTTPServer 3000 & sleep 2; firefox -new-tab localhost:3000
75 | ```
76 |
--------------------------------------------------------------------------------
/projects-index/build-script:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Build Script, version 2
3 | #
4 | # Populates the ./src/projects/ directory with subdirectories
5 | #+ containing distribution files for each project in ../ that has
6 | #+ both a src/ and a dist/ subdirectory at depth 1. Also creates the
7 | #+ file ./src/scripts/projects.js, which declares a global projects
8 | #+ variable in JavaScript. The projects variable is an array of
9 | #+ objects containing name and live properties, where name is the
10 | #+ name for a folder located in ../ excluding the projects-index
11 | #+ folder, and live is a boolean indicating the presence of
12 | #+ distribution files in the ./src/projects directory corresponding
13 | #+ to the named project.
14 |
15 | # Remove the ./src/projects directory if it exists.
16 | if [ -d "./src/projects" ]
17 | then
18 | rm -r ./src/projects
19 | fi
20 |
21 | # Get all directories in ../, excluding hidden (dot) directories and
22 | #+ the projects-index directory, then trim the preceding ../ to get
23 | #+ just the directory names.
24 | names=$(find ../ -maxdepth 1 -mindepth 1 -type d | grep -v "projects-index" | grep -v "\/\." | grep -o "[^\.\./].*")
25 |
26 | # Let the user know the directory names found.
27 | echo
28 | echo "Projects found:"
29 | echo "$names"
30 | echo
31 |
32 | # For each directory name...
33 | for name in $names
34 | do
35 | # Check for src/ and dist/ subdirectories at depth 1.
36 | if [ -d "../$name/src" ] && [ -d "../$name/dist" ]
37 | then
38 | # Let the user know the distribution files are being added.
39 | echo "Adding: ./src/projects/$name"
40 | # Make the destination directory.
41 | mkdir -p ./src/projects/$name
42 | # Copy the contents of dist/ to ./src/projects/$name/.
43 | cp -r ../$name/dist/* ./src/projects/$name/
44 | # Check for only src/ subdirectories at depth 1.
45 | elif [ -d "../$name/src" ]
46 | then
47 | # Warn the user that the project's distribution files may need
48 | #+ to be built.
49 | >&2 echo "Warning: ../$name/dist is missing. Did you forget to build the project?"
50 | fi
51 | done
52 |
53 | # Create the beginning of the string to write to the projects.js
54 | #+ file.
55 | js="var projects = ["
56 |
57 | # For each directory name...
58 | for name in $names
59 | do
60 | # Create the beginning of a new JavaScript object in the js string
61 | #+ and add the name property and value, and the live property.
62 | js="$js{name: '$name', live:"
63 |
64 | # Check for the presence of distribution files for the named
65 | #+ project in ./src/projects/.
66 | if [ -d "./src/projects/$name" ]
67 | then
68 | # Set the live property to true and close the JavaScript object.
69 | js="$js true}, "
70 | # If there are no distribution files for the named project...
71 | else
72 | # Set the live property to false and close the JavaScript object.
73 | js="$js false}, "
74 | fi
75 | done
76 |
77 | # Trim the last ", " from the js string.
78 | js=${js%", "}
79 |
80 | # End the JavaScript array declaration.
81 | js="$js];"
82 |
83 | # Make sure the ./src/scripts directory exists.
84 | if ! [ -d "./src/scripts" ]
85 | then
86 | mkdir ./src/scripts
87 | fi
88 |
89 | # Create or recreate the projects.js file beginning with a
90 | #+ JavaScript comment that the file was automatically generated.
91 | echo "// Generated automatically by \`build-script\`." > ./src/scripts/projects.js
92 |
93 | # Append the js string to the projects.js file.
94 | echo $js >> ./src/scripts/projects.js
95 |
96 | # Inform the user that the projects.js file was created.
97 | echo "Created: ./src/scripts/projects.js"
98 | echo
99 |
100 | exit
101 |
--------------------------------------------------------------------------------
/projects-index/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Index | FEND Projects
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/projects-index/src/scripts/main.js:
--------------------------------------------------------------------------------
1 | (function(global) {
2 | // Use this variable to define the path to your source code. In my case, I'm
3 | // using a subdirectory of a single GitHub repo. In most cases, this will
4 | // instead be something like 'https://github.com/YOUR_NAME/{{project-name}}'.
5 | var sourcePath = 'https://github.com/Tempurturtul/udacity-fend-projects/tree/master/{{project-name}}';
6 |
7 | var window = global.window;
8 | var document = global.document;
9 |
10 | // On load, call init.
11 | window.addEventListener('load', init);
12 |
13 | /**
14 | * Initializes the site by adding links to projects.
15 | */
16 | function init() {
17 | var projects = global.projects;
18 | var ul = document.getElementsByClassName('project-links')[0];
19 |
20 | var path, li;
21 |
22 | // For each project in the projects array...
23 | projects.forEach(function(project) {
24 | // Create a new li element.
25 | li = document.createElement('li');
26 | li.classList.add('project-links__entry');
27 |
28 | // Build the source path.
29 | path = sourcePath.replace('{{project-name}}', project.name);
30 |
31 | // Escape any double-quotes in the source path (just in case).
32 | path = path.replace(/"/g, '\\"');
33 |
34 | // Add a source link to the li.
35 | li.innerHTML = '' +
36 | 'Source';
37 |
38 | // Add the project name to the li (and make it HTML safe just in case).
39 | li.innerHTML += '' +
40 | project.name
41 | .replace(/>/g, '>')
42 | .replace(/';
44 |
45 | // If the project has a live version...
46 | if (project.live) {
47 | // Build the project path.
48 | path = 'projects/' + project.name + '/';
49 |
50 | // Escape any double-quotes in the project path (just in case).
51 | path = path.replace(/"/g, '\\"');
52 |
53 | // Add a live version link to the li.
54 | li.innerHTML += '' +
55 | 'Live Site';
56 | }
57 |
58 | // Add the li element to the existing ul element.
59 | ul.appendChild(li);
60 | });
61 | }
62 |
63 | })(this);
64 |
--------------------------------------------------------------------------------
/projects-index/src/styles/main.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | html,
6 | body {
7 | height: 100%;
8 | }
9 |
10 | body {
11 | background: #222;
12 | color: #f5f5f5;
13 | font-size: 0.8em;
14 | }
15 |
16 | .container {
17 | min-height: 100%;
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: center;
21 | }
22 |
23 | .project-links {
24 | list-style: none;
25 | margin: 5px auto;
26 | padding: 0;
27 | }
28 |
29 | .project-links__entry {
30 | margin: 5px;
31 | font-family: monospace;
32 | white-space: nowrap;
33 | }
34 |
35 | .project-links__link {
36 | color: #b55;
37 | text-decoration: none;
38 | padding: 5px;
39 | display: inline-block;
40 | font-size: 1.2em;
41 | font-variant: small-caps;
42 | }
43 |
44 | .project-links__link:visited {
45 | color: #755;
46 | }
47 |
48 | .project-links__link:hover {
49 | color: #f55;
50 | }
51 |
52 | .project-name {
53 | font-size: 1.4em;
54 | }
55 |
56 | @media (min-width: 450px) {
57 | body {
58 | font-size: 1em;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------