Skip to content
Snippets Groups Projects
Commit e0a6d78e authored by Brady James Garvin's avatar Brady James Garvin
Browse files

Initial commit.

parents
No related branches found
No related tags found
No related merge requests found
.eslintrc 0 → 100755
{
"env": {
"es6": true,
"browser": true,
"jquery": true,
},
"rules": {
"no-await-in-loop": "warn",
"no-compare-neg-zero": "warn",
"no-cond-assign": "warn",
"no-console": "off",
"no-constant-condition": "warn",
"no-control-regex": "warn",
"no-debugger": "warn",
"no-dupe-args": "warn",
"no-dupe-keys": "warn",
"no-duplicate-case": "warn",
"no-empty": "warn",
"no-empty-character-class": "warn",
"no-ex-assign": "warn",
"no-extra-boolean-cast": "warn",
"no-extra-parens": ["warn", "all", {
"nestedBinaryExpressions": false,
}],
"no-extra-semi": "warn",
"no-func-assign": "warn",
"no-inner-declarations": "warn",
"no-invalid-regexp": "warn",
"no-irregular-whitespace": "warn",
"no-obj-calls": "warn",
"no-prototype-builtins": "warn",
"no-regex-spaces": "warn",
"no-sparse-arrays": "warn",
"no-template-curly-in-string": "warn",
"no-unexpected-multiline": "warn",
"no-unreachable": "warn",
"no-unsafe-finally": "warn",
"no-unsafe-negation": "warn",
"use-isnan": "warn",
"valid-jsdoc": "warn",
"valid-typeof": "warn",
"accessor-pairs": "warn",
"array-callback-return": "warn",
"block-scoped-var": "warn",
"class-methods-use-this": "warn",
"complexity": "off",
"consistent-return": "warn",
"curly": "warn",
"default-case": "off",
"dot-location": "warn",
"dot-notation": "warn",
"eqeqeq": "warn",
"guard-for-in": "off", // see no-restricted-syntax
"no-alert": "warn",
"no-caller": "warn",
"no-case-declarations": "warn",
"no-div-regex": "warn",
"no-else-return": "warn",
"no-empty-function": "warn",
"no-empty-pattern": "warn",
"no-eq-null": "warn",
"no-eval": "warn",
"no-extend-native": "off",
"no-extra-bind": "warn",
"no-extra-label": "warn",
"no-fallthrough": "warn",
"no-floating-decimal": "warn",
"no-global-assign": "warn",
"no-implicit-coercion": "warn",
"no-implicit-globals": "off",
"no-implied-eval": "warn",
"no-invalid-this": "off",
"no-iterator": "warn",
"no-labels": "off",
"no-lone-blocks": "off",
"no-loop-func": "warn",
"no-magic-numbers": ["warn", {
"ignore": [-1, 0, 0.001, 0.5, 1, 2, 10, 100, 180, 360, 1000],
"detectObjects": true,
}],
"no-multi-spaces": "warn",
"no-multi-str": "warn",
"no-new": "warn",
"no-new-func": "warn",
"no-new-wrappers": "warn",
"no-octal": "warn",
"no-octal-escape": "warn",
"no-param-reassign": "warn",
"no-proto": "warn",
"no-redeclare": "warn",
"no-restricted-properties": "warn",
"no-return-assign": "warn",
"no-return-await": "warn",
"no-script-url": "warn",
"no-self-assign": "warn",
"no-self-compare": "warn",
"no-sequences": "warn",
"no-throw-literal": "warn",
"no-unmodified-loop-condition": "warn",
"no-unused-expressions": "warn",
"no-unused-labels": "warn",
"no-useless-call": "warn",
"no-useless-concat": "warn",
"no-useless-escape": "warn",
"no-useless-return": "warn",
"no-void": "warn",
"no-warning-comments": "warn",
"no-with": "warn",
"prefer-promise-reject-errors": "warn",
"radix": "warn",
"require-await": "warn",
"vars-on-top": "off",
"wrap-iife": "warn",
"yoda": "warn",
"strict": ["warn", "never"],
"init-declarations": "warn",
"no-catch-shadow": "warn",
"no-delete-var": "warn",
"no-label-var": "warn",
"no-restricted-globals": "warn",
"no-shadow": "warn",
"no-shadow-restricted-names": "warn",
"no-undef": "warn",
"no-undef-init": "off",
"no-undefined": "off",
"no-unused-vars": ["warn", {
"varsIgnorePattern": "_+",
}],
"no-use-before-define": "warn",
"array-bracket-spacing": "warn",
"block-spacing": "warn",
"brace-style": "warn",
"camelcase": "warn",
"capitalized-comments": "off",
"comma-dangle": ["warn", "always-multiline"],
"comma-spacing": "warn",
"comma-style": "warn",
"computed-property-spacing": "warn",
"consistent-this": "warn",
"eol-last": "warn",
"func-call-spacing": "warn",
"func-name-matching": "warn",
"func-names": ["warn", "as-needed"],
"func-style": "off",
"id-blacklist": ["warn", "temp"],
"id-length": "off",
"id-match": "off",
"indent": ["warn", 2],
"jsx-quotes": "warn",
"key-spacing": "warn",
"keyword-spacing": "warn",
"line-comment-position": "off",
"linebreak-style": "warn",
"lines-around-comment": "off",
"lines-around-directive": "warn",
"max-depth": "off",
"max-len": "off",
"max-lines": "off",
"max-nested-callbacks": "off",
"max-params": "off",
"max-statements": "off",
"max-statements-per-line": "warn",
"multiline-ternary": "off",
"new-cap": "warn",
"new-parens": "warn",
"newline-after-var": "off",
"newline-before-return": "off",
"newline-per-chained-call": "off",
"no-array-constructor": "warn",
"no-bitwise": "off",
"no-continue": "off",
"no-inline-comments": "off",
"no-lonely-if": "warn",
"no-mixed-operators": "off",
"no-mixed-spaces-and-tabs": "warn",
"no-multi-assign": "warn",
"no-multiple-empty-lines": ["warn", {
"maxBOF": 0,
"max": 1,
"maxEOF": 0,
}],
"no-negated-condition": "off",
"no-nested-ternary": "off",
"no-new-object": "warn",
"no-plusplus": "off",
"no-restricted-syntax": ["warn", {
"selector": "ForInStatement",
"message": "for-in loop used (did you mean to write a for-of loop?)",
}, {
"selector": "BinaryExpression[operator='in']",
"message": "in operator used (did you mean to call a membership-testing method?)",
}],
"no-tabs": "warn",
"no-ternary": "off",
"no-trailing-spaces": "warn",
"no-underscore-dangle": ["warn", {
"allowAfterThis": true,
"allowAfterSuper": true,
}],
"no-unneeded-ternary": "warn",
"no-whitespace-before-property": "warn",
"nonblock-statement-body-position": "off", // see curly
"object-curly-newline": "warn",
"object-curly-spacing": "warn",
"object-property-newline": "warn",
"one-var": ["warn", "never"],
"one-var-declaration-per-line": "warn",
"operator-assignment": "warn",
"operator-linebreak": "warn",
"padded-blocks": ["warn", "never"],
"quote-props": ["warn", "as-needed"],
"quotes": ["warn", "single"],
"require-jsdoc": "off",
"semi": "warn",
"semi-spacing": "warn",
"sort-keys": "off",
"sort-vars": "off",
"space-before-blocks": "off",
"space-before-function-paren": ["warn", "never"],
"space-in-parens": "warn",
"space-infix-ops": "warn",
"space-unary-ops": "warn",
"spaced-comment": "warn",
"template-tag-spacing": "off",
"unicode-bom": "warn",
"wrap-regex": "off",
"arrow-body-style": "warn",
"arrow-parens": "warn",
"arrow-spacing": "warn",
"constructor-super": "warn",
"generator-star-spacing": ["warn", "neither"],
"no-class-assign": "warn",
"no-confusing-arrow": "off",
"no-const-assign": "warn",
"no-dupe-class-members": "warn",
"no-duplicate-imports": "warn",
"no-new-symbol": "warn",
"no-restricted-imports": "off",
"no-this-before-super": "warn",
"no-useless-computed-key": "warn",
"no-useless-constructor": "warn",
"no-useless-rename": "warn",
"no-var": "warn",
"object-shorthand": "warn",
"prefer-arrow-callback": "warn",
"prefer-const": "warn",
"prefer-destructuring": "off",
"prefer-numeric-literals": "warn",
"prefer-rest-params": "warn",
"prefer-spread": "warn",
"prefer-template": "warn",
"require-yield": "warn",
"rest-spread-spacing": "warn",
"sort-imports": "off",
"symbol-description": "warn",
"template-curly-spacing": "warn",
"yield-star-spacing": "warn",
},
}
*~
{
"defaultSeverity": "warning",
"rules": {
"at-rule-empty-line-before": [ "always", {
except: [
"blockless-after-same-name-blockless",
"first-nested",
],
ignore: ["after-comment"],
} ],
"at-rule-name-case": "lower",
"at-rule-name-space-after": "always-single-line",
"at-rule-semicolon-newline-after": "always",
"block-closing-brace-empty-line-before": "never",
"block-closing-brace-newline-after": "always",
"block-closing-brace-newline-before": "always-multi-line",
"block-closing-brace-space-before": "always-single-line",
"block-no-empty": true,
"block-opening-brace-newline-after": "always-multi-line",
"block-opening-brace-space-after": "always-single-line",
"block-opening-brace-space-before": "always",
"color-hex-case": "lower",
"color-hex-length": "short",
"color-no-invalid-hex": true,
"comment-empty-line-before": [ "always", {
except: ["first-nested"],
ignore: ["stylelint-commands"],
} ],
"comment-no-empty": true,
"comment-whitespace-inside": "always",
"custom-property-empty-line-before": [ "always", {
except: [
"after-custom-property",
"first-nested",
],
ignore: [
"after-comment",
"inside-single-line-block",
],
} ],
"declaration-bang-space-after": "never",
"declaration-bang-space-before": "always",
"declaration-block-no-duplicate-properties": [ true, {
ignore: ["consecutive-duplicates-with-different-values"],
} ],
"declaration-block-no-redundant-longhand-properties": true,
"declaration-block-no-shorthand-property-overrides": true,
"declaration-block-semicolon-newline-after": "always-multi-line",
"declaration-block-semicolon-space-after": "always-single-line",
"declaration-block-semicolon-space-before": "never",
"declaration-block-single-line-max-declarations": 1,
"declaration-block-trailing-semicolon": "always",
"declaration-colon-newline-after": "always-multi-line",
"declaration-colon-space-after": "always-single-line",
"declaration-colon-space-before": "never",
"declaration-empty-line-before": [ "always", {
except: [
"after-declaration",
"first-nested",
],
ignore: [
"after-comment",
"inside-single-line-block",
],
} ],
"font-family-no-duplicate-names": true,
"function-calc-no-unspaced-operator": true,
"function-comma-newline-after": "always-multi-line",
"function-comma-space-after": "always-single-line",
"function-comma-space-before": "never",
"function-linear-gradient-no-nonstandard-direction": true,
"function-max-empty-lines": 0,
"function-name-case": "lower",
"function-parentheses-newline-inside": "always-multi-line",
"function-parentheses-space-inside": "never-single-line",
"function-whitespace-after": "always",
"indentation": 2,
"keyframe-declaration-no-important": true,
"length-zero-no-unit": true,
"max-empty-lines": 1,
"media-feature-colon-space-after": "always",
"media-feature-colon-space-before": "never",
"media-feature-name-case": "lower",
"media-feature-name-no-unknown": true,
"media-feature-parentheses-space-inside": "never",
"media-feature-range-operator-space-after": "always",
"media-feature-range-operator-space-before": "always",
"media-query-list-comma-newline-after": "always-multi-line",
"media-query-list-comma-space-after": "always-single-line",
"media-query-list-comma-space-before": "never",
"no-empty-source": true,
"no-eol-whitespace": true,
"no-extra-semicolons": true,
"no-invalid-double-slash-comments": true,
"no-missing-end-of-source-newline": true,
"number-leading-zero": "always",
"property-case": "lower",
"property-no-unknown": true,
"rule-empty-line-before": [ "always-multi-line", {
except: ["first-nested"],
ignore: ["after-comment"],
} ],
"selector-attribute-brackets-space-inside": "never",
"selector-attribute-operator-space-after": "never",
"selector-attribute-operator-space-before": "never",
"selector-combinator-space-after": "always",
"selector-combinator-space-before": "always",
"selector-descendant-combinator-no-non-space": true,
"selector-list-comma-newline-after": "always",
"selector-list-comma-space-before": "never",
"selector-max-empty-lines": 0,
"selector-pseudo-class-case": "lower",
"selector-pseudo-class-no-unknown": true,
"selector-pseudo-class-parentheses-space-inside": "never",
"selector-pseudo-element-case": "lower",
"selector-pseudo-element-colon-notation": "double",
"selector-pseudo-element-no-unknown": true,
"selector-type-case": "lower",
"selector-type-no-unknown": true,
"shorthand-property-no-redundant-values": true,
"string-no-newline": true,
"unit-case": "lower",
"unit-no-unknown": true,
"value-list-comma-newline-after": "always-multi-line",
"value-list-comma-space-after": "always-single-line",
"value-list-comma-space-before": "never",
"value-list-max-empty-lines": 0,
},
}
{
"ecmaVersion": 6,
"libs": [
"browser",
"jquery"
],
"loadEagerly": [],
"dontLoad": [
"node_module/**"
],
"plugins": {
"doc_comment": true,
"complete_strings": {
"maxLength": 15
}
}
}
\ No newline at end of file
# [Name of Page]
[description of page]
/* The following comments assume that you have already read the section on CSS
in the course textbook and that you have the CSS cheatsheet at hand to look
up what various selectors, combinators, and properties mean. */
/* Here we select the body element, which contains all visible content, and give
it a light-blue background, a sans-serif font, and center-aligned text. The
font and alignment will also be inherited by any elements inside of the body
unless some other rule overrides them. */
body {
background: #eef;
font-family: sans-serif;
text-align: center;
}
/* Here we select all top-level headings (there is only one on the current page)
and give it blank space above and below the same height as a letter "x" in
the heading's font and blank space on either side the same width as a letter
"m". */
h1 {
margin: 1ex 1em;
}
/* Now we select all unordered lists that have the class "control-group" and
make them one-row flexboxes with content centering. We also give them
internal padding. */
ul.control-group {
display: inline-flex;
flex-flow: row;
justify-content: center;
align-items: center;
padding: 1ex 1em;
}
/* This ruleset is related; it selects all list items inside such control
groups. We say that these list items cannot be resized to better fit the
flexbox, that they each have a margin, and that the do not show any bullets
or other symbols in front of their contents. */
ul.control-group li {
flex: 0 0 auto;
margin: 1ex 1em;
list-style: none;
}
/* Here we select both the control group with the ID "filters" and all tables.
We give them a fixed margin above and below, but an automatic margin on
either side so that they will self-center if displayed as blocks. We all add
a gray border with a translucent gray shadow and include some internal
padding. */
#filters, table {
margin: 1ex auto;
border: 1px solid #ccc;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
padding: 1ex 1em;
}
<!doctype html>
<html lang="en">
<!-- The following comments assume that you have already read the section on
HTML in the course textbook and that you have the HTML cheatsheet at hand
to look up what various elements mean. -->
<head>
<meta charset="UTF-8">
<!-- This meta tag tells mobile browsers to not pretend that they have
desktop-sized screens. -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- This link tag tells the browser to use styles from css/index.css. -->
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>Number-Filtering Example Code</title>
</head>
<body>
<h1>Number-Filtering Example</h1>
<!-- We create the filter controls as an unordered list so that other software
like a screen reader can detect that the options go together and that
they have no particular order. The unordered list has two classes,
`control-group` and `radio-buttons`, and the ID `filters`. Note that
class names and IDs are normally written as lowercase words separated by
hyphens. -->
<ul class="control-group radio-buttons" id="filters">
<!-- We create each option as a list item in the unordered list. -->
<li>
<!-- A radio-type input is just the circle that can be clicked on; the
associated text must appear in another element. Here we use the
`name` attribute to make all three radio buttons mutually exclusive,
and we give each radio button an ID so that the JavaScript can refer
to it specifically. The first radio button also has the attribute
`checked` with no value that marks it as checked. However, if a user
visits this page again, the browser might remember which radio button
they had selected and reuse that selection instead. -->
<input type="radio" name="filter" id="divisible-by-two" checked>
<!-- While we could just write text and have it appear next to the radio
button, here we use a `label` so that other software like a screen
reader can detect that this text is a caption for the radio
button. -->
<label for="divisible-by-two">Divisible by 2</label>
</li>
<li>
<input type="radio" name="filter" id="divisible-by-three">
<label for="divisible-by-three">Divisible by 3</label>
</li>
<li>
<input type="radio" name="filter" id="prime">
<label for="prime">Prime</label>
</li>
</ul>
<!-- What we write in the HTML is how the page initially appears. Here we
make an empty table, letting the JavaScript take care of filling in the
data. -->
<table>
<!-- We keep the table header separate both so that the table prints nicely
and so that we can clear the table body without losing the header. -->
<thead>
<tr>
<!-- We also leave the upper bound empty so that the JavaScript can fill
it in. But we use a span with an ID so that the JavaScript can
access this part of the page directly. -->
<th>Matching Numbers Less than <span id="limit"></span></th>
</tr>
</thead>
<!-- We give the table body an ID so that the JavaScript can access it
directly. -->
<tbody id="results">
</tbody>
</table>
<!-- This script tag tells the browser to load and run the local copy of
JQuery. Note that that code will run immediately, even before the (small
amount of) remaining HTML gets loaded. -->
<script src="libraries/jquery/jquery.min.js"></script>
<!-- This script tag tells the browser load and run the JavaScript from
js/index.js. Again, it will be run immediately. -->
<script src="js/index.js"></script>
</body>
</html>
// Constants are conventionally named in all caps with underscores:
const LIMIT = 100;
// ESLint correctly complains that we should be computing the primes less than
// half of LIMIT, not hardcoding them, but for demonstration purposes we use a
// comment to tell it to ignore the magic numbers on this line.
const SMALL_PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]; // eslint-disable-line no-magic-numbers
// We create a dictionary where the keys will be radio-button IDs and the values
// will be predicates on numbers. This variable is not named in all caps
// because we will change it (see immediately below).
const filters = new Map();
// Despite being `const`, we can change `filters` as long as we don't assign to
// it. Here, the dictionary value `(number) => number % 2 == 0` is an arrow
// function; it could be written in long form as
//
// function isDivisibleByTwo(number) {
// return number % 2 === 0;
// }
//
// That function does not run here; it is only saved in the dictionary for later
// when we run it in our event handler.
filters.set('divisible-by-two', (number) => number % 2 === 0); // eslint-disable-line no-magic-numbers
// Similarly:
filters.set('divisible-by-three', (number) => number % 3 === 0); // eslint-disable-line no-magic-numbers
// Here we write an arrow function using curly braces since we need more logic
// than just a return.
filters.set('prime', (number) => {
// A for-of loop is like a for-each loop in other languages.
for (const divisor of SMALL_PRIMES) {
// Conditionals are written as in Java.
if (divisor < number && number % divisor === 0) {
return false;
}
}
return number > 1;
});
// This is a named function because we want to run it both when the page loads
// and when the user clicks a radio button.
function updateResults() {
// The `$` function provided by JQuery takes a CSS selector and returns a
// collection representing all of the HTML elements that match at the time the
// function is run. Here we select just the element with the ID `limit`.
$('#limit').text(`${LIMIT}`);
// And here we select just the element with the ID `results`.
const results = $('#results');
// The `empty` method deletes all elements inside the ones we have selected.
// So here we delete any old rows in the table body.
results.empty();
// Besides for-of, loops, we can write ordinary for loops as in Java.
for (let i = 0; i < 100; ++i) {
let okay = true;
// Here we loop over all of key/value pairs in the filters map. Notice
// that, unlike Python where we could leave the parentheses off of the loop
// variable tuple, here we have to use the brackets to form an array.
for (const [id, filter] of filters) {
// The following code is broken into small steps so that we can comment on
// individual parts better.
// Create a CSS selector by substituting the variable `id` into a string.
// Note that the string is delimited with backticks to mark it as a
// template string. This selector matches elements that have the given ID
// and that are checked, so it will either match one radio button or none.
const selector = `#${id}:checked`;
// Use JQuery to find the matching elements.
const matchingCheckedRadioButtons = $(selector);
// If we matched an element, the radio button must be checked, so consult
// the corresponding filter:
if (matchingCheckedRadioButtons.length && !filter(i)) {
okay = false;
break;
}
}
if (okay) {
// The `append` method can be given HTML, from which it will create new
// elements.
results.append(`<tr><td>${i}<td></tr>`);
}
}
}
// Run the event handler right now (on page load).
updateResults();
// Here we write a selector that matches all `input` elements that have a `type`
// attribute set to `"radio"` and that are within the element with the ID
// `filters`.
const filterButtons = $('#filters input[type="radio"]');
// Finally, we attach an event handler to those elements using the `on` method.
// The first argument is an event name; here we use `'input'`, which fires any
// time the user gives input using an element. The second argument is the
// function to run.
filterButtons.on('input', updateResults);
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment