From e391f8ce87835623dc0c649207e2682224352eea Mon Sep 17 00:00:00 2001 From: apple502j <33279053+apple502j@users.noreply.github.com> Date: Sat, 9 Nov 2019 00:33:06 +0900 Subject: [PATCH 01/20] Member updates in Credits --- src/views/credits/credits.jsx | 3 +- src/views/credits/people.json | 61 +++++++++++++---------------------- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/views/credits/credits.jsx b/src/views/credits/credits.jsx index 5aa272cbe..4e04ef822 100644 --- a/src/views/credits/credits.jsx +++ b/src/views/credits/credits.jsx @@ -145,7 +145,8 @@ const Credits = () => ( Christina Huang, Tony Hwang, Abdulrahman Idlbi, Randy Jou, Lily Kim, Tauntaun Kim, Saskia Leggett, Tim Mickel, Amon Millner, Ricarose Roque, Andrea Saxman, Jay Silver, Tammy Stern, Lis Sylvan, Hanako Tjia, Claudia - Urrea, Oren Zuckerman. + Urrea, Oren Zuckerman, Tina Quach, My Nguyen, Lisa O'Brien, Joel Gritter, + Linda Fernsel, Ellen Daoust, Julia Zimmerman.

diff --git a/src/views/credits/people.json b/src/views/credits/people.json index 986b4990c..51a45999c 100644 --- a/src/views/credits/people.json +++ b/src/views/credits/people.json @@ -39,11 +39,6 @@ "userId": 27383273, "name": "Karishma Chadha" }, - { - "userName": "SunnyDay4aBlueJay", - "userId": 24164779, - "name": "Ellen Daoust" - }, { "userName": "shruti", "userId": 3714374, @@ -54,11 +49,6 @@ "userId": 900283, "name": "Champika Fernando" }, - { - "userName": "LiFaytheGoblin", - "userId": 1048810, - "name": "Linda Fernsel" - }, { "userName": "dietbacon", "userId": 24137617, @@ -84,11 +74,6 @@ "userId": 49156, "name": "Mark Goff" }, - { - "userName": "GulpTea", - "userId": 26249744, - "name": "Joel Gritter" - }, { "userName": "codubee", "userId": 10866958, @@ -104,11 +89,6 @@ "userId": 22183577, "name": "Sean Hickey" }, - { - "userName": "theladynico", - "userId": 35550237, - "name": "Nicole Hughes" - }, { "userName": "sgcc_", "userId": 21986973, @@ -134,16 +114,6 @@ "userId": 24838781, "name": "Marian Muthui" }, - { - "userName": "me_win", - "userId": 7664502, - "name": "My Nguyen" - }, - { - "userName": "lob12", - "userId": 2860339, - "name": "Lisa O'Brien" - }, { "userName": "", "userId": "", @@ -164,11 +134,6 @@ "userId": 2286560, "name": "Carmelo Presicce" }, - { - "userName": "quacht", - "userId": 25500116, - "name": "Tina Quach" - }, { "userName": "mres", "userId": 167, @@ -235,8 +200,28 @@ "name": "Kathy Wu" }, { - "userName": "stymphalianbirb", - "userId": 2796185, - "name": "Julia Zimmerman" + "userName": "amylaser", + "userId": 17462181, + "name": "Amy Lee" + }, + { + "userName": "algorithmar", + "userId": 43013126, + "name": "Maren Vernon" + }, + { + "userName": "bluecrazie", + "userId": 50257624, + "name": "JT Galla" + }, + { + "userName": "Za-Chary", + "userId": 974363, + "name": "Zachary Deiman" + }, + { + "userName": "", + "userId": "", + "name": "Joan Fusco" } ] From cb3a9791449538401654ec9803b555304871bfb2 Mon Sep 17 00:00:00 2001 From: apple502j <33279053+apple502j@users.noreply.github.com> Date: Sat, 9 Nov 2019 00:38:33 +0900 Subject: [PATCH 02/20] Don't link when userName is blank, in credits --- src/views/credits/credits.jsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/views/credits/credits.jsx b/src/views/credits/credits.jsx index 4e04ef822..183d26afc 100644 --- a/src/views/credits/credits.jsx +++ b/src/views/credits/credits.jsx @@ -32,12 +32,20 @@ const Credits = () => ( key={`person-${index}`} >

