Check Theme of Browser
Theme of the browser
const theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light",
const theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light",
'-' or '------': Equivalent to [NEVER](<https://rxjs.dev/api/index/const/NEVER>), or an observable that never emits or errors or completes.
|: Equivalent to [EMPTY](<https://rxjs.dev/api/index/const/EMPTY>), or an observable that never emits and completes immediately.
#: Equivalent to [throwError](<https://rxjs.dev/api/index/function/throwError>), or an observable that never emits and errors immediately.
'--a--': An observable that waits 2 "frames", emits value a on frame 2 and then never completes.
'--a--b--|': On frame 2 emit a, on frame 5 emit b, and on frame 8, complete.
'--a--b--#': On frame 2 emit a, on frame 5 emit b, and on frame 8, error.
'-a-^-b--|': In a hot observable, on frame -2 emit a, then on frame 2 emit b, and on frame 5, complete.
'--(abc)-|': on frame 2 emit a, b, and c, then on frame 8, complete.
'-----(a|)': on frame 5 emit a and complete.
'a 9ms b 9s c|': on frame 0 emit a, on frame 10 emit b, on frame 9,011 emit c, then on frame 9,012 complete.
'--a 2.5m b': on frame 2 emit a, on frame 150,003 emit b and never complete.
import { TestScheduler } from 'rxjs/testing';
import { throttleTime } from 'rxjs';
const testScheduler = new TestScheduler((actual, expected) => {
// asserting the two objects are equal - required
// for TestScheduler assertions to work via your test framework
// e.g. using chai.
expect(actual).deep.equal(expected);
});
// This test runs synchronously.
it('generates the stream correctly', () => {
testScheduler.run((helpers) => {
const { cold, time, expectObservable, expectSubscriptions } = helpers;
const e1 = cold(' -a--b--c---|');
const e1subs = ' ^----------!';
const t = time(' ---| '); // t = 3
const expected = '-a-----c---|';
expectObservable(e1.pipe(throttleTime(t))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
testScheduler.run((helpers) => {
const { time, cold } = helpers;
const source = cold('---a--b--|');
const t = time(' --| ');
// --|
const expected = ' -----a--b|';
const result = source.pipe(delay(t));
expectObservable(result).toBe(expected);
});
testScheduler.run((helpers) => {
const { animate, cold } = helpers;
animate(' ---x---x---x---x');
const requests = cold('-r-------r------');
/* ... */
const expected = ' ---a-------b----';
});
});
All JavaScript objects inherit properties and methods from a prototype.
Date objects inherit from Date.prototypeArray objects inherit from Array.prototypePerson objects inherit from Person.prototypeThe Object.prototype is on the top of the prototype inheritance chain:
Date objects, Array objects, and Person objects inherit from Object.prototype
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.nationality = "English";
Person.prototype.name = function() {
return this.firstName + " " + this.lastName;
};
var myFather = new Person("John", "Doe", 50, "blue");
var myMother = new Person("Sally", "Rally", 48, "green");
❗Please do not add a new property to an existing object constructor as below. That is a wrong way.
Person.nationality = "English";
a || b // equals: a ? a : b
a ?? b // equals: a != undefined && a != null ? a : b
!'' // output: true
0 ?? 'a' // output: 0
0 || 'a' // output: "a"
'' ?? 'a' // output: ""
'' || 'a' // output: "a"
These methods can change the this point.
function test(arg1, arg2) {};
test.call(null, a1, a2);
test.apply(null, [a1, a2]);
var t = test.bind(null);
t();
Asynchronous Module Definition (AMD) has gained traction on the frontend, with RequireJS being the most popular implementation.
Here’s module foo with a single dependency on jquery:
// filename: foo.js
define(['jquery'], function ($) {
// methods
function myFunc(){};
// exposed public methods
return myFunc;
});
And a little more complicated example with multiple dependencies and multiple exposed methods:
// filename: foo.js
define(['jquery', 'underscore'], function ($, _) {
// methods
function a(){}; // private because it's not returned (see below)
function b(){}; // public because it's returned
function c(){}; // public because it's returned
// exposed public methods
return {
b: b,
c: c
}
});
Standard locates at https://github.com/seajs/seajs/issues/242. It keeps more compatibilities with CommonJS and Node.js Modules.
define((require, exports, module) => {
module.exports = {
fun1: () => {
var $ = require('jquery');
return $('#test');
}
};
});
CommonJS is a style you may be familiar with if you’re written anything in Node (which uses a slight variant). It’s also been gaining traction on the frontend with Browserify.
Using the same format as before, here’s what our foo module looks like in CommonJS:
// filename: foo.js
// dependencies
var $ = require('jquery');
// methods
function myFunc(){};
// exposed public method (single)
module.exports = myFunc;
And our more complicate example, with multiple dependencies and multiple exposed methods:
// filename: foo.js
var $ = require('jquery');
var _ = require('underscore');
// methods
function a(){}; // private because it's omitted from module.exports (see below)
function b(){}; // public because it's defined in module.exports
function c(){}; // public because it's defined in module.exports
// exposed public methods
module.exports = {
b: b,
c: c
};
Since CommonJS and AMD styles have both been equally popular, it seems there’s yet no consensus. This has brought about the push for a “universal” pattern that supports both styles, which brings us to none other than the Universal Module Definition.
The pattern is admittedly ugly, but is both AMD and CommonJS compatible, as well as supporting the old-style “global” variable definition:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS-like
module.exports = factory(require('jquery'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.jQuery);
}
}(this, function ($) {
// methods
function myFunc(){};
// exposed public method
return myFunc;
}));
And keeping in the same pattern as the above examples, the more complicated case with multiple dependencies and multiple exposed methods:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery', 'underscore'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS-like
module.exports = factory(require('jquery'), require('underscore'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.jQuery, root._);
}
}(this, function ($, _) {
// methods
function a(){}; // private because it's not returned (see below)
function b(){}; // public because it's returned
function c(){}; // public because it's returned
// exposed public methods
return {
b: b,
c: c
}
}));
$('#GetFile').on('click', function () {
$.ajax({
url: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/172905/test.pdf',
method: 'GET',
xhrFields: {
responseType: 'blob'
},
success: function (response) {
var blob = response.data;
var a = document.createElement('a');
var fileUrl = window.URL.createObjectURL(blob);
var filename = 'myfile.pdf';
/* you can also use below to get filename from backend */
// var contentDisposition = response.headers('Content-Disposition');
// var matches = /filename=\\"(.+?)\\"/g.exec(contentDisposition);
// var filename = matches && matches.length > 1 ? matches\[1\] : '';
/* but need add backend code like below, otherwise you cannot get Content-Disposition header */
// + response.setHeader("Content-Disposition", "attachment; filename=\\"myfile.csv\\"");
// + response.setHeader("Content-type", "application/octet-stream;charset=utf-8");
// + response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
// work in IE
if (window.navigator && window.navigator.msSaveBlob) {
window.navigator.msSaveBlob(blob, filename);
return;
}
a.href = fileUrl;
a.download = filename;
a.dispatchEvent(new MouseEvent('click'));
setTimeout(function() {
a.remove();
window.URL.revokeObjectURL.bind(window.URL, fileUrl);
});
}
});
});
Install requisite dependencies
# run local scripts for executing ts file for deploying docs
npm i -D @types/node
npm i -D ts-node
# semantic-release and plugin for attaching version number to package.json
npm i -D semantic-release
npm i -D @semantic-release/git
# git hooks and validate commit messages
npm i -D husky
npm i -D @commitlint/cli
Add content to package.json
\{
"scripts": \{
"deploy-docs": "ts-node tools/gh-pages-publish.ts",
"semantic-release": "semantic-release"
\},
"files": [
"dist"
],
// if package scoped like @bndynet/ui, by default private, so...
"publishConfig": \{
"access": "public"
\},
"husky": \{
"hooks": \{
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
\}
\}
\}
New file .releaserc (Release Configurations)
\{
"branch": "master",
"prepare": [
"@semantic-release/npm",
\{
"path": "@semantic-release/git",
"assets": [
"package.json",
"package-lock.json"
],
"message": "chore(release): $\{nextRelease.version\} by CI\n\n$\{nextRelease.notes\}"
\}
],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/github",
"@semantic-release/git"
]
\}
New file .travis.yml (CI configurations for publishing docs and releasing package)
language: node_js
cache:
directories:
- ~/.npm
notifications:
email: false
node_js:
- '10'
script:
- npm run build
after_success:
- if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then npm run deploy-docs; fi
- if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then npm run semantic-release; fi
branches:
except:
- /^v\d+\.\d+\.\d+$/
New file tools/gh-pages-publish.ts (Scripts to upload docs to gh-pages branch)
import \{ cd, exec, echo, touch \} from "shelljs";
import \{ readFileSync \} from "fs";
import \{ parse \} from "url";
let repoUrl
let pkg = JSON.parse(readFileSync("package.json"))
if (typeof pkg.repository === "object") \{
if (!pkg.repository.hasOwnProperty("url")) \{
throw new Error("URL does not exist in repository section")
\}
repoUrl = pkg.repository.url
\} else \{
repoUrl = pkg.repository
\}
let parsedUrl = parse(repoUrl)
let repository = (parsedUrl.host || "") + (parsedUrl.path || "")
let ghToken = process.env.GH_TOKEN
echo("Deploying docs!!!")
cd("docs")
touch(".nojekyll")
exec("git init")
exec("git add .")
exec('git config user.name "Bendy Zhang"')
exec('git config user.email "zb@bndy.net"')
exec('git commit -m "docs(docs): update gh-pages"')
exec(
`git push --force --quiet "https://${ghToken}@${repository}" master:gh-pages`
)
echo("Docs deployed!!")
Add environment variables to CI (Travis CI)