- + {person.userName ? ( + + + + ) : ( + /* if userName is not given, there's no chance userId is given */ - + )}
{person.name} From 0bff005162b157b05496107d0fbbf1c3ca9f3007 Mon Sep 17 00:00:00 2001 From: apple502j <33279053+apple502j@users.noreply.github.com> Date: Thu, 14 Nov 2019 01:01:24 +0900 Subject: [PATCH 03/20] Member updates with latest info --- src/views/credits/people.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/views/credits/people.json b/src/views/credits/people.json index 51a45999c..30ca17e28 100644 --- a/src/views/credits/people.json +++ b/src/views/credits/people.json @@ -220,8 +220,13 @@ "name": "Zachary Deiman" }, { - "userName": "", - "userId": "", + "userName": "Mos20", + "userId": 52545208, "name": "Joan Fusco" + }, + { + "userName": "pixelmoth", + "userId": 2408962, + "name": "Jacy Edelman" } ] From 3f61b098894793d64de325b4c515ef8262f9ddcb Mon Sep 17 00:00:00 2001 From: apple502j <33279053+apple502j@users.noreply.github.com> Date: Tue, 19 Nov 2019 01:33:56 +0900 Subject: [PATCH 04/20] Remove jobs page --- src/views/jobs/jobs.jsx | 45 ----------- src/views/jobs/jobs.scss | 42 ---------- src/views/jobs/l10n.json | 8 -- src/views/jobs/moderator/moderator.jsx | 108 ------------------------- 4 files changed, 203 deletions(-) delete mode 100644 src/views/jobs/jobs.jsx delete mode 100644 src/views/jobs/jobs.scss delete mode 100644 src/views/jobs/l10n.json delete mode 100644 src/views/jobs/moderator/moderator.jsx diff --git a/src/views/jobs/jobs.jsx b/src/views/jobs/jobs.jsx deleted file mode 100644 index 37bcc9b35..000000000 --- a/src/views/jobs/jobs.jsx +++ /dev/null @@ -1,45 +0,0 @@ -const React = require('react'); -const render = require('../../lib/render.jsx'); -const FormattedMessage = require('react-intl').FormattedMessage; - -const Page = require('../../components/page/www/page.jsx'); - -require('./jobs.scss'); - -const Jobs = () => ( -
-
-
- -

-
-
- -
-
-

-

-

-
-
- -
-
-

- {/* */} - -
-
-
-); - -render(, document.getElementById('app')); diff --git a/src/views/jobs/jobs.scss b/src/views/jobs/jobs.scss deleted file mode 100644 index 8c07b5e57..000000000 --- a/src/views/jobs/jobs.scss +++ /dev/null @@ -1,42 +0,0 @@ -@import "../../colors"; - -.jobs { - .top { - img { - margin-bottom: 10px; - width: 100%; - } - } - - .middle { - margin: 20px 0; - background-color: $ui-gray; - padding: 40px 0; - width: 100%; - } - - .bottom { - width: 100%; - line-height: 200%; - - .thin-heading { - padding: 20px 0; - } - - p { - margin: auto; - width: 70%; - } - - ul { - padding-left: 0; - list-style: none; - - li { - span { - margin-left: 10px; - } - } - } - } -} diff --git a/src/views/jobs/l10n.json b/src/views/jobs/l10n.json deleted file mode 100644 index 9d1bebcdb..000000000 --- a/src/views/jobs/l10n.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "jobs.info": "With Scratch, young people from all backgrounds are learning to program their own interactive stories, games, and animations. Children and teens from around the world have created and shared more than 10 million projects in the rapidly-growing Scratch online community.", - "jobs.joinScratchTeam": "Join the Scratch Team!", - "jobs.openings": "Current Job Openings", - "jobs.titleQuestion": "Want to work on an innovative project that is transforming the ways young people create, share, and learn?", - "jobs.workEnvironment":"We’re seeking curious and motivated people to join our Scratch Team at the MIT Media Lab. We're a diverse group of educators, designers, and engineers, who work together in a playful, creative environment full of LEGO bricks, craft materials, and maker tools. We strongly value diversity, collaboration, and respect in the workplace.", - "jobs.nojobs":"We don't have any open positions at this time. Please check back soon for opportunities!" -} diff --git a/src/views/jobs/moderator/moderator.jsx b/src/views/jobs/moderator/moderator.jsx deleted file mode 100644 index eda225b7e..000000000 --- a/src/views/jobs/moderator/moderator.jsx +++ /dev/null @@ -1,108 +0,0 @@ -const React = require('react'); - -const Page = require('../../../components/page/www/page.jsx'); -const render = require('../../../lib/render.jsx'); - -const InformationPage = require('../../../components/informationpage/informationpage.jsx'); - -const Moderator = () => ( - -
-

- Interested in online communities, internet culture, and - working with kids? We're seeking community moderators - to work with the Scratch Team. Scratch - Moderators help keep Scratch a safe, trusted, and friendly - environment. -

-

- Scratch is a free service where young people learn to - program by creating interactive stories, games, and - animations which they can share to an online community. - Scratch has grown to more than 30 million registered - members (ages 8 and up) who create and share thousands - of projects each day. Moderators will gain valuable - experience working online with youth in a creative, - interest-driven setting. -

-

Responsibilities:

-
    -
  • - Promote the values and core ideas of the Scratch - project (such as inclusiveness, creative collaboration, - and constructive feedback) -
  • -
  • - Review reported users, projects, studios, and comments - for appropriateness on the Scratch website -
  • -
  • - Work with young people to help them understand what they - did that breaks our Community Guidelines -
  • -
  • - Determine when a person is or isn’t likely to be able to - participate constructively in the Scratch online community -
  • -
-
-

Qualifications:

-
    -
  • - Active participation in online communities, forums, - or social media -
  • -
  • - Excellent writing and communication skills -
  • -
  • - Comfortable learning to use new software and websites -
  • -
  • - Strong online research skills -
  • -
  • - Good judgement and ability to consider issues from - multiple perspectives -
  • -
  • - Able to work well independently, manage your time - well, and stay focused while working remotely -
  • -
  • - Able to work well as part of a team and participate - in group discussions -
  • -
  • - Not required, but would be nice: ability to read and - write in multiple languages (especially if one of those - languages is Japanese, Korean, or Russian!) -
  • -
-
-

- This position is part-time (10-15 hours per week), - flexible hours (this work can be done 24/7 and we - set a schedule which fits in with your life), - under contract with starting pay of $12 per hour. - All candidates must be at least 18 years old and - have authorization to work in the United States. -

-

(MIT Media Lab, Cambridge, MA or Remote)

-

- Send a copy of your resume, links to one or more of your online - presences, and cover letter to{' '} - jobs+moderator@scratch.mit.edu. -

-

- - Really want the gig? Create an - awesome Scratch project to introduce yourself, share - it on the Scratch website, and send us a link. - -

-
-
-); - -render(, document.getElementById('app')); From 6d9a7d20dad34abdaaaff4efcd442a61bc7217cf Mon Sep 17 00:00:00 2001 From: apple502j <33279053+apple502j@users.noreply.github.com> Date: Tue, 19 Nov 2019 01:34:19 +0900 Subject: [PATCH 05/20] Links and test changes --- src/components/footer/www/footer.jsx | 4 ++-- src/routes.json | 10 ++++------ src/views/developers/developers.jsx | 2 +- .../smoke-testing/test_footer_links.js | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/components/footer/www/footer.jsx b/src/components/footer/www/footer.jsx index ae31006c9..f533c8a3c 100644 --- a/src/components/footer/www/footer.jsx +++ b/src/components/footer/www/footer.jsx @@ -22,7 +22,7 @@ const Footer = props => (
- +
@@ -83,7 +83,7 @@ const Footer = props => (
- +
diff --git a/src/routes.json b/src/routes.json index 3b6621946..e0dcefc3d 100644 --- a/src/routes.json +++ b/src/routes.json @@ -148,18 +148,16 @@ "title": "Ideas" }, { - "name": "jobs", + "name": "jobs-redirect", "pattern": "^/jobs/?$", "routeAlias": "/jobs(/moderator)?/?$", - "view": "jobs/jobs", - "title": "Jobs" + "redirect": "https://www.scratchfoundation.org/opportunities/" }, { - "name": "jobs-moderator", + "name": "jobs-redirect2", "pattern": "^/jobs/moderator/?$", "routeAlias": "/jobs(/moderator)?/?$", - "view": "jobs/moderator/moderator", - "title": "Community Moderator" + "redirect": "https://www.scratchfoundation.org/opportunities/" }, { "name": "join", diff --git a/src/views/developers/developers.jsx b/src/views/developers/developers.jsx index f1c967144..858fde3cb 100644 --- a/src/views/developers/developers.jsx +++ b/src/views/developers/developers.jsx @@ -228,7 +228,7 @@ const Developers = () => ( id="developers.joinBody" values={{ jobsPageLink: ( - + ), diff --git a/test/integration-legacy/smoke-testing/test_footer_links.js b/test/integration-legacy/smoke-testing/test_footer_links.js index 0fa9ed80e..5a49d87b6 100644 --- a/test/integration-legacy/smoke-testing/test_footer_links.js +++ b/test/integration-legacy/smoke-testing/test_footer_links.js @@ -101,9 +101,9 @@ tap.test('clickCreditsLink', options, t => { // JOBS tap.test('clickJobsLink', options, t => { const linkText = 'Jobs'; - const expectedHref = '/jobs'; + const expectedUrl = 'https://www.scratchfoundation.org/opportunities/'; clickFooterLinks(linkText).then(url => { - t.equal(url.substr(-expectedHref.length), expectedHref); + t.equal(url, expectedUrl); t.end(); }); }); From af172aee7e437e46c0a11190a392342e51facf10 Mon Sep 17 00:00:00 2001 From: apple502j <33279053+apple502j@users.noreply.github.com> Date: Fri, 22 Nov 2019 01:00:13 +0900 Subject: [PATCH 06/20] Change routes a bit --- src/routes.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/routes.json b/src/routes.json index e0dcefc3d..b339bcb21 100644 --- a/src/routes.json +++ b/src/routes.json @@ -149,14 +149,7 @@ }, { "name": "jobs-redirect", - "pattern": "^/jobs/?$", - "routeAlias": "/jobs(/moderator)?/?$", - "redirect": "https://www.scratchfoundation.org/opportunities/" - }, - { - "name": "jobs-redirect2", - "pattern": "^/jobs/moderator/?$", - "routeAlias": "/jobs(/moderator)?/?$", + "pattern": "^/jobs/?(\\?.*)?$", "redirect": "https://www.scratchfoundation.org/opportunities/" }, { From af8740379332599599b5c3d9f2688431a8cd0c7a Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Sun, 24 Nov 2019 00:00:12 -0500 Subject: [PATCH 07/20] major reformat of README, with changes to indenting and testing instructions --- README.md | 203 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 154 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index a6d38d01a..cb423a9ab 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,70 @@ -## scratch-www +# scratch-www #### Standalone web client for Scratch [![Build Status](https://travis-ci.org/LLK/scratch-www.svg)](https://travis-ci.org/LLK/scratch-www) [![Coverage Status](https://coveralls.io/repos/github/LLK/scratch-www/badge.svg?branch=develop)](https://coveralls.io/github/LLK/scratch-www?branch=develop) -[![dependencies Status](https://david-dm.org/llk/scratch-www/status.svg)](https://david-dm.org/llk/scratch-www) -[![devDependencies Status](https://david-dm.org/llk/scratch-www/dev-status.svg)](https://david-dm.org/llk/scratch-www?type=dev) [![Greenkeeper badge](https://badges.greenkeeper.io/LLK/scratch-www.svg)](https://greenkeeper.io/) +[![Greenkeeper badge](https://badges.greenkeeper.io/LLK/scratch-www.svg)](https://greenkeeper.io/) -### Where am I? -Physically? No idea. +## Overview -Digitally? You’re at Scratch’s open source web client! +This is Scratch’s open source web client! This is the code for much of the [Scratch website](https://scratch.mit.edu). -We’re working to update the [Scratch website](https://scratch.mit.edu) to use a new codebase, contained in this repository. +In particular, this codebase includes code for: +* the "project page", which shows a playable version of the project, along with the project's title, description, comments, remixes and studios; this page operates in the background when you "See inside" a project +* the site's home page +* the Ideas page +* landing pages for various Scratch extensions, such as LEGO Mindstorms and Micro:bit +* the info page for Scratch Desktop +* and other pages such as Credits and FAQ. -We’re currently building Scratch using [React](https://facebook.github.io/react/) and [SCSS](http://sass-lang.com/documentation/file.SASS_REFERENCE.html). Here are some resources to help you get acquainted with how we’re working on the Scratch codebase: +## Understanding this codebase + +### Guides + +Here are some resources to help you get acquainted with how we’re working on the Scratch codebase: * [Style Guide](https://github.com/LLK/scratch-www/wiki/Style-Guide) * [Testing Guide](https://github.com/LLK/scratch-www/wiki/Testing-Guide-for-Bugfixes) * [Localization Guide](https://github.com/LLK/scratch-www/wiki/Localization-Guide) * [Map of the repository](https://github.com/LLK/scratch-www/wiki/Repo-Map) +### Core technologies + +Significant core technologies this codebase uses include: + +#### Development technologies + +* Node +* Webpack +* [React](https://facebook.github.io/react/) +* Redux +* [SCSS](http://sass-lang.com/documentation/file.SASS_REFERENCE.html) + +#### Testing technologies + +* Jest +* Enzyme +* Tap +* Selenium + +## Developing scratch-www ### Before Getting Started -* Make sure you have node (v4.2 or higher) and npm [installed](https://docs.npmjs.com/getting-started/installing-node) -We use npm (Node Package Manager) to maintain and update packages required to build the site. + +Make sure you have installed: +* [node](https://docs.npmjs.com/getting-started/installing-node): v4.2 or higher +* npm (Node Package Manager): used to maintain and update packages required to build the site ### Update Packages -It's important to make sure that all of the dependencies are up to date because the scratch-www code only works with specific versions of the dependencies. You can update the packages by running this command: + +It's important to make sure that all of the dependencies are up to date because the +scratch-www code only works with specific versions of the dependencies. +You can update the packages by using the command: ```bash npm install ``` -### To Build -To compile the source code into HTML and JavaScript bundles browsers can read, run this command: - -```bash -npm run build -``` -If you want to run a server that rebuilds the files as you edit them, skip to the To Run section below. - #### Warnings during npm install These warnings can be safely ignored: @@ -52,34 +77,54 @@ npm WARN react-addons-test-utils@0.14.7 requires a peer of react@^0.14.7 but non npm WARN react-dom@0.14.8 requires a peer of react@^0.14.8 but none was installed. ``` -These currently exist in static/js/lib +These currently exist in static/js/lib . -### To Run -If you would like to create a temporary version of the site on your machine that you can access through your web browser run the command below. Building (see To Build above) is not necessary for this step and the temporary server can be turned off (see To Stop below). +### To Build -The intl directory must be built separately with the `npm run translate` line below in order for the text to appear properly. +To compile the source code into HTML and JavaScript bundles browsers can read, you can create +a temporary version of the site on your machine that you can access through your web browser. + +You can either "build" the site a single time, by running: + +```bash +npm run build +``` + +Or, you can run a server that rebuilds the files as you edit them, by running the commands: ```bash npm run translate npm start ``` -The site hosted on your local machine can now be accessed by a web browser by entering localhost:8333 into your web browser. +*NOTE: `npm run translate` builds the intl directory. The site will build fine without it, +but translatable text strings will not show up correctly until you have built intl.* -During development, `npm start` watches any update you make to files in either `./static` or `./src` and triggers a rebuild of the project. In development, the build is stored in memory, and not served from the `./build` directory. +During development, `npm start` watches any update you make to files in either +`./static` or `./src` and triggers a rebuild of the project. In development, +the build is stored in memory, and not served from the `./build` directory. + +### Viewing the local site + +Once you have built the local site, using either `npm run build` or `npm start`, +the site hosted on your local machine can be accessed by a web browser by entering +`localhost:8333` into your browser's address bar. + +### Troubleshooting When running `npm start`, here are some important log messages to keep an eye out for: * `webpack: bundle is now VALID.` – The bundle has been loaded into memory and is now viewable in the browser. This will show up both once `npm start` has completed its setup, and also once updates you make to files have been re-compiled for viewing in the browser. * `webpack: bundle is now INVALID.` – If you see this, then it means you have made updates to files that are still being compiled for browser viewing. Pages will still be viewable, but they will not see any updates you made yet. -Once running, open `http://localhost:8333` in your browser. If you wish to have the server reload automatically, you can install either [nodemon](https://github.com/remy/nodemon) or [forever](https://github.com/foreverjs/forever). +### To stop npm -### To stop -To stop the process that is making the site available to your web browser (created above in To Start) use `^C`. +To stop the `npm start` process which is making the site available to your web browser +(created above in "To Build"), use `^C` (control-c) in the terminal. #### Configuration -`npm start` can be configured with the following environment variables +`npm start` can be configured with the following environment variables, by setting them in +the beginning of the command, before `npm start`: | Variable | Default | Description | | --------------- | ---------------------------------- | ---------------------------------------------- | @@ -93,33 +138,87 @@ To stop the process that is making the site available to your web browser (creat | `NODE_ENV` | `null` | If not `production`, app acts like development | | `PORT` | `8333` | Port for devserver (http://localhost:XXXX) | -**NOTE:** Because by default `API_HOST=https://api.scratch.mit.edu`, please be aware that, by default, you will be seeing and interacting with real data on the Scratch website. +*NOTE: Because by default `API_HOST=https://api.scratch.mit.edu`, please be aware that, by default, you will be seeing and interacting with real data on the Scratch website.* + +## Tests + +### Unit tests + +Most of our unit tests run using Jest, but older unit tests use the TAP framework. + +#### Run all tests + +To build the application and run all unit and localization tests, use the command: -### Unit Tests -To run: ```bash npm test ``` -This will build the application and run the unit and localization tests. Some of the tests are run using the TAP framework and others run using Jest. + +#### Run one test + +To run a single unit test file from the command-line using Jest, use the command: + +```bash +node_modules/.bin/jest ./test/unit/PATH/TO/FILENAME.test.js +``` + +*NOTE: replace `PATH/TO/FILENAME` with the actual path to the file you wish to run.* ### Integration tests -We are transitioning from using TAP to using Jest as our testing framework so for the time being our tests run using both. + +Our integration tests assume that a larger environment is running than just scratch-www +on its own; for instance, many require that a test user be able to log in to the site, +which requires backend and database support. + +By default, tests run against our Staging instance, but you can pass in a different +location with the ROOT_URL environment variable (see below) if you want to run the +tests against another location--for instance, your local build. + +We are transitioning from using TAP to using Jest as our testing framework, +so for the time being our tests run using both. #### Running the tests -* By default, tests run against our Staging instance, but you can pass in a different location with the ROOT_URL environment variable (see below) if you want to run the tests against e.g. your local build +To run all integration tests from the command-line: -#### Running the tests -* Run all tests from the command-line: `$ SMOKE_USERNAME=username SMOKE_PASSWORD=password ROOT_URL=https://scratch.mit.edu npm run test:integration` -* To run a single file from the command-line using TAP: `$ SMOKE_USERNAME=username SMOKE_PASSWORD=password ROOT_URL=https://scratch.mit.edu node_modules/.bin/tap ./test/integration-legacy/smoke-testing/filename.js --timeout=3600` - * The timeout var is for the length of the entire tap test-suite; if you are getting a timeout error, you may need to adjust this value (some of the Selenium tests take a while to run) -* To run a single file from the command-line using Jest: `$ SMOKE_USERNAME=username SMOKE_PASSWORD=password ROOT_URL=https://scratch.mit.edu node_modules/.bin/jest ./test/integration/filename.test.js` +```bash +SMOKE_USERNAME=username SMOKE_PASSWORD=password ROOT_URL=https://scratch.mit.edu npm run test:integration +``` + +To run a single file from the command-line using Jest: + +```bash +SMOKE_USERNAME=username SMOKE_PASSWORD=password ROOT_URL=https://scratch.mit.edu node_modules/.bin/jest ./test/integration/filename.test.js +``` + +To run a single file from the command-line using TAP: + +```bash +SMOKE_USERNAME=username SMOKE_PASSWORD=password ROOT_URL=https://scratch.mit.edu node_modules/.bin/tap ./test/integration-legacy/smoke-testing/filename.js -R classic --no-coverage --timeout=3600 +``` + +* the `-R classic` makes tap use the old reporting style, which avoids an error with the "nyc" package +* `--no-coverage` is because we do not use the coverage-tracking feature of tap +* the `timeout` argument is for the length of the entire tap test-suite; if you are getting a timeout error, you may need to adjust this value (some of the Selenium tests take a while to run) #### Running Remote tests -* TAP tests can be run using Saucelabs, an online service that can test browser/os combinations remotely. Currently all tests are written for use for chrome on mac. -* You will need a Saucelabs account in order to use it for testing. To find the Access Key, click your username and select User Settings from the dropdown menu. Near the bottom of the page is your access key that you can copy and use in the command line. -* Currently Jest tests will not run with Saucelabs. -* To run tests using saucelabs run this command `$ SMOKE_USERNAME=username SMOKE_PASSWORD=password SAUCE_USERNAME=saucelabsUsername SAUCE_ACCESS_KEY=saucelabsAccessKey ROOT_URL=https://scratch.mit.edu npm run test:integration:remote` + +Integration tests can be run using Saucelabs, an online service that can test multiple +browser/OS combinations remotely. (Currently, all tests are written for use for Chrome on Mac). + +You will need a Saucelabs account in order to use it for testing. If you have one, you can +find your Access Key: +1. click your username +1. select "User Settings" from the dropdown menu +1. near the bottom of the page is your access key + +To run tests using Saucelabs, run the command: + +```bash +SMOKE_USERNAME=username SMOKE_PASSWORD=password SAUCE_USERNAME=saucelabsUsername SAUCE_ACCESS_KEY=saucelabsAccessKey ROOT_URL=https://scratch.mit.edu npm run test:integration:remote +``` + +*NOTE: Currently Jest tests will not run with Saucelabs.* #### Configuration @@ -133,7 +232,7 @@ We are transitioning from using TAP to using Jest as our testing framework so fo | `SAUCE_USERNAME` | `None` | Username for your Sauce Labs account | | `SAUCE_ACCESS_KEY` | `None` | Access Key for Sauce Labs found under User Settings | -### To Deploy +## To Deploy Deploying to staging or production will upload code to S3 and configure Fastly. @@ -155,19 +254,25 @@ npm run build && npm run deploy | `S3_BUCKET_NAME` | `''` | S3 bucket name to deploy into | -### Current issues with the development +## Current issues with developing scratch-www + We're currently in the process of transitioning into this web client from Scratch's existing structure. As we transition, there are going to be some issues along the way that relate to how this client needs to interact with the existing infrastructure to work properly in production. -#### FALLBACK +### FALLBACK + On top of migrating to using this as our web client, Scratch is also transitioning into using a new API backend, Scratch REST API. As that is also currently in development and incomplete, we are set up to fall back to using existing Scratch endpoints if an API endpoint does not exist – which is where the `FALLBACK` comes in. Most of the issues we have currently revolve around the use of `FALLBACK`. This variable is used to specify what URL to fall back onto should a request fail within the context of this web client, or when using the `API_HOST`. If not specified in the process, it will not be used, and any request that is not made through the web client or the API will be unreachable. Setting `FALLBACK=https://scratch.mit.edu` allows the web client to retrieve data from the Scratch website in your development environment. However, because of security concerns, trying to send data to Scratch through your development environment won't work. This means the following things will be broken for the time being: + * Login on the splash page (*In the process of being fixed*) * Some update attempts to production data made through a development version of the web client Additionally, if you set `FALLBACK=https://scratch.mit.edu`, be aware that clicking on links to parts of the website not yet migrated over (currently such as `Explore`, `Discuss`, `Profile`, etc.) will take you to the Scratch website itself. -#### Windows -Some users have experienced difficulties when trying to get our web client to work on Windows. One solution could be to use [Cygwin](https://www.cygwin.com/). If that doesn't work, you might want to use [Wubi](https://wiki.ubuntu.com/WubiGuide) (Windows XP, Vista, 7) or [Wubiuefi](https://github.com/hakuna-m/wubiuefi) (Windows 8 or higher). Wubi(uefi) is a Windows Installer for Ubuntu that allows you to have Ubuntu and Windows on one disk, without the need of an extra partition. +### Windows + +Some users have experienced difficulties when trying to get our web client to work on Windows. + +One solution could be to use [Cygwin](https://www.cygwin.com/). If that doesn't work, you might want to use [Wubi](https://wiki.ubuntu.com/WubiGuide) (Windows XP, Vista, 7) or [Wubiuefi](https://github.com/hakuna-m/wubiuefi) (Windows 8 or higher). Wubi(uefi) is a Windows Installer for Ubuntu that allows you to have Ubuntu and Windows on one disk, without the need of an extra partition. From 03576f0707d4eddfb84cce206d67a79e9d5e2155 Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Sun, 1 Dec 2019 23:05:43 -0500 Subject: [PATCH 08/20] Corrected list of scratchr2 pages; added intro text --- README.md | 59 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index cb423a9ab..6b045dee5 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,47 @@ In particular, this codebase includes code for: * the "project page", which shows a playable version of the project, along with the project's title, description, comments, remixes and studios; this page operates in the background when you "See inside" a project * the site's home page * the Ideas page -* landing pages for various Scratch extensions, such as LEGO Mindstorms and Micro:bit +* landing pages for various Scratch extensions, such as LEGO MINDSTORMS and micro:bit * the info page for Scratch Desktop * and other pages such as Credits and FAQ. +### How this fits in with other Scratch repos + +The scratch-www project has lots of aspects of its design that are particular to our backend systems. +To use it for your own project, you would have to look at all the places it makes backend calls, and +create your own backend systems to perform those functions. + +The [scratch-gui](https://github.com/LLK/scratch-gui) project, on the other hand, is designed to be +able to be used by anyone, without needing to create backend systems, though it also can support +backend systems for project and asset saving. + +### Contributing + +We welcome your contributions to this codebase! You may want to start by browsing [the current +list of open issues labeled "help wanted"](https://github.com/LLK/scratch-www/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22). + +Contributing to scratch-www can be more difficult than contributing to +[scratch-gui](https://github.com/LLK/scratch-gui). This is because scratch-gui can be run on its +own, without needing any other services to be running, while scratch-www needs to communicate +with several backend systems that the Scratch team runs (see "How this fits in with other Scratch +repos" above). If you are new to contributing to Scratch's source code, we suggest you start +by becoming familiar with scratch-gui and its [list of open issues labeled "help +wanted"](https://github.com/LLK/scratch-gui/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22). + +To contribute, please follow the [standard steps for contributing to a project on +GitHub](https://github.com/firstcontributions/first-contributions). + +### Using scratch-www for your own project + +If you're thinking of using scratch-www for your own project, you might want to think about what parts +of the codebase you really need for your project. Is it the layout of the project page? Is it +the way the project page manages the information it passes to the scratch-gui instance? You may wish +to use just those parts, and work out the rest your own way. + +### License + +See the [LICENSE](https://github.com/LLK/scratch-www/blob/master/LICENSE) file in this repo. + ## Understanding this codebase ### Guides @@ -34,18 +71,20 @@ Significant core technologies this codebase uses include: #### Development technologies -* Node -* Webpack +* [Node](https://nodejs.org/) +* [Webpack](https://webpack.js.org/) * [React](https://facebook.github.io/react/) -* Redux -* [SCSS](http://sass-lang.com/documentation/file.SASS_REFERENCE.html) +* [Redux](https://redux.js.org/) +* [Sass](http://sass-lang.com/documentation/file.SASS_REFERENCE.html) #### Testing technologies -* Jest -* Enzyme -* Tap -* Selenium +Our tests use: + +* [Jest](https://jestjs.io/) (we are writing most new tests in Jest) +* [Tap](https://node-tap.org/) (we are moving away from using Tap, but many tests still use it) +* [Enzyme](https://airbnb.io/enzyme/) +* [Selenium](https://selenium.dev/) ## Developing scratch-www @@ -269,7 +308,7 @@ Setting `FALLBACK=https://scratch.mit.edu` allows the web client to retrieve dat * Login on the splash page (*In the process of being fixed*) * Some update attempts to production data made through a development version of the web client -Additionally, if you set `FALLBACK=https://scratch.mit.edu`, be aware that clicking on links to parts of the website not yet migrated over (currently such as `Explore`, `Discuss`, `Profile`, etc.) will take you to the Scratch website itself. +Additionally, if you set `FALLBACK=https://scratch.mit.edu`, be aware that clicking on links to parts of the website not yet migrated over (currently such as `Discuss`, `Profile`, `My Stuff`, etc.) will take you to the Scratch website itself. ### Windows From bfbeb6645ac85ef3a566f720180e1214fa716d33 Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Mon, 2 Dec 2019 09:19:20 -0500 Subject: [PATCH 09/20] changes to Windows and Node instructions per adroitwhiz suggestions --- README.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6b045dee5..8e40cbf6a 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ Our tests use: ### Before Getting Started Make sure you have installed: -* [node](https://docs.npmjs.com/getting-started/installing-node): v4.2 or higher +* [node](https://docs.npmjs.com/getting-started/installing-node): version 8 or higher * npm (Node Package Manager): used to maintain and update packages required to build the site ### Update Packages @@ -292,6 +292,17 @@ npm run build && npm run deploy | `AWS_SECRET_ACCESS_KEY` | `''` | AWS secret access key for S3 | | `S3_BUCKET_NAME` | `''` | S3 bucket name to deploy into | +## Windows + +For development on Windows, you will probably need to use a program that provides you a Unix interface. + +There are several options for doing this: + +* Use the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to run Linux inside Windows +* Use [Cygwin](https://www.cygwin.com/) +* Use Wubi, a Windows Installer for Ubuntu that allows you to have Ubuntu and Windows on one disk, without the need of an extra partition. There is a [version for Windows XP, Vista, or 7](https://wiki.ubuntu.com/WubiGuide) and a [version for Windows 8 or higher](https://github.com/hakuna-m/wubiuefi). + +In addition, you will need to install Node; [here are instructions for installing Node on WSL](https://docs.microsoft.com/en-us/windows/nodejs/setup-on-wsl2#install-nvm-nodejs-and-npm). ## Current issues with developing scratch-www @@ -299,7 +310,7 @@ We're currently in the process of transitioning into this web client from Scratc ### FALLBACK -On top of migrating to using this as our web client, Scratch is also transitioning into using a new API backend, Scratch REST API. As that is also currently in development and incomplete, we are set up to fall back to using existing Scratch endpoints if an API endpoint does not exist – which is where the `FALLBACK` comes in. +On top of migrating to using this as our web client, Scratch is also transitioning into using a new API backend, Scratch REST API (closed-source). As that is also currently in development and incomplete, we are set up to fall back to using existing Scratch endpoints if an API endpoint does not exist – which is where the `FALLBACK` comes in. Most of the issues we have currently revolve around the use of `FALLBACK`. This variable is used to specify what URL to fall back onto should a request fail within the context of this web client, or when using the `API_HOST`. If not specified in the process, it will not be used, and any request that is not made through the web client or the API will be unreachable. @@ -309,9 +320,3 @@ Setting `FALLBACK=https://scratch.mit.edu` allows the web client to retrieve dat * Some update attempts to production data made through a development version of the web client Additionally, if you set `FALLBACK=https://scratch.mit.edu`, be aware that clicking on links to parts of the website not yet migrated over (currently such as `Discuss`, `Profile`, `My Stuff`, etc.) will take you to the Scratch website itself. - -### Windows - -Some users have experienced difficulties when trying to get our web client to work on Windows. - -One solution could be to use [Cygwin](https://www.cygwin.com/). If that doesn't work, you might want to use [Wubi](https://wiki.ubuntu.com/WubiGuide) (Windows XP, Vista, 7) or [Wubiuefi](https://github.com/hakuna-m/wubiuefi) (Windows 8 or higher). Wubi(uefi) is a Windows Installer for Ubuntu that allows you to have Ubuntu and Windows on one disk, without the need of an extra partition. From 9e38129fa902de62bea0cf68cd1efe60cbec7af8 Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Mon, 2 Dec 2019 14:50:29 -0500 Subject: [PATCH 10/20] removed unnecessary section about using in your own project --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 8e40cbf6a..fecc70902 100644 --- a/README.md +++ b/README.md @@ -43,13 +43,6 @@ wanted"](https://github.com/LLK/scratch-gui/issues?q=is%3Aopen+is%3Aissue+label% To contribute, please follow the [standard steps for contributing to a project on GitHub](https://github.com/firstcontributions/first-contributions). -### Using scratch-www for your own project - -If you're thinking of using scratch-www for your own project, you might want to think about what parts -of the codebase you really need for your project. Is it the layout of the project page? Is it -the way the project page manages the information it passes to the scratch-gui instance? You may wish -to use just those parts, and work out the rest your own way. - ### License See the [LICENSE](https://github.com/LLK/scratch-www/blob/master/LICENSE) file in this repo. From dba2c9b452764b793bce032c1612bfa2915c1eb1 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" <23040076+greenkeeper[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2019 14:45:47 +0000 Subject: [PATCH 11/20] chore(package): update scratch-gui to version 0.1.0-prerelease.20191204143415 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fb3e7dad1..f966301e6 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "redux-mock-store": "^1.2.3", "redux-thunk": "2.0.1", "sass-loader": "6.0.6", - "scratch-gui": "0.1.0-prerelease.20191120175131", + "scratch-gui": "0.1.0-prerelease.20191204143415", "scratch-l10n": "latest", "selenium-webdriver": "3.6.0", "slick-carousel": "1.6.0", From 85ab0f35aaf694ca8a75decacc04c718d6ccdbe4 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" <23040076+greenkeeper[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2019 14:45:52 +0000 Subject: [PATCH 12/20] chore(package): update lockfile package-lock.json --- package-lock.json | 204 ++++++++++++++++++++++++---------------------- 1 file changed, 105 insertions(+), 99 deletions(-) diff --git a/package-lock.json b/package-lock.json index 305f8501d..0fcf1ddb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,13 +5,13 @@ "requires": true, "dependencies": { "@babel/cli": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.7.0.tgz", - "integrity": "sha512-jECEqAq6Ngf3pOhLSg7od9WKyrIacyh1oNNYtRXNn+ummSHCTXBamGywOAtiae34Vk7zKuQNnLvo2BKTMCoV4A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.7.4.tgz", + "integrity": "sha512-O7mmzaWdm+VabWQmxuM8hqNrWGGihN83KfhPUzp2lAW4kzIMwBxujXkZbD4fMwKMYY9FXTbDvXsJqU+5XHXi4A==", "dev": true, "requires": { "chokidar": "^2.1.8", - "commander": "^2.8.1", + "commander": "^4.0.1", "convert-source-map": "^1.1.0", "fs-readdir-recursive": "^1.1.0", "glob": "^7.0.0", @@ -110,6 +110,12 @@ "upath": "^1.1.1" } }, + "commander": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.0.1.tgz", + "integrity": "sha512-IPF4ouhCP+qdlcmCedhxX4xiGBPyigb8v5NeUp+0LyhwLgxMqyp3S0vl7TAPfS/hiP7FC3caI/PB9lTmP8r1NA==", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -477,18 +483,18 @@ } }, "@babel/core": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.2.tgz", - "integrity": "sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.4.tgz", + "integrity": "sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helpers": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.7.2", + "@babel/generator": "^7.7.4", + "@babel/helpers": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "json5": "^2.1.0", @@ -508,84 +514,84 @@ } }, "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", + "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", "dev": true, "requires": { - "@babel/types": "^7.7.2", + "@babel/types": "^7.7.4", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", + "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/helper-get-function-arity": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", + "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", "dev": true, "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", + "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", "dev": true, "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz", + "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==", "dev": true }, "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", + "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", + "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", + "@babel/generator": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", + "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -721,86 +727,86 @@ } }, "@babel/helpers": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.0.tgz", - "integrity": "sha512-VnNwL4YOhbejHb7x/b5F39Zdg5vIQpUUNzJwx0ww1EcVRt41bbGRZWhAURrfY32T5zTT3qwNOQFWpn+P0i0a2g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", + "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", "dev": true, "requires": { - "@babel/template": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" }, "dependencies": { "@babel/generator": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.2.tgz", - "integrity": "sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", + "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", "dev": true, "requires": { - "@babel/types": "^7.7.2", + "@babel/types": "^7.7.4", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", + "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/helper-get-function-arity": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", + "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", "dev": true, "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", + "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", "dev": true, "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.7.4" } }, "@babel/parser": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.3.tgz", - "integrity": "sha512-bqv+iCo9i+uLVbI0ILzKkvMorqxouI+GbV13ivcARXn9NNEabi2IEz912IgNpT/60BNXac5dgcfjb94NjsF33A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz", + "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==", "dev": true }, "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", + "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/traverse": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.2.tgz", - "integrity": "sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", + "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.2", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.2", - "@babel/types": "^7.7.2", + "@babel/generator": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -818,9 +824,9 @@ } }, "@babel/types": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.2.tgz", - "integrity": "sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", + "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -15653,15 +15659,15 @@ } }, "scratch-gui": { - "version": "0.1.0-prerelease.20191120175131", - "resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20191120175131.tgz", - "integrity": "sha512-eNr4hNLW4EI3/5WO5w2/7fzhKL8h3imHS5WbjP8SQMS3CIGrE9un7e30RepR0jT9VnsWoNL7nNMLVclBZpeoLA==", + "version": "0.1.0-prerelease.20191204143415", + "resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20191204143415.tgz", + "integrity": "sha512-tFnNw7Dj/BthiW5aPXFCGUMNPw5N3RdSm+9khP9bNxtPA0tKZp72tR94oXztX4kSO/atRMJk8sryhPeoB+Sg4g==", "dev": true }, "scratch-l10n": { - "version": "3.6.20191120161253", - "resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.6.20191120161253.tgz", - "integrity": "sha512-M315ak1Y/VF+0Yv2nrSlQM8qIEV2MlkPC2VVHz7/Ag64ib6PJBuPNLXmQ26u4ToDxA97ouzgBDWUoupJS3n96g==", + "version": "3.6.20191204142956", + "resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.6.20191204142956.tgz", + "integrity": "sha512-3IKAbV9PDEpYrvnyZrHclyibGGqTnr+/eo98pg27lk46Vo2hdH92SBV/PntOkz5r88A51tqf+vJq1VPRHslXZw==", "dev": true, "requires": { "@babel/cli": "^7.1.2", From 8c4422802c7073af52cbf7d6abcd154a51226fe0 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" <23040076+greenkeeper[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2019 15:10:58 +0000 Subject: [PATCH 13/20] chore(package): update scratch-gui to version 0.1.0-prerelease.20191204144806 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f966301e6..767a53624 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "redux-mock-store": "^1.2.3", "redux-thunk": "2.0.1", "sass-loader": "6.0.6", - "scratch-gui": "0.1.0-prerelease.20191204143415", + "scratch-gui": "0.1.0-prerelease.20191204144806", "scratch-l10n": "latest", "selenium-webdriver": "3.6.0", "slick-carousel": "1.6.0", From a5f347704d37c924d8f7f9094db28b6b24abe530 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" <23040076+greenkeeper[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2019 15:11:02 +0000 Subject: [PATCH 14/20] chore(package): update lockfile package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0fcf1ddb3..54e6bae4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15659,9 +15659,9 @@ } }, "scratch-gui": { - "version": "0.1.0-prerelease.20191204143415", - "resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20191204143415.tgz", - "integrity": "sha512-tFnNw7Dj/BthiW5aPXFCGUMNPw5N3RdSm+9khP9bNxtPA0tKZp72tR94oXztX4kSO/atRMJk8sryhPeoB+Sg4g==", + "version": "0.1.0-prerelease.20191204144806", + "resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20191204144806.tgz", + "integrity": "sha512-GwVOCJPPBaMsw0ulId/Dxv/vrJ1T4GCZZQk49hlN7gpZozM5HQAYkz9DzZCGnwrwTFFJhI0biqQ/SOLfpe5bTQ==", "dev": true }, "scratch-l10n": { From b89fe1a985d5e9873f59361da7168271c9ffc616 Mon Sep 17 00:00:00 2001 From: picklesrus Date: Wed, 4 Dec 2019 16:28:23 -0500 Subject: [PATCH 15/20] Add recognition text and links to the bottom of the page. Adds a prop to the Page component so each page can say whether or not it wants them to appear. --- src/components/page/www/donor-recognition.jsx | 36 ++++++++++++++++++ .../page/www/donor-recognition.scss | 38 +++++++++++++++++++ src/components/page/www/page.jsx | 12 +++++- src/l10n.json | 3 ++ src/views/credits/credits.jsx | 5 ++- src/views/splash/splash.jsx | 6 ++- test/unit/components/page.test.jsx | 21 ++++++++++ 7 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 src/components/page/www/donor-recognition.jsx create mode 100644 src/components/page/www/donor-recognition.scss create mode 100644 test/unit/components/page.test.jsx diff --git a/src/components/page/www/donor-recognition.jsx b/src/components/page/www/donor-recognition.jsx new file mode 100644 index 000000000..033e8c3fe --- /dev/null +++ b/src/components/page/www/donor-recognition.jsx @@ -0,0 +1,36 @@ +const FormattedMessage = require('react-intl').FormattedMessage; +const injectIntl = require('react-intl').injectIntl; +const React = require('react'); + +require('./donor-recognition.scss'); + +const DonorRecognition = () => ( +
+
+ + + + ) + }} + /> +
+
+ +
+
+); + +module.exports = injectIntl(DonorRecognition); diff --git a/src/components/page/www/donor-recognition.scss b/src/components/page/www/donor-recognition.scss new file mode 100644 index 000000000..99e5bb87b --- /dev/null +++ b/src/components/page/www/donor-recognition.scss @@ -0,0 +1,38 @@ +@import "../../../colors"; +@import "../../../frameless"; + +#donor { + color: $type-gray; + font-size: .875rem; + line-height: 1.5em; + background-color: $ui-gray; + padding-bottom: 2.5rem; + padding-top: 1rem; + #donor-text { + text-align: center; + width: $cols12; + margin: 0 auto; + } +} + +@media only screen and (min-width: $tabletPortrait) and (max-width: $desktop) { + #donor { + #donor-text { + width: $cols11; + } + } +} +@media only screen and (min-width: $mobile) and (max-width: $tabletPortrait) { + #donor { + #donor-text { + width: $cols6; + } + } +} +@media only screen and (max-width: $mobile) { + #donor { + #donor-text { + width: $cols4; + } + } +} diff --git a/src/components/page/www/page.jsx b/src/components/page/www/page.jsx index 77f3712ba..23676a325 100644 --- a/src/components/page/www/page.jsx +++ b/src/components/page/www/page.jsx @@ -4,11 +4,13 @@ const React = require('react'); const Navigation = require('../../navigation/www/navigation.jsx'); const Footer = require('../../footer/www/footer.jsx'); +const DonorRecognition = require('./donor-recognition.jsx'); const ErrorBoundary = require('../../errorboundary/errorboundary.jsx'); const Page = ({ children, - className + className, + showDonorRecognition }) => (
@@ -26,13 +28,19 @@ const Page = ({ + {showDonorRecognition && +
+ +
+ }
); Page.propTypes = { children: PropTypes.node, - className: PropTypes.string + className: PropTypes.string, + showDonorRecognition: PropTypes.bool }; module.exports = Page; diff --git a/src/l10n.json b/src/l10n.json index 840295d2c..a1a17c168 100644 --- a/src/l10n.json +++ b/src/l10n.json @@ -122,6 +122,9 @@ "footer.discuss": "Discussion Forums", "footer.scratchFamily": "Scratch Family", + "footer.donorRecognition": "Scratch is available for free, thanks to generous support from our {donorLink}. We are grateful to our Founding Partners:", + "footer.donors": "donors", + "footer.donorList": "{donor1}, {donor2}, and {donor3}", "form.validationRequired": "This field is required", diff --git a/src/views/credits/credits.jsx b/src/views/credits/credits.jsx index 5aa272cbe..05d7abe08 100644 --- a/src/views/credits/credits.jsx +++ b/src/views/credits/credits.jsx @@ -46,7 +46,10 @@ const Credits = () => ( ))} -
+

diff --git a/src/views/splash/splash.jsx b/src/views/splash/splash.jsx index 8910c0ce2..2c92600b6 100644 --- a/src/views/splash/splash.jsx +++ b/src/views/splash/splash.jsx @@ -271,7 +271,11 @@ const ConnectedSplash = connect( )(Splash); render( - , + + + , document.getElementById('app'), {splash: splashActions.splashReducer} ); diff --git a/test/unit/components/page.test.jsx b/test/unit/components/page.test.jsx new file mode 100644 index 000000000..1fecbf52e --- /dev/null +++ b/test/unit/components/page.test.jsx @@ -0,0 +1,21 @@ +const React = require('react'); +const {shallowWithIntl} = require('../../helpers/intl-helpers.jsx'); +const Page = require('../../../src/components/page/www/page.jsx'); + +describe('Page', () => { + test('Do not show donor recognition', () => { + const component = shallowWithIntl( + + ); + expect(component.find('#donor')).toHaveLength(0); + }); + + test('Show donor recognition', () => { + const component = shallowWithIntl( + + ); + expect(component.find('#donor')).toHaveLength(1); + }); +}); From 8f01525c321d345adea50cd2c928c3a04cc5a90e Mon Sep 17 00:00:00 2001 From: picklesrus Date: Thu, 5 Dec 2019 08:32:55 -0500 Subject: [PATCH 16/20] Add missing . --- src/l10n.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/l10n.json b/src/l10n.json index a1a17c168..5ec674823 100644 --- a/src/l10n.json +++ b/src/l10n.json @@ -124,7 +124,7 @@ "footer.scratchFamily": "Scratch Family", "footer.donorRecognition": "Scratch is available for free, thanks to generous support from our {donorLink}. We are grateful to our Founding Partners:", "footer.donors": "donors", - "footer.donorList": "{donor1}, {donor2}, and {donor3}", + "footer.donorList": "{donor1}, {donor2}, and {donor3}.", "form.validationRequired": "This field is required", From 1d8ba39f8f3dbd42e03deb7549f545901db5ce8e Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" <23040076+greenkeeper[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2019 14:45:51 +0000 Subject: [PATCH 17/20] chore(package): update scratch-gui to version 0.1.0-prerelease.20191205143447 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 767a53624..fcf1a976b 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "redux-mock-store": "^1.2.3", "redux-thunk": "2.0.1", "sass-loader": "6.0.6", - "scratch-gui": "0.1.0-prerelease.20191204144806", + "scratch-gui": "0.1.0-prerelease.20191205143447", "scratch-l10n": "latest", "selenium-webdriver": "3.6.0", "slick-carousel": "1.6.0", From a0810f085204b1f1f9d4bede8e8387df69bc8e5f Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" <23040076+greenkeeper[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2019 14:45:56 +0000 Subject: [PATCH 18/20] chore(package): update lockfile package-lock.json --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 54e6bae4c..ccc456877 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15659,9 +15659,9 @@ } }, "scratch-gui": { - "version": "0.1.0-prerelease.20191204144806", - "resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20191204144806.tgz", - "integrity": "sha512-GwVOCJPPBaMsw0ulId/Dxv/vrJ1T4GCZZQk49hlN7gpZozM5HQAYkz9DzZCGnwrwTFFJhI0biqQ/SOLfpe5bTQ==", + "version": "0.1.0-prerelease.20191205143447", + "resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20191205143447.tgz", + "integrity": "sha512-dx2ssVXXmCIXEoWbhOp9DM7oAZ6Nd0BHBhMQrDtSy+G2smODMsTqx7xsvfuQ+4+xtd8Sru7qjWG2RxPrJ6Fdkw==", "dev": true }, "scratch-l10n": { From c306b92d7873be0c7985a46ea03754136a4b17af Mon Sep 17 00:00:00 2001 From: picklesrus Date: Thu, 5 Dec 2019 09:47:12 -0500 Subject: [PATCH 19/20] add a missing t. --- src/components/page/www/donor-recognition.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/page/www/donor-recognition.jsx b/src/components/page/www/donor-recognition.jsx index 033e8c3fe..5fc28eb70 100644 --- a/src/components/page/www/donor-recognition.jsx +++ b/src/components/page/www/donor-recognition.jsx @@ -24,7 +24,7 @@ const DonorRecognition = () => ( Date: Thu, 5 Dec 2019 09:58:15 -0500 Subject: [PATCH 20/20] Remove an extra comma. --- src/l10n.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/l10n.json b/src/l10n.json index 5ec674823..58cf33a74 100644 --- a/src/l10n.json +++ b/src/l10n.json @@ -122,7 +122,7 @@ "footer.discuss": "Discussion Forums", "footer.scratchFamily": "Scratch Family", - "footer.donorRecognition": "Scratch is available for free, thanks to generous support from our {donorLink}. We are grateful to our Founding Partners:", + "footer.donorRecognition": "Scratch is available for free thanks to generous support from our {donorLink}. We are grateful to our Founding Partners:", "footer.donors": "donors", "footer.donorList": "{donor1}, {donor2}, and {donor3}.",