build(js): Migrate from yarn to npm (#4252)

This commit is contained in:
Barret Schloerke
2025-08-04 16:07:39 -04:00
committed by GitHub
parent ae82850e1f
commit 7dcb54bc7e
163 changed files with 8566 additions and 12495 deletions

View File

@@ -22,18 +22,16 @@
^manualtests$
^\.github$
^\.yarn$
^\.vscode$
^\.madgerc$
^\.prettierrc\.yml$
^jest\.config\.js$
^package\.json$
^tsconfig\.json$
^yarn\.lock$
^package-lock\.json$
^node_modules$
^coverage$
^.ignore$
^\.browserslistrc$
^\.eslintrc\.yml$
^\.yarnrc\.yml$
^_dev$

View File

@@ -1,8 +0,0 @@
# Browsers that we support
last 2 versions
not dead
> 0.2%
# > 1%
Firefox ESR
phantomjs 2.1
IE 11 # sorry

View File

@@ -1,110 +0,0 @@
root: true
env:
browser: true
es6: true
extends:
- 'eslint:recommended'
- 'plugin:@typescript-eslint/recommended'
- 'plugin:jest/recommended'
- 'plugin:prettier/recommended'
- 'plugin:jest-dom/recommended'
globals:
Atomics: readonly
SharedArrayBuffer: readonly
parser: '@typescript-eslint/parser'
parserOptions:
ecmaVersion: 2018
sourceType: module
project:
- './tsconfig.json'
ignorePatterns: # mirrors tsconfig.json's exclude
- '**/__tests__'
- '**/*.d.ts'
plugins:
- '@typescript-eslint'
- prettier
- jest-dom
- unicorn
rules:
"@typescript-eslint/explicit-function-return-type":
- off
"@typescript-eslint/no-explicit-any":
- off
"@typescript-eslint/explicit-module-boundary-types":
- error
default-case:
- error
linebreak-style:
- error
- unix
quotes:
- error
- double
- avoid-escape
semi:
- error
- always
dot-location:
- error
- property
camelcase:
# - error
- "off"
unicorn/filename-case:
- error
- case: camelCase
"@typescript-eslint/array-type":
- error
- default: array-simple
readonly: array-simple
"@typescript-eslint/consistent-indexed-object-style":
- error
- index-signature
"@typescript-eslint/sort-type-union-intersection-members":
- error
"@typescript-eslint/consistent-type-imports":
- error
"@typescript-eslint/no-floating-promises":
- error
"@typescript-eslint/naming-convention":
- error
- selector: default
format: [camelCase]
- selector: method
modifiers: [private]
format: [camelCase]
leadingUnderscore: require
- selector: method
modifiers: [protected]
format: [camelCase]
leadingUnderscore: require
- selector: variable
format: [camelCase]
trailingUnderscore: forbid
leadingUnderscore: forbid
- selector: parameter
format: [camelCase]
trailingUnderscore: allow
leadingUnderscore: forbid
- selector: [enum, enumMember]
format: [PascalCase]
- selector: typeLike
format: [PascalCase]
custom:
regex: "(t|T)ype$"
match: false

View File

@@ -5,8 +5,8 @@ echo "Updating package.json version to match DESCRIPTION Version"
Rscript ./tools/updatePackageJsonVersion.R
if [ -n "$(git status --porcelain package.json)" ]
then
echo "package.json has changed after running ./tools/updatePackageJsonVersion.R. Re-running 'yarn build'"
yarn build
echo "package.json has changed after running ./tools/updatePackageJsonVersion.R. Re-running 'npm run build'"
npm run build
git add ./inst package.json && git commit -m 'Sync package version (GitHub Actions)' || echo "No package version to commit"
else
echo "No package version difference detected; package.json is current."

View File

@@ -8,7 +8,7 @@ on:
pull_request:
branches: [main]
schedule:
- cron: '0 5 * * 1' # every monday
- cron: "0 5 * * 1" # every monday
name: Package checks
@@ -17,7 +17,5 @@ jobs:
uses: rstudio/shiny-workflows/.github/workflows/website.yaml@v1
routine:
uses: rstudio/shiny-workflows/.github/workflows/routine.yaml@v1
with:
node-version: "14.x"
R-CMD-check:
uses: rstudio/shiny-workflows/.github/workflows/R-CMD-check.yaml@v1

12
.gitignore vendored
View File

@@ -9,20 +9,16 @@
shinyapps/
README.html
.*.Rnb.cached
tools/yarn-error.log
/_dev/
.sass_cache_keys
# TypeScript / yarn
# TypeScript
/node_modules/
.cache
.yarn/*
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*
coverage/
madge.svg
# GHA remotes installation
.github/r-depends.rds
.claude/settings.local.json

View File

@@ -1,7 +1,5 @@
{
"search.exclude": {
"**/.yarn": true,
"**/.pnp.*": true
},
"prettier.prettierPath": "./node_modules/prettier",
"typescript.enablePromptUseWorkspaceTsdk": true,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,10 +0,0 @@
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs
spec: "https://github.com/mskelton/yarn-plugin-outdated/raw/main/bundles/@yarnpkg/plugin-outdated.js"
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-3.2.3.cjs
checksumBehavior: update

View File

@@ -1,2 +1,2 @@
# Generated by tools/updateBootstrapDatepicker.R; do not edit by hand
version_bs_date_picker <- "1.9.0"
version_bs_date_picker <- "1.10.0"

108
eslint.config.mjs Normal file
View File

@@ -0,0 +1,108 @@
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import prettier from "eslint-plugin-prettier";
import unicorn from "eslint-plugin-unicorn";
import globals from "globals";
import tsParser from "@typescript-eslint/parser";
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
});
export default [{
ignores: ["**/*.d.ts"],
}, ...compat.extends(
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
), {
plugins: {
"@typescript-eslint": typescriptEslint,
prettier,
unicorn,
},
languageOptions: {
globals: {
...globals.browser,
Atomics: "readonly",
SharedArrayBuffer: "readonly",
},
parser: tsParser,
ecmaVersion: 2021,
sourceType: "module",
parserOptions: {
project: ["./tsconfig.json"],
},
},
rules: {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": "error",
"default-case": ["error"],
"linebreak-style": ["error", "unix"],
quotes: ["error", "double", "avoid-escape"],
semi: ["error", "always"],
"dot-location": ["error", "property"],
camelcase: ["off"],
"unicorn/filename-case": ["error", {
case: "camelCase",
}],
"@typescript-eslint/array-type": ["error", {
default: "array-simple",
readonly: "array-simple",
}],
"@typescript-eslint/consistent-indexed-object-style": ["error", "index-signature"],
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/naming-convention": ["error", {
selector: "default",
format: ["camelCase"],
}, {
selector: "method",
modifiers: ["private"],
format: ["camelCase"],
leadingUnderscore: "require",
}, {
selector: "method",
modifiers: ["protected"],
format: ["camelCase"],
leadingUnderscore: "require",
}, {
selector: "variable",
format: ["camelCase"],
trailingUnderscore: "forbid",
leadingUnderscore: "forbid",
}, {
selector: "parameter",
format: ["camelCase"],
trailingUnderscore: "allow",
leadingUnderscore: "forbid",
}, {
selector: ["enum", "enumMember"],
format: ["PascalCase"],
}, {
selector: "typeLike",
format: ["PascalCase"],
custom: {
regex: "(t|T)ype$",
match: false,
},
}],
},
}];

View File

@@ -1,5 +1,5 @@
.datepicker {
border-radius: 0.25rem;
border-radius: 3px;
direction: ltr;
}
@@ -30,7 +30,7 @@
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid rgba(0, 0, 0, 0.15);
border-bottom: 7px solid var(--bs-border-color-translucent);
border-top: 0;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
@@ -41,7 +41,7 @@
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
border-bottom: 6px solid var(--bs-body-bg);
border-top: 0;
position: absolute;
}
@@ -73,13 +73,13 @@
.datepicker-dropdown.datepicker-orient-top:before {
bottom: -7px;
border-bottom: 0;
border-top: 7px solid rgba(0, 0, 0, 0.15);
border-top: 7px solid var(--bs-border-color-translucent);
}
.datepicker-dropdown.datepicker-orient-top:after {
bottom: -6px;
border-bottom: 0;
border-top: 6px solid #fff;
border-top: 6px solid var(--bs-body-bg);
}
.datepicker table {
@@ -105,64 +105,64 @@
}
.datepicker table tr td.old, .datepicker table tr td.new {
color: #6c757d;
color: #707782;
}
.datepicker table tr td.day:hover, .datepicker table tr td.focused {
color: #000;
background: #e9e9ea;
background: #e8e9e9;
cursor: pointer;
}
.datepicker table tr td.disabled, .datepicker table tr td.disabled:hover {
background: none;
color: #6c757d;
color: #707782;
cursor: default;
}
.datepicker table tr td.highlighted {
color: #000;
background-color: #d1ecf1;
border-color: #83ccd9;
background-color: #cdf4fa;
border-color: #70e0f1;
border-radius: 0;
}
.datepicker table tr td.highlighted:focus, .datepicker table tr td.highlighted.focus {
color: #000;
background-color: #bcd4d9;
border-color: #6299a3;
background-color: #b9dce1;
border-color: #54a8b5;
}
.datepicker table tr td.highlighted:hover {
color: #000;
background-color: #697679;
border-color: #73b3bf;
background-color: #677a7d;
border-color: #63c5d4;
}
.datepicker table tr td.highlighted:active, .datepicker table tr td.highlighted.active {
color: #000;
background-color: #bcd4d9;
border-color: #73b3bf;
background-color: #b9dce1;
border-color: #63c5d4;
}
.datepicker table tr td.highlighted:active:hover, .datepicker table tr td.highlighted:active:focus, .datepicker table tr td.highlighted.focus:active, .datepicker table tr td.highlighted.active:hover, .datepicker table tr td.highlighted.active:focus, .datepicker table tr td.highlighted.active.focus {
.datepicker table tr td.highlighted:active:hover, .datepicker table tr td.highlighted:active:focus, .datepicker table tr td.highlighted:active.focus, .datepicker table tr td.highlighted.active:hover, .datepicker table tr td.highlighted.active:focus, .datepicker table tr td.highlighted.active.focus {
color: #000;
background-color: #adc4c8;
border-color: #6299a3;
background-color: #aacbd0;
border-color: #54a8b5;
}
.datepicker table tr td.highlighted.disabled:hover, .datepicker table tr td.highlighted.disabled:focus, .datepicker table tr td.highlighted.disabled.focus, .datepicker table tr td.highlighted[disabled]:hover, .datepicker table tr td.highlighted[disabled]:focus, .datepicker table tr td.highlighted.focus[disabled], fieldset[disabled] .datepicker table tr td.highlighted:hover, fieldset[disabled] .datepicker table tr td.highlighted:focus, fieldset[disabled] .datepicker table tr td.highlighted.focus {
background-color: #d1ecf1;
border-color: #83ccd9;
.datepicker table tr td.highlighted.disabled:hover, .datepicker table tr td.highlighted.disabled:focus, .datepicker table tr td.highlighted.disabled.focus, .datepicker table tr td.highlighted[disabled]:hover, .datepicker table tr td.highlighted[disabled]:focus, .datepicker table tr td.highlighted[disabled].focus, fieldset[disabled] .datepicker table tr td.highlighted:hover, fieldset[disabled] .datepicker table tr td.highlighted:focus, fieldset[disabled] .datepicker table tr td.highlighted.focus {
background-color: #cdf4fa;
border-color: #70e0f1;
}
.datepicker table tr td.highlighted.focused {
background: #aadce5;
background: #9feaf5;
}
.datepicker table tr td.highlighted.disabled, .datepicker table tr td.highlighted.disabled:active {
background: #d1ecf1;
color: #6c757d;
background: #cdf4fa;
color: #707782;
}
.datepicker table tr td.today {
@@ -189,13 +189,13 @@
border-color: #e0a12d;
}
.datepicker table tr td.today:active:hover, .datepicker table tr td.today:active:focus, .datepicker table tr td.today.focus:active, .datepicker table tr td.today.active:hover, .datepicker table tr td.today.active:focus, .datepicker table tr td.today.active.focus {
.datepicker table tr td.today:active:hover, .datepicker table tr td.today:active:focus, .datepicker table tr td.today:active.focus, .datepicker table tr td.today.active:hover, .datepicker table tr td.today.active:focus, .datepicker table tr td.today.active.focus {
color: #000;
background-color: #d4b67f;
border-color: #bf8926;
}
.datepicker table tr td.today.disabled:hover, .datepicker table tr td.today.disabled:focus, .datepicker table tr td.today.disabled.focus, .datepicker table tr td.today[disabled]:hover, .datepicker table tr td.today[disabled]:focus, .datepicker table tr td.today.focus[disabled], fieldset[disabled] .datepicker table tr td.today:hover, fieldset[disabled] .datepicker table tr td.today:focus, fieldset[disabled] .datepicker table tr td.today.focus {
.datepicker table tr td.today.disabled:hover, .datepicker table tr td.today.disabled:focus, .datepicker table tr td.today.disabled.focus, .datepicker table tr td.today[disabled]:hover, .datepicker table tr td.today[disabled]:focus, .datepicker table tr td.today[disabled].focus, fieldset[disabled] .datepicker table tr td.today:hover, fieldset[disabled] .datepicker table tr td.today:focus, fieldset[disabled] .datepicker table tr td.today.focus {
background-color: #ffdb99;
border-color: #ffb733;
}
@@ -206,96 +206,96 @@
.datepicker table tr td.today.disabled, .datepicker table tr td.today.disabled:active {
background: #ffdb99;
color: #6c757d;
color: #707782;
}
.datepicker table tr td.range {
color: #000;
background-color: #e9e9ea;
border-color: #b5b5b8;
background-color: #e8e9e9;
border-color: #b4b7b7;
border-radius: 0;
}
.datepicker table tr td.range:focus, .datepicker table tr td.range.focus {
color: #000;
background-color: #d2d2d3;
border-color: #88888a;
background-color: #d1d2d2;
border-color: #878989;
}
.datepicker table tr td.range:hover {
color: #000;
background-color: #757575;
border-color: #9f9fa2;
background-color: #747575;
border-color: #9ea1a1;
}
.datepicker table tr td.range:active, .datepicker table tr td.range.active {
color: #000;
background-color: #d2d2d3;
border-color: #9f9fa2;
background-color: #d1d2d2;
border-color: #9ea1a1;
}
.datepicker table tr td.range:active:hover, .datepicker table tr td.range:active:focus, .datepicker table tr td.range.focus:active, .datepicker table tr td.range.active:hover, .datepicker table tr td.range.active:focus, .datepicker table tr td.range.active.focus {
.datepicker table tr td.range:active:hover, .datepicker table tr td.range:active:focus, .datepicker table tr td.range:active.focus, .datepicker table tr td.range.active:hover, .datepicker table tr td.range.active:focus, .datepicker table tr td.range.active.focus {
color: #000;
background-color: #c1c1c2;
border-color: #88888a;
background-color: #c1c1c1;
border-color: #878989;
}
.datepicker table tr td.range.disabled:hover, .datepicker table tr td.range.disabled:focus, .datepicker table tr td.range.disabled.focus, .datepicker table tr td.range[disabled]:hover, .datepicker table tr td.range[disabled]:focus, .datepicker table tr td.range.focus[disabled], fieldset[disabled] .datepicker table tr td.range:hover, fieldset[disabled] .datepicker table tr td.range:focus, fieldset[disabled] .datepicker table tr td.range.focus {
background-color: #e9e9ea;
border-color: #b5b5b8;
.datepicker table tr td.range.disabled:hover, .datepicker table tr td.range.disabled:focus, .datepicker table tr td.range.disabled.focus, .datepicker table tr td.range[disabled]:hover, .datepicker table tr td.range[disabled]:focus, .datepicker table tr td.range[disabled].focus, fieldset[disabled] .datepicker table tr td.range:hover, fieldset[disabled] .datepicker table tr td.range:focus, fieldset[disabled] .datepicker table tr td.range.focus {
background-color: #e8e9e9;
border-color: #b4b7b7;
}
.datepicker table tr td.range.focused {
background: #cfcfd1;
background: #ced0d0;
}
.datepicker table tr td.range.disabled, .datepicker table tr td.range.disabled:active {
background: #e9e9ea;
color: #6c757d;
background: #e8e9e9;
color: #707782;
}
.datepicker table tr td.range.highlighted {
color: #000;
background-color: #ddebee;
border-color: #99c3cc;
background-color: #dbeff2;
border-color: #90ced7;
}
.datepicker table tr td.range.highlighted:focus, .datepicker table tr td.range.highlighted.focus {
color: #000;
background-color: #c7d4d6;
border-color: #739299;
background-color: #c5d7da;
border-color: #6c9aa1;
}
.datepicker table tr td.range.highlighted:hover {
color: #000;
background-color: #6f7677;
border-color: #87acb4;
background-color: #6e7879;
border-color: #7fb5bd;
}
.datepicker table tr td.range.highlighted:active, .datepicker table tr td.range.highlighted.active {
color: #000;
background-color: #c7d4d6;
border-color: #87acb4;
background-color: #c5d7da;
border-color: #7fb5bd;
}
.datepicker table tr td.range.highlighted:active:hover, .datepicker table tr td.range.highlighted:active:focus, .datepicker table tr td.range.highlighted.focus:active, .datepicker table tr td.range.highlighted.active:hover, .datepicker table tr td.range.highlighted.active:focus, .datepicker table tr td.range.highlighted.active.focus {
.datepicker table tr td.range.highlighted:active:hover, .datepicker table tr td.range.highlighted:active:focus, .datepicker table tr td.range.highlighted:active.focus, .datepicker table tr td.range.highlighted.active:hover, .datepicker table tr td.range.highlighted.active:focus, .datepicker table tr td.range.highlighted.active.focus {
color: #000;
background-color: #b7c3c6;
border-color: #739299;
background-color: #b6c6c9;
border-color: #6c9aa1;
}
.datepicker table tr td.range.highlighted.disabled:hover, .datepicker table tr td.range.highlighted.disabled:focus, .datepicker table tr td.range.highlighted.disabled.focus, .datepicker table tr td.range.highlighted[disabled]:hover, .datepicker table tr td.range.highlighted[disabled]:focus, .datepicker table tr td.range.highlighted.focus[disabled], fieldset[disabled] .datepicker table tr td.range.highlighted:hover, fieldset[disabled] .datepicker table tr td.range.highlighted:focus, fieldset[disabled] .datepicker table tr td.range.highlighted.focus {
background-color: #ddebee;
border-color: #99c3cc;
.datepicker table tr td.range.highlighted.disabled:hover, .datepicker table tr td.range.highlighted.disabled:focus, .datepicker table tr td.range.highlighted.disabled.focus, .datepicker table tr td.range.highlighted[disabled]:hover, .datepicker table tr td.range.highlighted[disabled]:focus, .datepicker table tr td.range.highlighted[disabled].focus, fieldset[disabled] .datepicker table tr td.range.highlighted:hover, fieldset[disabled] .datepicker table tr td.range.highlighted:focus, fieldset[disabled] .datepicker table tr td.range.highlighted.focus {
background-color: #dbeff2;
border-color: #90ced7;
}
.datepicker table tr td.range.highlighted.focused {
background: #bbd7dd;
background: #b6dee4;
}
.datepicker table tr td.range.highlighted.disabled, .datepicker table tr td.range.highlighted.disabled:active {
background: #ddebee;
color: #6c757d;
background: #dbeff2;
color: #707782;
}
.datepicker table tr td.range.today {
@@ -322,92 +322,92 @@
border-color: #d08d14;
}
.datepicker table tr td.range.today:active:hover, .datepicker table tr td.range.today:active:focus, .datepicker table tr td.range.today.focus:active, .datepicker table tr td.range.today.active:hover, .datepicker table tr td.range.today.active:focus, .datepicker table tr td.range.today.active.focus {
.datepicker table tr td.range.today:active:hover, .datepicker table tr td.range.today:active:focus, .datepicker table tr td.range.today:active.focus, .datepicker table tr td.range.today.active:hover, .datepicker table tr td.range.today.active:focus, .datepicker table tr td.range.today.active.focus {
color: #000;
background-color: #cba561;
border-color: #b17811;
}
.datepicker table tr td.range.today.disabled:hover, .datepicker table tr td.range.today.disabled:focus, .datepicker table tr td.range.today.disabled.focus, .datepicker table tr td.range.today[disabled]:hover, .datepicker table tr td.range.today[disabled]:focus, .datepicker table tr td.range.today.focus[disabled], fieldset[disabled] .datepicker table tr td.range.today:hover, fieldset[disabled] .datepicker table tr td.range.today:focus, fieldset[disabled] .datepicker table tr td.range.today.focus {
.datepicker table tr td.range.today.disabled:hover, .datepicker table tr td.range.today.disabled:focus, .datepicker table tr td.range.today.disabled.focus, .datepicker table tr td.range.today[disabled]:hover, .datepicker table tr td.range.today[disabled]:focus, .datepicker table tr td.range.today[disabled].focus, fieldset[disabled] .datepicker table tr td.range.today:hover, fieldset[disabled] .datepicker table tr td.range.today:focus, fieldset[disabled] .datepicker table tr td.range.today.focus {
background-color: #f4c775;
border-color: #eca117;
}
.datepicker table tr td.range.today.disabled, .datepicker table tr td.range.today.disabled:active {
background: #f4c775;
color: #6c757d;
color: #707782;
}
.datepicker table tr td.selected, .datepicker table tr td.selected.highlighted {
color: #fff;
background-color: #898b8d;
border-color: #6b6e71;
color: #000;
background-color: #878889;
border-color: #606060;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.selected:focus, .datepicker table tr td.selected.focus, .datepicker table tr td.selected.highlighted:focus, .datepicker table tr td.selected.highlighted.focus {
color: #fff;
background-color: #959798;
border-color: #909295;
color: #000;
background-color: #7a7a7b;
border-color: #484848;
}
.datepicker table tr td.selected:hover, .datepicker table tr td.selected.highlighted:hover {
color: #fff;
background-color: #c4c5c6;
border-color: #7d7f82;
color: #000;
background-color: #444445;
border-color: #545454;
}
.datepicker table tr td.selected:active, .datepicker table tr td.selected.active, .datepicker table tr td.selected.highlighted:active, .datepicker table tr td.selected.highlighted.active {
color: #fff;
background-color: #959798;
border-color: #7d7f82;
color: #000;
background-color: #7a7a7b;
border-color: #545454;
}
.datepicker table tr td.selected:active:hover, .datepicker table tr td.selected:active:focus, .datepicker table tr td.selected.focus:active, .datepicker table tr td.selected.active:hover, .datepicker table tr td.selected.active:focus, .datepicker table tr td.selected.active.focus, .datepicker table tr td.selected.highlighted:active:hover, .datepicker table tr td.selected.highlighted:active:focus, .datepicker table tr td.selected.highlighted.focus:active, .datepicker table tr td.selected.highlighted.active:hover, .datepicker table tr td.selected.highlighted.active:focus, .datepicker table tr td.selected.highlighted.active.focus {
color: #fff;
background-color: #9d9fa0;
border-color: #909295;
.datepicker table tr td.selected:active:hover, .datepicker table tr td.selected:active:focus, .datepicker table tr td.selected:active.focus, .datepicker table tr td.selected.active:hover, .datepicker table tr td.selected.active:focus, .datepicker table tr td.selected.active.focus, .datepicker table tr td.selected.highlighted:active:hover, .datepicker table tr td.selected.highlighted:active:focus, .datepicker table tr td.selected.highlighted:active.focus, .datepicker table tr td.selected.highlighted.active:hover, .datepicker table tr td.selected.highlighted.active:focus, .datepicker table tr td.selected.highlighted.active.focus {
color: #000;
background-color: #707172;
border-color: #484848;
}
.datepicker table tr td.selected.disabled:hover, .datepicker table tr td.selected.disabled:focus, .datepicker table tr td.selected.disabled.focus, .datepicker table tr td.selected[disabled]:hover, .datepicker table tr td.selected[disabled]:focus, .datepicker table tr td.selected.focus[disabled], fieldset[disabled] .datepicker table tr td.selected:hover, fieldset[disabled] .datepicker table tr td.selected:focus, fieldset[disabled] .datepicker table tr td.selected.focus, .datepicker table tr td.selected.highlighted.disabled:hover, .datepicker table tr td.selected.highlighted.disabled:focus, .datepicker table tr td.selected.highlighted.disabled.focus, .datepicker table tr td.selected.highlighted[disabled]:hover, .datepicker table tr td.selected.highlighted[disabled]:focus, .datepicker table tr td.selected.highlighted.focus[disabled], fieldset[disabled] .datepicker table tr td.selected.highlighted:hover, fieldset[disabled] .datepicker table tr td.selected.highlighted:focus, fieldset[disabled] .datepicker table tr td.selected.highlighted.focus {
background-color: #898b8d;
border-color: #6b6e71;
.datepicker table tr td.selected.disabled:hover, .datepicker table tr td.selected.disabled:focus, .datepicker table tr td.selected.disabled.focus, .datepicker table tr td.selected[disabled]:hover, .datepicker table tr td.selected[disabled]:focus, .datepicker table tr td.selected[disabled].focus, fieldset[disabled] .datepicker table tr td.selected:hover, fieldset[disabled] .datepicker table tr td.selected:focus, fieldset[disabled] .datepicker table tr td.selected.focus, .datepicker table tr td.selected.highlighted.disabled:hover, .datepicker table tr td.selected.highlighted.disabled:focus, .datepicker table tr td.selected.highlighted.disabled.focus, .datepicker table tr td.selected.highlighted[disabled]:hover, .datepicker table tr td.selected.highlighted[disabled]:focus, .datepicker table tr td.selected.highlighted[disabled].focus, fieldset[disabled] .datepicker table tr td.selected.highlighted:hover, fieldset[disabled] .datepicker table tr td.selected.highlighted:focus, fieldset[disabled] .datepicker table tr td.selected.highlighted.focus {
background-color: #878889;
border-color: #606060;
}
.datepicker table tr td.active, .datepicker table tr td.active.highlighted {
color: #fff;
background-color: #007bff;
border-color: #0277f4;
color: #ffffff;
background-color: #007bc2;
border-color: #0176ba;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.active:focus, .datepicker table tr td.active.focus, .datepicker table tr td.active.highlighted:focus, .datepicker table tr td.active.highlighted.focus {
color: #fff;
background-color: #1a88ff;
border-color: #4199f7;
color: #ffffff;
background-color: #1a88c8;
border-color: #4198cb;
}
.datepicker table tr td.active:hover, .datepicker table tr td.active.highlighted:hover {
color: #fff;
background-color: #80bdff;
border-color: #2087f5;
color: #ffffff;
background-color: #80bde1;
border-color: #1f86c2;
}
.datepicker table tr td.active:active, .datepicker table tr td.active.active, .datepicker table tr td.active.highlighted:active, .datepicker table tr td.active.highlighted.active {
color: #fff;
background-color: #1a88ff;
border-color: #2087f5;
color: #ffffff;
background-color: #1a88c8;
border-color: #1f86c2;
}
.datepicker table tr td.active:active:hover, .datepicker table tr td.active:active:focus, .datepicker table tr td.active.focus:active, .datepicker table tr td.active.active:hover, .datepicker table tr td.active.active:focus, .datepicker table tr td.active.active.focus, .datepicker table tr td.active.highlighted:active:hover, .datepicker table tr td.active.highlighted:active:focus, .datepicker table tr td.active.highlighted.focus:active, .datepicker table tr td.active.highlighted.active:hover, .datepicker table tr td.active.highlighted.active:focus, .datepicker table tr td.active.highlighted.active.focus {
color: #fff;
background-color: #2b91ff;
border-color: #4199f7;
.datepicker table tr td.active:active:hover, .datepicker table tr td.active:active:focus, .datepicker table tr td.active:active.focus, .datepicker table tr td.active.active:hover, .datepicker table tr td.active.active:focus, .datepicker table tr td.active.active.focus, .datepicker table tr td.active.highlighted:active:hover, .datepicker table tr td.active.highlighted:active:focus, .datepicker table tr td.active.highlighted:active.focus, .datepicker table tr td.active.highlighted.active:hover, .datepicker table tr td.active.highlighted.active:focus, .datepicker table tr td.active.highlighted.active.focus {
color: #ffffff;
background-color: #2b91cc;
border-color: #4198cb;
}
.datepicker table tr td.active.disabled:hover, .datepicker table tr td.active.disabled:focus, .datepicker table tr td.active.disabled.focus, .datepicker table tr td.active[disabled]:hover, .datepicker table tr td.active[disabled]:focus, .datepicker table tr td.active.focus[disabled], fieldset[disabled] .datepicker table tr td.active:hover, fieldset[disabled] .datepicker table tr td.active:focus, fieldset[disabled] .datepicker table tr td.active.focus, .datepicker table tr td.active.highlighted.disabled:hover, .datepicker table tr td.active.highlighted.disabled:focus, .datepicker table tr td.active.highlighted.disabled.focus, .datepicker table tr td.active.highlighted[disabled]:hover, .datepicker table tr td.active.highlighted[disabled]:focus, .datepicker table tr td.active.highlighted.focus[disabled], fieldset[disabled] .datepicker table tr td.active.highlighted:hover, fieldset[disabled] .datepicker table tr td.active.highlighted:focus, fieldset[disabled] .datepicker table tr td.active.highlighted.focus {
background-color: #007bff;
border-color: #0277f4;
.datepicker table tr td.active.disabled:hover, .datepicker table tr td.active.disabled:focus, .datepicker table tr td.active.disabled.focus, .datepicker table tr td.active[disabled]:hover, .datepicker table tr td.active[disabled]:focus, .datepicker table tr td.active[disabled].focus, fieldset[disabled] .datepicker table tr td.active:hover, fieldset[disabled] .datepicker table tr td.active:focus, fieldset[disabled] .datepicker table tr td.active.focus, .datepicker table tr td.active.highlighted.disabled:hover, .datepicker table tr td.active.highlighted.disabled:focus, .datepicker table tr td.active.highlighted.disabled.focus, .datepicker table tr td.active.highlighted[disabled]:hover, .datepicker table tr td.active.highlighted[disabled]:focus, .datepicker table tr td.active.highlighted[disabled].focus, fieldset[disabled] .datepicker table tr td.active.highlighted:hover, fieldset[disabled] .datepicker table tr td.active.highlighted:focus, fieldset[disabled] .datepicker table tr td.active.highlighted.focus {
background-color: #007bc2;
border-color: #0176ba;
}
.datepicker table tr td span {
@@ -423,53 +423,53 @@
.datepicker table tr td span:hover, .datepicker table tr td span.focused {
color: #000;
background: #e9e9ea;
background: #e8e9e9;
}
.datepicker table tr td span.disabled, .datepicker table tr td span.disabled:hover {
background: none;
color: #6c757d;
color: #707782;
cursor: default;
}
.datepicker table tr td span.active, .datepicker table tr td span.active:hover, .datepicker table tr td span.active.disabled, .datepicker table tr td span.active.disabled:hover {
color: #fff;
background-color: #007bff;
border-color: #0277f4;
color: #ffffff;
background-color: #007bc2;
border-color: #0176ba;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:focus, .datepicker table tr td span.active.focus, .datepicker table tr td span.active:hover:focus, .datepicker table tr td span.active.focus:hover, .datepicker table tr td span.active.disabled:focus, .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active.disabled:hover:focus, .datepicker table tr td span.active.disabled.focus:hover {
color: #fff;
background-color: #1a88ff;
border-color: #4199f7;
.datepicker table tr td span.active:focus, .datepicker table tr td span.active.focus, .datepicker table tr td span.active:hover:focus, .datepicker table tr td span.active:hover.focus, .datepicker table tr td span.active.disabled:focus, .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active.disabled:hover:focus, .datepicker table tr td span.active.disabled:hover.focus {
color: #ffffff;
background-color: #1a88c8;
border-color: #4198cb;
}
.datepicker table tr td span.active:hover, .datepicker table tr td span.active:hover:hover, .datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active.disabled:hover:hover {
color: #fff;
background-color: #80bdff;
border-color: #2087f5;
color: #ffffff;
background-color: #80bde1;
border-color: #1f86c2;
}
.datepicker table tr td span.active:active, .datepicker table tr td span.active.active, .datepicker table tr td span.active:hover:active, .datepicker table tr td span.active.active:hover, .datepicker table tr td span.active.disabled:active, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled:hover:active, .datepicker table tr td span.active.disabled.active:hover {
color: #fff;
background-color: #1a88ff;
border-color: #2087f5;
.datepicker table tr td span.active:active, .datepicker table tr td span.active.active, .datepicker table tr td span.active:hover:active, .datepicker table tr td span.active:hover.active, .datepicker table tr td span.active.disabled:active, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled:hover:active, .datepicker table tr td span.active.disabled:hover.active {
color: #ffffff;
background-color: #1a88c8;
border-color: #1f86c2;
}
.datepicker table tr td span.active:active:hover, .datepicker table tr td span.active:active:focus, .datepicker table tr td span.active.focus:active, .datepicker table tr td span.active.active:hover, .datepicker table tr td span.active.active:focus, .datepicker table tr td span.active.active.focus, .datepicker table tr td span.active:hover:active:hover, .datepicker table tr td span.active:hover:active:focus, .datepicker table tr td span.active.focus:hover:active, .datepicker table tr td span.active.active:hover:hover, .datepicker table tr td span.active.active:hover:focus, .datepicker table tr td span.active.active.focus:hover, .datepicker table tr td span.active.disabled:active:hover, .datepicker table tr td span.active.disabled:active:focus, .datepicker table tr td span.active.disabled.focus:active, .datepicker table tr td span.active.disabled.active:hover, .datepicker table tr td span.active.disabled.active:focus, .datepicker table tr td span.active.disabled.active.focus, .datepicker table tr td span.active.disabled:hover:active:hover, .datepicker table tr td span.active.disabled:hover:active:focus, .datepicker table tr td span.active.disabled.focus:hover:active, .datepicker table tr td span.active.disabled.active:hover:hover, .datepicker table tr td span.active.disabled.active:hover:focus, .datepicker table tr td span.active.disabled.active.focus:hover {
color: #fff;
background-color: #2b91ff;
border-color: #4199f7;
.datepicker table tr td span.active:active:hover, .datepicker table tr td span.active:active:focus, .datepicker table tr td span.active:active.focus, .datepicker table tr td span.active.active:hover, .datepicker table tr td span.active.active:focus, .datepicker table tr td span.active.active.focus, .datepicker table tr td span.active:hover:active:hover, .datepicker table tr td span.active:hover:active:focus, .datepicker table tr td span.active:hover:active.focus, .datepicker table tr td span.active:hover.active:hover, .datepicker table tr td span.active:hover.active:focus, .datepicker table tr td span.active:hover.active.focus, .datepicker table tr td span.active.disabled:active:hover, .datepicker table tr td span.active.disabled:active:focus, .datepicker table tr td span.active.disabled:active.focus, .datepicker table tr td span.active.disabled.active:hover, .datepicker table tr td span.active.disabled.active:focus, .datepicker table tr td span.active.disabled.active.focus, .datepicker table tr td span.active.disabled:hover:active:hover, .datepicker table tr td span.active.disabled:hover:active:focus, .datepicker table tr td span.active.disabled:hover:active.focus, .datepicker table tr td span.active.disabled:hover.active:hover, .datepicker table tr td span.active.disabled:hover.active:focus, .datepicker table tr td span.active.disabled:hover.active.focus {
color: #ffffff;
background-color: #2b91cc;
border-color: #4198cb;
}
.datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active.disabled:focus, .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active[disabled]:hover, .datepicker table tr td span.active[disabled]:focus, .datepicker table tr td span.active.focus[disabled], fieldset[disabled] .datepicker table tr td span.active:hover, fieldset[disabled] .datepicker table tr td span.active:focus, fieldset[disabled] .datepicker table tr td span.active.focus, .datepicker table tr td span.active.disabled:hover:hover, .datepicker table tr td span.active.disabled:hover:focus, .datepicker table tr td span.active.disabled.focus:hover, .datepicker table tr td span.active[disabled]:hover:hover, .datepicker table tr td span.active[disabled]:hover:focus, .datepicker table tr td span.active.focus[disabled]:hover, fieldset[disabled] .datepicker table tr td span.active:hover:hover, fieldset[disabled] .datepicker table tr td span.active:hover:focus, fieldset[disabled] .datepicker table tr td span.active.focus:hover, .datepicker table tr td span.active.disabled.disabled:hover, .datepicker table tr td span.active.disabled.disabled:focus, .datepicker table tr td span.active.disabled.disabled.focus, .datepicker table tr td span.active.disabled[disabled]:hover, .datepicker table tr td span.active.disabled[disabled]:focus, .datepicker table tr td span.active.disabled.focus[disabled], fieldset[disabled] .datepicker table tr td span.active.disabled:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:focus, fieldset[disabled] .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active.disabled.disabled:hover:hover, .datepicker table tr td span.active.disabled.disabled:hover:focus, .datepicker table tr td span.active.disabled.disabled.focus:hover, .datepicker table tr td span.active.disabled[disabled]:hover:hover, .datepicker table tr td span.active.disabled[disabled]:hover:focus, .datepicker table tr td span.active.disabled.focus[disabled]:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus, fieldset[disabled] .datepicker table tr td span.active.disabled.focus:hover {
background-color: #007bff;
border-color: #0277f4;
.datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active.disabled:focus, .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active[disabled]:hover, .datepicker table tr td span.active[disabled]:focus, .datepicker table tr td span.active[disabled].focus, fieldset[disabled] .datepicker table tr td span.active:hover, fieldset[disabled] .datepicker table tr td span.active:focus, fieldset[disabled] .datepicker table tr td span.active.focus, .datepicker table tr td span.active:hover.disabled:hover, .datepicker table tr td span.active:hover.disabled:focus, .datepicker table tr td span.active:hover.disabled.focus, .datepicker table tr td span.active:hover[disabled]:hover, .datepicker table tr td span.active:hover[disabled]:focus, .datepicker table tr td span.active:hover[disabled].focus, fieldset[disabled] .datepicker table tr td span.active:hover:hover, fieldset[disabled] .datepicker table tr td span.active:hover:focus, fieldset[disabled] .datepicker table tr td span.active:hover.focus, .datepicker table tr td span.active.disabled.disabled:hover, .datepicker table tr td span.active.disabled.disabled:focus, .datepicker table tr td span.active.disabled.disabled.focus, .datepicker table tr td span.active.disabled[disabled]:hover, .datepicker table tr td span.active.disabled[disabled]:focus, .datepicker table tr td span.active.disabled[disabled].focus, fieldset[disabled] .datepicker table tr td span.active.disabled:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:focus, fieldset[disabled] .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active.disabled:hover.disabled:hover, .datepicker table tr td span.active.disabled:hover.disabled:focus, .datepicker table tr td span.active.disabled:hover.disabled.focus, .datepicker table tr td span.active.disabled:hover[disabled]:hover, .datepicker table tr td span.active.disabled:hover[disabled]:focus, .datepicker table tr td span.active.disabled:hover[disabled].focus, fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus, fieldset[disabled] .datepicker table tr td span.active.disabled:hover.focus {
background-color: #007bc2;
border-color: #0176ba;
}
.datepicker table tr td span.old, .datepicker table tr td span.new {
color: #6c757d;
color: #707782;
}
.datepicker .datepicker-switch {
@@ -488,7 +488,7 @@
.datepicker .next:hover,
.datepicker tfoot tr th:hover {
color: #000;
background: #e9e9ea;
background: #e8e9e9;
}
.datepicker .prev.disabled, .datepicker .next.disabled {

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
/*!
* Datepicker for Bootstrap v1.9.0 (https://github.com/uxsolutions/bootstrap-datepicker)
* Datepicker for Bootstrap v1.10.0 (https://github.com/uxsolutions/bootstrap-datepicker)
*
* Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* Licensed under the Apache License v2.0 (https://www.apache.org/licenses/LICENSE-2.0)
*/
(function(factory){
@@ -61,7 +61,7 @@
replace: function(new_array){
if (!new_array)
return;
if (!$.isArray(new_array))
if (!Array.isArray(new_array))
new_array = [new_array];
this.clear();
this.push.apply(this, new_array);
@@ -103,9 +103,15 @@
this.isInput = this.element.is('input');
this.inputField = this.isInput ? this.element : this.element.find('input');
this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn') : false;
if (this.component && this.component.length === 0)
if (this.component && this.component.length === 0){
this.component = false;
this.isInline = !this.component && this.element.is('div');
}
if (this.o.isInline === null){
this.isInline = !this.component && !this.isInput;
} else {
this.isInline = this.o.isInline;
}
this.picker = $(DPGlobal.template);
@@ -176,7 +182,7 @@
},
_resolveDaysOfWeek: function(daysOfWeek){
if (!$.isArray(daysOfWeek))
if (!Array.isArray(daysOfWeek))
daysOfWeek = daysOfWeek.split(/[,\s]*/);
return $.map(daysOfWeek, Number);
},
@@ -263,7 +269,7 @@
o.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted||[]);
o.datesDisabled = o.datesDisabled||[];
if (!$.isArray(o.datesDisabled)) {
if (!Array.isArray(o.datesDisabled)) {
o.datesDisabled = o.datesDisabled.split(',');
}
o.datesDisabled = $.map(o.datesDisabled, function(d){
@@ -570,16 +576,15 @@
clearDates: function(){
this.inputField.val('');
this.update();
this._trigger('changeDate');
this.update();
if (this.o.autoclose) {
this.hide();
}
},
setDates: function(){
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
var args = Array.isArray(arguments[0]) ? arguments[0] : arguments;
this.update.apply(this, args);
this._trigger('changeDate');
this.setValue();
@@ -587,7 +592,7 @@
},
setUTCDates: function(){
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
var args = Array.isArray(arguments[0]) ? arguments[0] : arguments;
this.setDates.apply(this, $.map(args, this._utc_to_local));
return this;
},
@@ -1039,7 +1044,7 @@
//Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2)
//Fallback to unique function for older jquery versions
if ($.isFunction($.uniqueSort)) {
if (typeof $.uniqueSort === "function") {
clsName = $.uniqueSort(clsName);
} else {
clsName = $.unique(clsName);
@@ -1571,12 +1576,12 @@
if (new_date < this.dates[j]){
// Date being moved earlier/left
while (j >= 0 && new_date < this.dates[j]){
while (j >= 0 && new_date < this.dates[j] && (this.pickers[j].element.val() || "").length > 0) {
this.pickers[j--].setUTCDate(new_date);
}
} else if (new_date > this.dates[k]){
// Date being moved later/right
while (k < l && new_date > this.dates[k]){
while (k < l && new_date > this.dates[k] && (this.pickers[k].element.val() || "").length > 0) {
this.pickers[k++].setUTCDate(new_date);
}
}
@@ -1690,6 +1695,7 @@
endDate: Infinity,
forceParse: true,
format: 'mm/dd/yyyy',
isInline: null,
keepEmptyValues: false,
keyboardNavigation: true,
language: 'en',
@@ -2007,7 +2013,7 @@
/* DATEPICKER VERSION
* =================== */
$.fn.datepicker.version = '1.9.0';
$.fn.datepicker.version = '1.10.0';
$.fn.datepicker.deprecated = function(msg){
var console = window.console;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
!function(a){a.fn.datepicker.dates["ar-DZ"]={days:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت","الأحد"],daysShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت","أحد"],daysMin:["ح","ن","ث","ع","خ","ج","س","ح"],months:["جانفي","فيفري","مارس","أفريل","ماي","جوان","جويليه","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthsShort:["جانفي","فيفري","مارس","أفريل","ماي","جوان","جويليه","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],today:"هذا اليوم",rtl:!0,monthsTitle:"أشهر",clear:"إزالة",format:"yyyy/mm/dd",weekStart:0}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.ca={days:["Diumenge","Dilluns","Dimarts","Dimecres","Dijous","Divendres","Dissabte"],daysShort:["Diu","Dil","Dmt","Dmc","Dij","Div","Dis"],daysMin:["dg","dl","dt","dc","dj","dv","ds"],months:["Gener","Febrer","Març","Abril","Maig","Juny","Juliol","Agost","Setembre","Octubre","Novembre","Desembre"],monthsShort:["Gen","Feb","Mar","Abr","Mai","Jun","Jul","Ago","Set","Oct","Nov","Des"],today:"Avui",monthsTitle:"Mesos",clear:"Esborrar",weekStart:1,format:"dd/mm/yyyy"}}(jQuery);
!function(a){a.fn.datepicker.dates.ca={days:["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],daysShort:["dg.","dl.","dt.","dc.","dj.","dv.","ds."],daysMin:["dg","dl","dt","dc","dj","dv","ds"],months:["gener","febrer","març","abril","maig","juny","juliol","agost","setembre","octubre","novembre","desembre"],monthsShort:["gen.","febr.","març","abr.","maig","juny","jul.","ag.","set.","oct.","nov.","des."],today:"Avui",monthsTitle:"Mesos",clear:"Esborra",weekStart:1,format:"dd/mm/yyyy"}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.de={days:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],daysShort:["Son","Mon","Die","Mit","Don","Fre","Sam"],daysMin:["So","Mo","Di","Mi","Do","Fr","Sa"],months:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",monthsTitle:"Monate",clear:"Löschen",weekStart:1,format:"dd.mm.yyyy"}}(jQuery);
!function(a){a.fn.datepicker.dates.de={days:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],daysShort:["So","Mo","Di","Mi","Do","Fr","Sa"],daysMin:["So","Mo","Di","Mi","Do","Fr","Sa"],months:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",monthsTitle:"Monate",clear:"Löschen",weekStart:1,format:"dd.mm.yyyy"}}(jQuery);

View File

@@ -0,0 +1 @@
!function(a){a.fn.datepicker.dates["en-US"]={days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",monthsTitle:"Months",clear:"Clear",weekStart:0,format:"m/d/yyyy"}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.fi={days:["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"],daysShort:["sun","maa","tii","kes","tor","per","lau"],daysMin:["su","ma","ti","ke","to","pe","la"],months:["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu"],monthsShort:["tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mar","jou"],today:"tänään",clear:"Tyhjennä",weekStart:1,format:"d.m.yyyy"}}(jQuery);
!function(a){a.fn.datepicker.dates.fi={days:["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"],daysShort:["sun","maa","tii","kes","tor","per","lau"],daysMin:["su","ma","ti","ke","to","pe","la"],months:["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu"],monthsShort:["tammi","helmi","maalis","huhti","touko","kesä","hei","elo","syys","loka","marras","joulu"],today:"tänään",clear:"Tyhjennä",weekStart:1,format:"d.m.yyyy"}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.id={days:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],daysShort:["Mgu","Sen","Sel","Rab","Kam","Jum","Sab"],daysMin:["Mg","Sn","Sl","Ra","Ka","Ju","Sa"],months:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"],monthsShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Ags","Sep","Okt","Nov","Des"],today:"Hari Ini",clear:"Kosongkan"}}(jQuery);
!function(a){a.fn.datepicker.dates.id={days:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],daysShort:["Min","Sen","Sel","Rab","Kam","Jum","Sab"],daysMin:["Mg","Sn","Sl","Rb","Km","Jm","Sb"],months:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"],monthsShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agt","Sep","Okt","Nov","Des"],today:"Hari Ini",monthsTitle:"Bulan",clear:"Kosongkan",weekStart:0,format:"dd-mm-yyyy"}}(jQuery);

View File

@@ -0,0 +1 @@
!function(a){a.fn.datepicker.dates.mar={days:["रविवार","सोमवार","मंगळवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"],daysShort:["रवि","सोम","मंगळ","बुध","गुरु","शुक्र","शनि"],daysMin:["र","सो","मं","बु","गु","शु","श"],months:["जानेवारी","फेब्रुवारी","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टेंबर","ऑक्टोबर","नोव्हेंबर","डिसेंबर"],monthsShort:["जाने.","फेब्रु.","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टें.","ऑक्टो.","नोव्हें.","डिसें."],today:"आज",monthsTitle:"महीने",clear:"हटवा",weekStart:1,format:"dd / mm / yyyy"}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.uk={days:["Неділя","Понеділок","Вівторок","Середа","Четвер","П'ятниця","Субота"],daysShort:["Нед","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Cічень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],monthsShort:["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру"],today:"Сьогодні",clear:"Очистити",format:"dd.mm.yyyy",weekStart:1}}(jQuery);
!function(a){a.fn.datepicker.dates.uk={days:["Неділя","Понеділок","Вівторок","Середа","Четвер","П'ятниця","Субота"],daysShort:["Нед","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],monthsShort:["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру"],today:"Сьогодні",clear:"Очистити",format:"dd.mm.yyyy",weekStart:1}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates["zh-TW"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["週日","週一","週二","週三","週四","週五","週六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",format:"yyyymmdd",weekStart:1,clear:"清除"}}(jQuery);
!function(a){a.fn.datepicker.dates["zh-TW"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["週日","週一","週二","週三","週四","週五","週六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"月份",format:"yyyy/mm/dd",weekStart:0,titleFormat:"yyyy年mm月",clear:"清除"}}(jQuery);

File diff suppressed because one or more lines are too long

View File

@@ -31,7 +31,6 @@ Michael Bensoussan <mickey@seesmic.com>
Louis-Rémi Babé <lrbabe@gmail.com>
Robert Katić <robert.katic@gmail.com>
Damian Janowski <damian.janowski@gmail.com>
Anton Kovalyov <anton@kovalyov.net>
Dušan B. Jovanovic <dbjdbj@gmail.com>
Earle Castledine <mrspeaker@gmail.com>
Rich Dougherty <rich@rd.gen.nz>
@@ -69,11 +68,11 @@ temp01 <temp01irc@gmail.com>
Colin Snover <github.com@zetafleet.com>
Jared Grippe <jared@deadlyicon.com>
Ryan W Tenney <ryan@10e.us>
Alex Sexton <AlexSexton@gmail.com>
Pinhook <contact@pinhooklabs.com>
Ron Otten <r.j.g.otten@gmail.com>
Jephte Clain <Jephte.Clain@univ-reunion.fr>
Anton Matzneller <obhvsbypqghgc@gmail.com>
Alex Sexton <AlexSexton@gmail.com>
Dan Heberden <danheberden@gmail.com>
Henri Wiechers <hwiechers@gmail.com>
Russell Holbrook <russell.holbrook@patch.com>
@@ -87,9 +86,10 @@ Sylvester Keil <sylvester@keil.or.at>
Brandon Sterne <bsterne@mozilla.com>
Mathias Bynens <mathias@qiwi.be>
Lee Carpenter <elcarpie@gmail.com>
Timmy Willison <4timmywil@gmail.com>
Timmy Willison <timmywil@users.noreply.github.com>
Corey Frang <gnarf37@gmail.com>
Digitalxero <digitalxero>
Anton Kovalyov <anton@kovalyov.net>
David Murdoch <david@davidmurdoch.com>
Josh Varner <josh.varner@gmail.com>
Charles McNulty <cmcnulty@kznf.com>
@@ -111,7 +111,7 @@ Mike Sherov <mike.sherov@gmail.com>
Greg Hazel <ghazel@gmail.com>
Schalk Neethling <schalk@ossreleasefeed.com>
Denis Knauf <Denis.Knauf@gmail.com>
Timo Tijhof <krinklemail@gmail.com>
Timo Tijhof <krinkle@fastmail.com>
Steen Nielsen <swinedk@gmail.com>
Anton Ryzhov <anton@ryzhov.me>
Shi Chuan <shichuanr@gmail.com>
@@ -151,7 +151,6 @@ Chris Faulkner <thefaulkner@gmail.com>
Marcel Greter <marcel.greter@ocbnet.ch>
Elijah Manor <elijah.manor@gmail.com>
Daniel Chatfield <chatfielddaniel@gmail.com>
Daniel Gálvez <dgalvez@editablething.com>
Nikita Govorov <nikita.govorov@gmail.com>
Wesley Walser <waw325@gmail.com>
Mike Pennisi <mike@mikepennisi.com>
@@ -162,9 +161,7 @@ Dave Riddle <david@joyvuu.com>
Callum Macrae <callum@lynxphp.com>
Jonathan Sampson <jjdsampson@gmail.com>
Benjamin Truyman <bentruyman@gmail.com>
Jay Merrifield <fracmak@gmail.com>
James Huston <james@jameshuston.net>
Sai Lung Wong <sai.wong@huffingtonpost.com>
Erick Ruiz de Chávez <erickrdch@gmail.com>
David Bonner <dbonner@cogolabs.com>
Allen J Schmidt Jr <cobrasoft@gmail.com>
@@ -174,8 +171,11 @@ Ismail Khair <ismail.khair@gmail.com>
Carl Danley <carldanley@gmail.com>
Mike Petrovich <michael.c.petrovich@gmail.com>
Greg Lavallee <greglavallee@wapolabs.com>
Daniel Gálvez <dgalvez@editablething.com>
Sai Lung Wong <sai.wong@huffingtonpost.com>
Tom H Fuertes <TomFuertes@gmail.com>
Roland Eckl <eckl.roland@googlemail.com>
Jay Merrifield <fracmak@gmail.com>
Yiming He <yiminghe@gmail.com>
David Fox <dfoxinator@gmail.com>
Bennett Sorbo <bsorbo@gmail.com>
@@ -192,9 +192,9 @@ Diego Tres <diegotres@gmail.com>
Jean Boussier <jean.boussier@gmail.com>
Andrew Plummer <plummer.andrew@gmail.com>
Mark Raddatz <mraddatz@gmail.com>
Pascal Borreli <pascal@borreli.com>
Isaac Z. Schlueter <i@izs.me>
Karl Sieburg <ksieburg@yahoo.com>
Pascal Borreli <pascal@borreli.com>
Nguyen Phuc Lam <ruado1987@gmail.com>
Dmitry Gusev <dmitry.gusev@gmail.com>
Steven Benner <admin@stevenbenner.com>
@@ -202,7 +202,6 @@ Li Xudong <istonelee@gmail.com>
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Renato Oliveira dos Santos <ros3@cin.ufpe.br>
Frederic Junod <frederic.junod@camptocamp.com>
Tom H Fuertes <tomfuertes@gmail.com>
Mitch Foley <mitch@thefoley.net>
ros3cin <ros3@cin.ufpe.br>
Kyle Robinson Young <kyle@dontkry.com>
@@ -250,7 +249,6 @@ Dan Hart <danhart@notonthehighstreet.com>
Nazar Mokrynskyi <nazar@mokrynskyi.com>
Benjamin Tan <demoneaux@gmail.com>
Amit Merchant <bullredeyes@gmail.com>
Jason Bedard <jason+github@jbedard.ca>
Veaceslav Grimalschi <grimalschi@yandex.ru>
Richard McDaniel <rm0026@uah.edu>
Arthur Verschaeve <contact@arthurverschaeve.be>
@@ -273,12 +271,12 @@ Jon Hester <jon.d.hester@gmail.com>
Colin Frick <colin@bash.li>
Winston Howes <winstonhowes@gmail.com>
Alexander O'Mara <me@alexomara.com>
Chris Rebert <github@rebertia.com>
Bastian Buchholz <buchholz.bastian@googlemail.com>
Mu Haibao <mhbseal@163.com>
Calvin Metcalf <calvin.metcalf@gmail.com>
Arthur Stolyar <nekr.fabula@gmail.com>
Gabriel Schulhof <gabriel.schulhof@intel.com>
Chris Rebert <github@rebertia.com>
Gilad Peleg <giladp007@gmail.com>
Julian Alexander Murillo <julian.alexander.murillo@gmail.com>
Kevin Kirsche <Kev.Kirsche+GitHub@gmail.com>
@@ -297,15 +295,14 @@ Christian Grete <webmaster@christiangrete.com>
Tom von Clef <thomas.vonclef@gmail.com>
Liza Ramo <liza.h.ramo@gmail.com>
Joelle Fleurantin <joasqueeniebee@gmail.com>
Steve Mao <maochenyan@gmail.com>
Jon Dufresne <jon.dufresne@gmail.com>
Jae Sung Park <alberto.park@gmail.com>
Josh Soref <apache@soref.com>
Saptak Sengupta <saptak013@gmail.com>
Henry Wong <henryw4k@gmail.com>
Jun Sun <klsforever@gmail.com>
Martijn W. van der Lee <martijn@vanderlee.com>
Devin Wilson <dwilson6.github@gmail.com>
Steve Mao <maochenyan@gmail.com>
Damian Senn <jquery@topaxi.codes>
Zack Hall <zackhall@outlook.com>
Vitaliy Terziev <vitaliyterziev@gmail.com>
@@ -336,6 +333,7 @@ Jordan Beland <jordan.beland@gmail.com>
Henry Zhu <hi@henryzoo.com>
Nilton Cesar <niltoncms@gmail.com>
basil.belokon <basil.belokon@gmail.com>
Saptak Sengupta <saptak013@gmail.com>
Andrey Meshkov <ay.meshkov@gmail.com>
tmybr11 <tomas.perone@gmail.com>
Luis Emilio Velasco Sanchez <emibloque@gmail.com>
@@ -344,14 +342,34 @@ Bert Zhang <enbo@users.noreply.github.com>
Sébastien Règne <regseb@users.noreply.github.com>
wartmanm <3869625+wartmanm@users.noreply.github.com>
Siddharth Dungarwal <sd5869@gmail.com>
abnud1 <ahmad13932013@hotmail.com>
Andrei Fangli <andrei_fangli@outlook.com>
Marja Hölttä <marja.holtta@gmail.com>
abnud1 <ahmad13932013@hotmail.com>
buddh4 <mail@jharrer.de>
Hoang <dangkyokhoang@gmail.com>
Sean Robinson <sean.robinson@scottsdalecc.edu>
Wonseop Kim <wonseop.kim@samsung.com>
Pat O'Callaghan <patocallaghan@gmail.com>
JuanMa Ruiz <ruizjuanma@gmail.com>
Ahmed.S.ElAfifi <ahmed.s.elafifi@gmail.com>
Sean Robinson <sean.robinson@scottsdalecc.edu>
Christian Oliff <christianoliff@pm.me>
Christian Wenz <christian@wenz.org>
Jonathan <vanillajonathan@users.noreply.github.com>
Ed Sanders <ejsanders@gmail.com>
Pierre Grimaud <grimaud.pierre@gmail.com>
Beatriz Rezener <beatrizrezener@users.noreply.github.com>
Necmettin Karakaya <necmettin.karakaya@gmail.com>
Wonhyoung Park <wh05.park@samsung.com>
Dallas Fraser <dallas.fraser.waterloo@gmail.com>
高灰 <www@zeroplace.cn>
fecore1 <89127124+fecore1@users.noreply.github.com>
ygj6 <7699524+ygj6@users.noreply.github.com>
Bruno PIERRE <brunopierre4@yahoo.fr>
Simon Legner <Simon.Legner@gmail.com>
Baoshuo Ren <i@baoshuo.ren>
Anders Kaseorg <andersk@mit.edu>
Alex <aleksandrosansan@gmail.com>
Gabriela Gutierrez <gabigutierrez@google.com>
Dimitri Papadopoulos Orfanos <3234522+DimitriPapadopoulos@users.noreply.github.com>
J.Son <x@x-wx.com>
Liam James <liam@minimaximize.com>

File diff suppressed because one or more lines are too long

View File

@@ -2,6 +2,6 @@
"version": 3,
"sources": ["../../../srcts/extras/shiny-autoreload.ts"],
"sourcesContent": ["/* eslint-disable unicorn/filename-case */\n\ndocument.documentElement.classList.add(\"autoreload-enabled\");\n\nconst protocol = window.location.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n// Add trailing slash to path, if necessary, before appending \"autoreload\"\nconst defaultPath =\n window.location.pathname.replace(/\\/?$/, \"/\") + \"autoreload/\";\nconst defaultUrl = `${protocol}//${window.location.host}${defaultPath}`;\n\n// By default, use the defaultUrl. But if there's a data-ws-url attribute on our\n// <script> tag, use that instead.\nconst wsUrl = document.currentScript?.dataset?.wsUrl || defaultUrl;\n\n/**\n * Connects to an autoreload URL and waits for the server to tell us what to do.\n *\n * @param url The ws:// or wss:// URL to connect to.\n * @returns true if the server requests a reload, or false if the connection was\n * successfully established but then closed without the server requesting a\n * reload\n * @throws A nondescript error if the connection fails to be established.\n */\nasync function autoreload(url: string): Promise<boolean> {\n const ws = new WebSocket(url);\n\n let success = false;\n\n return new Promise((resolve, reject) => {\n ws.onopen = () => {\n success = true;\n };\n\n ws.onerror = (err) => {\n reject(err);\n };\n\n ws.onclose = () => {\n if (!success) {\n reject(new Error(\"WebSocket connection failed\"));\n } else {\n resolve(false);\n }\n };\n\n ws.onmessage = function (event) {\n if (event.data === \"autoreload\") {\n resolve(true);\n }\n };\n });\n}\n\nasync function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function initialize() {\n while (true) {\n try {\n if (await autoreload(wsUrl)) {\n window.location.reload();\n return;\n }\n } catch (err) {\n // It's possible for the autoreload() call to throw. If it does, that\n // means we tried but failed to connect to the autoreload socket. This\n // probably means that the entire `shiny run --reload` process was\n // restarted. As of today, the autoreload websocket port number is\n // randomly chosen for each `shiny run --reload` process, so it's\n // impossible for us to recover.\n console.debug(\"Giving up on autoreload\");\n return;\n }\n // If we get here, the connection to the autoreload server was\n // successful but then got broken. Wait for a second, and then\n // try to re-establish the connection.\n await sleep(1000);\n }\n}\n\ninitialize().catch((err) => {\n console.error(err);\n});\n\nexport {};\n"],
"mappings": ";mBAEA,SAAS,gBAAgB,UAAU,IAAI,oBAAoB,EAE3D,IAAMA,EAAW,OAAO,SAAS,WAAa,SAAW,OAAS,MAE5DC,EACJ,OAAO,SAAS,SAAS,QAAQ,OAAQ,GAAG,EAAI,cAC5CC,EAAa,GAAGF,MAAa,OAAO,SAAS,OAAOC,IAIpDE,EAAQ,SAAS,eAAe,SAAS,OAASD,EAWxD,eAAeE,EAAWC,EAA+B,CACvD,IAAMC,EAAK,IAAI,UAAUD,CAAG,EAExBE,EAAU,GAEd,OAAO,IAAI,QAAQ,CAACC,EAASC,IAAW,CACtCH,EAAG,OAAS,IAAM,CAChBC,EAAU,EACZ,EAEAD,EAAG,QAAWI,GAAQ,CACpBD,EAAOC,CAAG,CACZ,EAEAJ,EAAG,QAAU,IAAM,CACZC,EAGHC,EAAQ,EAAK,EAFbC,EAAO,IAAI,MAAM,6BAA6B,CAAC,CAInD,EAEAH,EAAG,UAAY,SAAUK,EAAO,CAC1BA,EAAM,OAAS,cACjBH,EAAQ,EAAI,CAEhB,CACF,CAAC,CACH,CAEA,eAAeI,EAAMC,EAAY,CAC/B,OAAO,IAAI,QAASL,GAAY,WAAWA,EAASK,CAAE,CAAC,CACzD,CAEA,eAAeC,GAAa,CAC1B,OAAa,CACX,GAAI,CACF,GAAI,MAAMV,EAAWD,CAAK,EAAG,CAC3B,OAAO,SAAS,OAAO,EACvB,MACF,CACF,MAAE,CAOA,QAAQ,MAAM,yBAAyB,EACvC,MACF,CAIA,MAAMS,EAAM,GAAI,CAClB,CACF,CAEAE,EAAW,EAAE,MAAOJ,GAAQ,CAC1B,QAAQ,MAAMA,CAAG,CACnB,CAAC",
"mappings": ";mBAEA,SAAS,gBAAgB,UAAU,IAAI,oBAAoB,EAE3D,IAAMA,EAAW,OAAO,SAAS,WAAa,SAAW,OAAS,MAE5DC,EACJ,OAAO,SAAS,SAAS,QAAQ,OAAQ,GAAG,EAAI,cAC5CC,EAAa,GAAGF,CAAQ,KAAK,OAAO,SAAS,IAAI,GAAGC,CAAW,GAI/DE,EAAQ,SAAS,eAAe,SAAS,OAASD,EAWxD,eAAeE,EAAWC,EAA+B,CACvD,IAAMC,EAAK,IAAI,UAAUD,CAAG,EAExBE,EAAU,GAEd,OAAO,IAAI,QAAQ,CAACC,EAASC,IAAW,CACtCH,EAAG,OAAS,IAAM,CAChBC,EAAU,EACZ,EAEAD,EAAG,QAAWI,GAAQ,CACpBD,EAAOC,CAAG,CACZ,EAEAJ,EAAG,QAAU,IAAM,CACZC,EAGHC,EAAQ,EAAK,EAFbC,EAAO,IAAI,MAAM,6BAA6B,CAAC,CAInD,EAEAH,EAAG,UAAY,SAAUK,EAAO,CAC1BA,EAAM,OAAS,cACjBH,EAAQ,EAAI,CAEhB,CACF,CAAC,CACH,CAEA,eAAeI,EAAMC,EAAY,CAC/B,OAAO,IAAI,QAASL,GAAY,WAAWA,EAASK,CAAE,CAAC,CACzD,CAEA,eAAeC,GAAa,CAC1B,OAAa,CACX,GAAI,CACF,GAAI,MAAMV,EAAWD,CAAK,EAAG,CAC3B,OAAO,SAAS,OAAO,EACvB,MACF,CACF,MAAc,CAOZ,QAAQ,MAAM,yBAAyB,EACvC,MACF,CAIA,MAAMS,EAAM,GAAI,CAClB,CACF,CAEAE,EAAW,EAAE,MAAOJ,GAAQ,CAC1B,QAAQ,MAAMA,CAAG,CACnB,CAAC",
"names": ["protocol", "defaultPath", "defaultUrl", "wsUrl", "autoreload", "url", "ws", "success", "resolve", "reject", "err", "event", "sleep", "ms", "initialize"]
}

View File

@@ -1,3 +1,3 @@
/*! shiny 1.11.1.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
"use strict";(()=>{var f=400;function c(e,i){let t=0;if(e.nodeType===3){let n=e.nodeValue.replace(/\n/g,"").length;if(n>=i)return{element:e,offset:i};t+=n}else if(e.nodeType===1&&e.firstChild){let n=c(e.firstChild,i);if(n.element!==null)return n;t+=n.offset}return e.nextSibling?c(e.nextSibling,i-t):{element:null,offset:t}}function r(e,i,t){let n=0;for(let s=0;s<e.childNodes.length;s++){let l=e.childNodes[s];if(l.nodeType===3){let o=/\n/g,d;for(;(d=o.exec(l.nodeValue))!==null;)if(n++,n===i)return c(l,d.index+t+1)}else if(l.nodeType===1){let o=r(l,i-n,t);if(o.element!==null)return o;n+=o.offset}}return{element:null,offset:n}}function w(e,i){if(!document.createRange)return;let t=document.getElementById("srcref_"+e);if(!t){t=document.createElement("span"),t.id="srcref_"+e;let n=e,s=document.getElementById(i.replace(/\./g,"_")+"_code");if(!s)return;let l=r(s,n[0],n[4]),o=r(s,n[2],n[5]);if(l.element===null||o.element===null)return;let d=document.createRange();l.element.parentNode.nodeName==="SPAN"&&l.element!==o.element?d.setStartBefore(l.element.parentNode):d.setStart(l.element,l.offset),o.element.parentNode.nodeName==="SPAN"&&l.element!==o.element?d.setEndAfter(o.element.parentNode):d.setEnd(o.element,o.offset),d.surroundContents(t)}$(t).stop(!0,!0).effect("highlight",null,1600)}Shiny&&Shiny.addCustomMessageHandler("showcase-src",function(e){e.srcref&&e.srcfile&&w(e.srcref,e.srcfile)});var a=!1,m=function(e,i){let t=i?f:1,n=e?document.getElementById("showcase-sxs-code"):document.getElementById("showcase-code-inline"),s=e?document.getElementById("showcase-code-inline"):document.getElementById("showcase-sxs-code");if(document.getElementById("showcase-app-metadata")===null){let o=$("#showcase-well");e?o.fadeOut(t):o.fadeIn(t)}$(n).hide(),$(s).fadeOut(t,function(){let o=document.getElementById("showcase-code-tabs");s.removeChild(o),n.appendChild(o),e?h():document.getElementById("showcase-code-content").removeAttribute("style"),$(n).fadeIn(t),e||(document.getElementById("showcase-app-container").removeAttribute("style"),i&&$(document.body).animate({scrollTop:$(n).offset().top}));let d=document.getElementById("readme-md");d!==null&&(d.parentElement.removeChild(d),e?(s.appendChild(d),$(s).fadeIn(t)):document.getElementById("showcase-app-metadata").appendChild(d)),document.getElementById("showcase-code-position-toggle").innerHTML=e?'<i class="fa fa-level-down"></i> show below':'<i class="fa fa-level-up"></i> show with app'}),e&&$(document.body).animate({scrollTop:0},t),a=e,u(e&&i),$(window).trigger("resize")};function u(e){let t=960,n=1,s=document.getElementById("showcase-app-code").offsetWidth;s/2>960?t=s/2:s*.66>960?t=960:(t=s*.66,n=t/960);let l=document.getElementById("showcase-app-container");$(l).animate({width:t+"px",zoom:n*100+"%"},e?f:0)}var g=function(){m(!a,!0)},p=function(){document.body.offsetWidth>1350&&m(!0,!1)};function h(){document.getElementById("showcase-code-content").style.height=$(window).height()+"px"}function y(){let e=document.getElementById("showcase-markdown-content");if(e!==null){let i=e.innerText||e.innerHTML,t=window.Showdown.converter;document.getElementById("readme-md").innerHTML=new t().makeHtml(i)}}$(window).resize(function(){a&&(u(!1),h())});window.toggleCodePosition=g;$(window).on("load",p);$(window).on("load",y);window.hljs&&window.hljs.initHighlightingOnLoad();})();
"use strict";(()=>{var m=400;function c(e,l){let t=0;if(e.nodeType===3){let n=e.nodeValue?.replace(/\n/g,"").length??0;if(n>=l)return{element:e,offset:l};t+=n}else if(e.nodeType===1&&e.firstChild){let n=c(e.firstChild,l);if(n.element!==null)return n;t+=n.offset}return e.nextSibling?c(e.nextSibling,l-t):{element:null,offset:t}}function r(e,l,t){let n=0;for(let s=0;s<e.childNodes.length;s++){let i=e.childNodes[s];if(i.nodeType===3){let o=/\n/g,d;for(;(d=o.exec(i.nodeValue))!==null;)if(n++,n===l)return c(i,d.index+t+1)}else if(i.nodeType===1){let o=r(i,l-n,t);if(o.element!==null)return o;n+=o.offset}}return{element:null,offset:n}}function p(e,l){if(!document.createRange)return;let t=document.getElementById("srcref_"+e);if(!t){t=document.createElement("span"),t.id="srcref_"+e;let n=e,s=document.getElementById(l.replace(/\./g,"_")+"_code");if(!s)return;let i=r(s,n[0],n[4]),o=r(s,n[2],n[5]);if(i.element===null||o.element===null)return;let d=document.createRange();i.element.parentNode?.nodeName==="SPAN"&&i.element!==o.element?d.setStartBefore(i.element.parentNode):d.setStart(i.element,i.offset),o.element.parentNode?.nodeName==="SPAN"&&i.element!==o.element?d.setEndAfter(o.element.parentNode):d.setEnd(o.element,o.offset),d.surroundContents(t)}$(t).stop(!0,!0).effect("highlight",null,1600)}window.Shiny&&window.Shiny.addCustomMessageHandler("showcase-src",function(e){e.srcref&&e.srcfile&&p(e.srcref,e.srcfile)});var a=!1,u=function(e,l){let t=l?m:1,n=e?document.getElementById("showcase-sxs-code"):document.getElementById("showcase-code-inline"),s=e?document.getElementById("showcase-code-inline"):document.getElementById("showcase-sxs-code");if(document.getElementById("showcase-app-metadata")===null){let o=$("#showcase-well");e?o.fadeOut(t):o.fadeIn(t)}if(n===null||s===null){console.warn("Could not find the host elements for the code tabs. This is likely a bug in the showcase app.");return}$(n).hide(),$(s).fadeOut(t,function(){let o=document.getElementById("showcase-code-tabs");if(o===null){console.warn("Could not find the code tabs element. This is likely a bug in the showcase app.");return}if(s.removeChild(o),n.appendChild(o),e?w():document.getElementById("showcase-code-content")?.removeAttribute("style"),$(n).fadeIn(t),!e&&(document.getElementById("showcase-app-container")?.removeAttribute("style"),l)){let f=$(n).offset()?.top;f!==void 0&&$(document.body).animate({scrollTop:f})}let d=document.getElementById("readme-md");d!==null&&(d.parentElement?.removeChild(d),e?(s.appendChild(d),$(s).fadeIn(t)):document.getElementById("showcase-app-metadata")?.appendChild(d)),document.getElementById("showcase-code-position-toggle").innerHTML=e?'<i class="fa fa-level-down"></i> show below':'<i class="fa fa-level-up"></i> show with app'}),e&&$(document.body).animate({scrollTop:0},t),a=e,h(e&&l),$(window).trigger("resize")};function h(e){let t=960,n=1,s=document.getElementById("showcase-app-code").offsetWidth;s/2>960?t=s/2:s*.66>960?t=960:(t=s*.66,n=t/960),$("#showcase-app-container").animate({width:t+"px",zoom:n*100+"%"},e?m:0)}var g=function(){u(!a,!0)},y=function(){document.body.offsetWidth>1350&&u(!0,!1)};function w(){document.getElementById("showcase-code-content").style.height=$(window).height()+"px"}function E(){let e=document.getElementById("showcase-markdown-content");if(e!==null){let l=e.innerText||e.innerHTML,t=window.Showdown.converter;document.getElementById("readme-md").innerHTML=new t().makeHtml(l)}}$(window).resize(function(){a&&(h(!1),w())});window.toggleCodePosition=g;$(window).on("load",y);$(window).on("load",E);window.hljs&&window.hljs.initHighlightingOnLoad();})();
//# sourceMappingURL=shiny-showcase.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,4 @@
@use "sass:meta";
// DEFAULTS
$shiny-disconnected-bg: #999 !default;
$shiny-table-na: #909090 !default;
@@ -47,7 +48,7 @@ $shiny-file-over-shadow: inset 0 1px 1px rgba(black, .075), 0 0 8px r
// Both BS3 and BS4 define a border radius mixin, but just in case
// we're trying to compile this without bootstrapSass
@mixin border-radius-shim($radius) {
@if mixin-exists("border-radius") {
@if meta.mixin-exists("border-radius") {
@include border-radius($radius);
} @else {
border-radius: $radius;

View File

@@ -1,4 +0,0 @@
module.exports = {
preset: "ts-jest",
testEnvironment: "jsdom",
};

6336
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -15,80 +15,61 @@
"srcts/types/**/*.d.ts"
],
"engines": {
"node": ">= 14",
"yarn": ">= 1.22"
"node": ">= 18",
"npm": ">= 10"
},
"dependencies": {
"@types/bootstrap": "3.4.0",
"@types/bootstrap-datepicker": "0.0.14",
"@types/datatables.net": "^1.10.19",
"@types/bootstrap": "5.2.x",
"@types/bootstrap-datepicker": "1.10.0",
"@types/datatables.net": "1.10.x",
"@types/ion-rangeslider": "2.3.0",
"@types/jquery": "3.5.32",
"@types/selectize": "0.12.34",
"lit": "^3.0.0"
"@types/selectize": "0.12.x",
"lit": "3.2.x"
},
"devDependencies": {
"@deanc/esbuild-plugin-postcss": "^1.0.2",
"@selectize/selectize": "https://github.com/selectize/selectize.js.git#e3f2e0b4aa251375bc21b5fcd8ca7d374a921f08",
"@testing-library/dom": "^7.31.0",
"@testing-library/jest-dom": "^5.12.0",
"@testing-library/user-event": "^13.1.9",
"@types/highlightjs": "^9.12.1",
"@types/jest": "^26.0.23",
"@types/highlightjs": "9.x",
"@types/jqueryui": "1.12.24",
"@types/lodash": "^4.14.170",
"@types/node": "^18.14.2",
"@types/showdown": "^1.9.3",
"@typescript-eslint/eslint-plugin": "^5.38.1",
"@typescript-eslint/parser": "^5.38.1",
"autoprefixer": "^10.2.6",
"browserslist": "^4.19.1",
"caniuse-lite": "^1.0.30001312",
"core-js": "^3.13.0",
"esbuild": "^0.15.10",
"esbuild-plugin-globals": "^0.1.1",
"esbuild-plugin-sass": "^1.0.1",
"eslint": "^8.24.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-jest": "^27.0.4",
"eslint-plugin-jest-dom": "^4.0.2",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-unicorn": "^43.0.2",
"fs-readdir-recursive": "^1.1.0",
"jest": "^26.6.3",
"@types/lodash": "4.x",
"@types/node": "18.x",
"@types/showdown": "1.x",
"@typescript-eslint/eslint-plugin": "8.x",
"@typescript-eslint/parser": "8.x",
"autoprefixer": "10.x",
"bootstrap-datepicker": "1.10.0",
"esbuild": ">=0.20.0",
"esbuild-plugin-globals": "0.1.x",
"esbuild-sass-plugin": "3.x",
"eslint": "9.x",
"eslint-config-prettier": "10.x",
"eslint-plugin-prettier": "5.x",
"eslint-plugin-unicorn": "56.x",
"fs-readdir-recursive": "1.x",
"jquery": "3.7.1",
"lodash": "^4.17.21",
"madge": "^4.0.2",
"node-gyp": "^8.1.0",
"phantomjs-prebuilt": "^2.1.16",
"postcss": "^8.3.5",
"prettier": "^2.7.1",
"prettier-plugin-organize-imports": "^3.2.4",
"readcontrol": "^1.0.0",
"replace": "^1.2.1",
"ts-jest": "^26",
"ts-node": "^10.9.1",
"type-coverage": "^2.22.0",
"typescript": "^4.8.4",
"util-inspect": "https://github.com/deecewan/browser-util-inspect#c0b4350df4378ffd743e8c36dd3898ce3992823e"
"lodash": "4.x",
"postcss": "8.x",
"postcss-preset-env": "10.2.x",
"prettier": "3.x",
"prettier-plugin-organize-imports": "4.x",
"readcontrol": "1.x",
"tsx": "4.x",
"type-coverage": "2.29.x",
"typescript": "5.8.x"
},
"scripts": {
"prepare": "node --eval \"1+1; // help yarn users not install the whole repo; https://github.com/yarnpkg/yarn/issues/2822#issuecomment-847360267\"",
"watch": "yarn run build_shiny --watch",
"build": "yarn run build_shiny && yarn run bundle_extras && yarn run bundle_external_libs",
"build_shiny": "yarn run checks && yarn run bundle_shiny",
"bundle_shiny": "ts-node srcts/build/shiny.ts",
"bundle_external_libs": "ts-node srcts/build/external_libs.ts",
"bundle_extras": "ts-node srcts/build/extras.ts",
"test": "jest --coverage",
"test_phantom": "echo '\n\t!! Must manually stop phantomjs test !!\n\n' && yarn bundle_shiny && phantomjs --debug=yes ../inst/www/shared/shiny.js",
"checks": "yarn run lint && yarn run build_types && yarn run coverage && yarn run circular",
"lint": "node --eval \"console.log('linting code...')\" && eslint --fix --ext .ts srcts/src",
"watch": "npm run bundle_shiny -- --watch",
"build": "npm run build_shiny && npm run bundle_extras && npm run bundle_external_libs",
"build_shiny": "npm run checks && npm run bundle_shiny",
"bundle_shiny": "tsx srcts/build/shiny.ts",
"bundle_external_libs": "tsx srcts/build/external_libs.ts",
"bundle_extras": "tsx srcts/build/extras.ts",
"checks": "npm run lint && npm run build_types && npm run coverage && npm run circular",
"lint": "node --eval \"console.log('linting code...')\" && eslint 'srcts/src/**/*.ts' --fix",
"build_types": "tsc -p tsconfig.json",
"coverage_detailed": "yarn type-check --detail",
"coverage_detailed": "npx --yes type-check --detail",
"coverage": "type-coverage -p tsconfig.json --at-least 90",
"circular": "madge --circular --extensions ts srcts/src",
"circular_image": "madge --circular --extensions ts --image madge.svg srcts/src"
"circular": "npx --yes dpdm --transform ./srcts/src/index.ts"
},
"prettier": {
"plugins": [

View File

@@ -1,14 +1,12 @@
# Using Shiny TypeScript Definitions
When developing TypeScript projects that use `window.Shiny`, we recommend installing the Shiny TypeScript definitions to your package. To install the latest stable definitions, run one of the following (depending on if you're using `npm` or `yarn`):
When developing TypeScript projects that use `window.Shiny`, we recommend installing the Shiny TypeScript definitions to your package. To install the latest stable definitions, run:
```bash
npm install https://github.com/rstudio/shiny\#v1.11.1 --save-dev
# or
yarn add https://github.com/rstudio/shiny\#v1.11.1 --dev
npm install https://github.com/rstudio/shiny\#v1.11.0 --save-dev
```
, matching the GitHub tag to your current the Shiny CRAN release (ex: `v1.11.1`). If you are asked to select a version of `@types/jquery`, please select the closest matching version.
, matching the GitHub tag to your current the Shiny CRAN release (ex: `v1.11.0`). If you are asked to select a version of `@types/jquery`, please select the closest matching version.
This will provide a global type definition of `window.Shiny`. In your code, you can access the Shiny object via `window.Shiny` or just `Shiny`. However, note that if you are using TypeScript, it will be OK with `window.Shiny` but it will flag uses of `Shiny` (without the `window.` prefix), because TypeScript won't know that it's a global variable. We consider it better practice to use `window.Shiny` instead of `Shiny`, but if you want TypeScript to know that `Shiny` is available as a global variable, you can add the following to a TypeScript file in your code base.
@@ -28,31 +26,36 @@ When loading your compiled file, it should be loaded after `shiny.js` is loaded.
All files will be described as if the working directory is the root folder of `rstudio/shiny`, not relative to this `README.md` file.
## First-time setup
Shiny's TypeScript build tools use Node.js, along with [yarn](https://yarnpkg.com/) v2 to manage the JavaScript packages.
Shiny's TypeScript build tools use Node.js and `npm`.
Installation of Node.js differs across platforms, see [the official Node.js website](https://nodejs.org/) for instructions on downloading and installing. We presume that you have Node.js installed on your machine before continuing.
Install yarn using the [official instructions](https://yarnpkg.com/en/docs/install).
Install npm using the [official instructions](https://docs.npmjs.com/getting-started/installing-node).
You can test that Node.js and yarn are installed properly by running the following commands:
You can test that Node.js and `npm` are installed properly by running the following commands:
```bash
node --version
yarn --version
npm --version
```
Once both are installed, run the following in the root repo directory to install the packages :
```bash
# Sitting in `rstudio/shiny` repo
yarn install
npm install
```
### Yarn v2
### Reproducible builds
This repo uses Yarn v2. If you have the latest yarn installed from brew (v1.x), Yarn will pick up on the fact that this repo is a Yarn v2 (`berry`) repo.
To ensure that the same versions of packages are used between users, install the package lock dependencies by running:
For compatibility with `esbuild`, the `./node_modules` is still maintained.
```bash
npm ci
```
This command will install the exact versions of packages specified in the `package-lock.json` file, ensuring that all developers are using the same versions of dependencies.
## Updating Node
@@ -69,26 +72,22 @@ npx n ls
```
## Adding packages
If in the future you want to upgrade or add a package, run:
```bash
yarn add --dev [packagename]
npm install --save-dev [packagename]
```
This will automatically add the package to the dependencies in `package.json`, and it will also update the `yarn.lock` to reflect that change. If someone other than yourself does this, simply run `yarn` to update your local packages to match the new `package.json`.
This will automatically add the package to the dependencies in `package.json`, and it will also update the `package-lock.json` to reflect that change. If someone other than yourself does this, simply run `npm ci` to update your local packages to match the new `package.json`.
## Upgrading packages
Periodically, it's good to upgrade the packages to a recent version. There's two ways of doing this, depending on your intention:
1. Use `yarn up` to upgrade all dependencies to their latest version based on the version range specified in the package.json file (the `yarn.lock` file will be recreated as well. Yarn packages use [semantic versioning](https://yarnpkg.com/en/docs/dependency-versions), i.e. each version is writen with a maximum of 3 dot-separated numbers such that: `major.minor.patch`. For example in the version `3.1.4`, 3 is the major version number, 1 is the minor version number and 4 is the patch version number. Here are the most used operators (these appear before the version number):
1. Use `npm outdated` to see outdated dependencies based on the version range specified in the `package.json` file. Npm packages use [semantic versioning](https://docs.npmjs.com/about-semantic-versioning), i.e. each version is writen with a maximum of 3 dot-separated numbers such that: `major.minor.patch`. For example in the version `3.1.4`, 3 is the major version number, 1 is the minor version number and 4 is the patch version number. Please use an `x` to denote where packages can automatically bump their version. For example, `3.1.x` will accept any patch version for `3.1`. Or `3.x` to accept any v3 minor version.
- `~` is for upgrades that keep the minor version the same (assuming that was specified);
- `^` is for upgrades that keep the major version the same (more or less -- more specifically, it allow changes that do not modify the first non-zero digit in the version, either the 3 in 3.1.4 or the 4 in 0.4.2.). This is the default operator added to the package.json when you run `yarn add [package-name]`.
2. Use `yarn up [package]` to upgrade a single named package to the version specified by the latest tag (potentially upgrading the package across major versions).
3. To see all outdated packages, run `yarn outdated`
2. Use `npm update [package]` to upgrade a single named package to the version specified by the latest tag (potentially upgrading the package across major versions).
# TypeScript
@@ -148,25 +147,16 @@ The JavaScript community likes to build many small, effective packages that do m
All config files are located in the root folder to avoid opening two separate VS Code projects.
* `.browserslistrc`
* Used with `browserslist` and `core-js` to determine which polyfills should be incorporated.
* `.eslintrc.yml`
* Used with `eslint` and `prettier` to determine how the TypeScript files should be formatted and which lint failures should cause warnings, errors, or be ignored.
* `.madgerc`
* Package used to determine if circular dependencies are found. `type` only imports are ignored as they are not included in the final bundle.
* `.prettierrc.yml`
* Used by `prettier` to know how to adjust code when a file is saved in VSCode or within `eslint`'s linting process.
* `yarnrc.yml`
* Notifies `yarn` to use `yarn` v2, install `./node_modules` folder for `esbuild`, and any CLI plugins.
* `jest.config.js`
* Used to configure [`jest` testing](https://jestjs.io/)
* `package.json`
* Contains useful scripts that can be run by `yarn` via `yarn run SCRIPTNAME`.
* Contains useful scripts that can be run by `npm` via `npm run SCRIPTNAME`.
* The scripts described below are inteded for developer use. All other scripts are means to an end.
* `yarn run watch` - Watch `srcts/src` for changes and rebuild the JavaScript files.
* `yarn run build` - Build `shiny.js` and `shiny.min.js` in `inst/www/shared`. Both files will have a corresponding sourcemap
* `yarn run lint` - Fix all TypeScript lints using [`eslint`](https://eslint.org/) and [`prettier`](https://prettier.io/)
* `yarn run test` - Run all TypeScript tests
* `npm run watch` - Watch `srcts/src` for changes and rebuild the JavaScript files.
* `npm run build` - Build `shiny.js` and `shiny.min.js` in `inst/www/shared`. Both files will have a corresponding sourcemap
* `npm run lint` - Fix all TypeScript lints using [`eslint`](https://eslint.org/) and [`prettier`](https://prettier.io/)
* `tsconfig.json` -
* TypeScript config file
* Notable options set:
@@ -181,13 +171,13 @@ All config files are located in the root folder to avoid opening two separate VS
To run all build tasks, run:
```bash
yarn build
npm run build
```
It's also useful to have `esbuild` watch for updated files and immediately re-build `shiny.js` as necessary during development. This is done with:
```bash
yarn watch
npm run watch
```
Both JavaScript files will produce a sourcemap (`**.js.map`) that the browser will understand. This will help you debug Shiny's JavaScript code within the browser and point back to the original TypeScript files.
@@ -200,40 +190,8 @@ Both JavaScript files will produce a sourcemap (`**.js.map`) that the browser wi
On push to the `main` branch or push to a Pull Request to the `main` branch, a GitHub Action will be run to make sure the bundled JavaScript code is up to date. If the source code does not compile to the exact same file, it will be committed an pushed back to the outdated branch. (This makes it so the full build tools are not necessary for small tweaks and comments. 🎉)
<!-- #### Auto build and browser refresh
An alternative to `yarn watch` is to use `entr` to trigger `grunt` when sources change. `entr` can be installed with `brew install entr` on a Mac, or on Linux using your distribution's package manager. Using this technique, it's possible to both automatically rebuild sources and reload Chrome at the same time:
*macOS*:
```bash
find ../srcts/ | entr bash -c './node_modules/grunt/bin/grunt && osascript -e "tell application \"Google Chrome\" to reload active tab of window 1"'
```
*Linux*:
For this to work you must first install `xdotool` using your distribution's package manager.
```bash
find ../srcts/ | entr bash -c './node_modules/grunt/bin/grunt && xdotool search --onlyvisible --class Chrome windowfocus key ctrl+r'
``` -->
# Updating dependencies
### `@types/jquery`
As of v3.5.5, `@types/jquery` produces a globally available constant of `$` and `jQuery`. This is problematic as TypeScript is there to enforce that all variables are accounted for. Declaring that these two variables exist globally removes the requirement to import `$` (or `jQuery`). This is bad for Shiny as the `$` would not be enforced to the "within package" `$`.
To overcome this, a patch is used to remove the globally defined `$` (and `Symbol`) variable declarations. Yarn v2 has a [`patch` protocol](https://yarnpkg.com/features/protocols#patch) that allows a local patch to be applied to the publically available `@types/jquery` package upon installation.
If in the future where the variables are not globally declared anymore, the patch may be removed and `@types/jquery` can be imported directly.
A global module plugin is used by `esbuild` to swap out a real `jquery` module to just return `window.jQuery`. This allows for tests and core code to behave the same way.
### `core-js`
To update the version of `core-js`:
* Check if there is a newer version available by running `yarn outdated core-js`. (If there's no output, then you have the latest version.)
* Run `yarn add --dev core-js --exact`.
### External libraries
@@ -245,3 +203,4 @@ Shiny already has a handful of html dependencies that should NOT be bundled with
* `bootstrap-datepicker` / `@types/bootstrap-datepicker`
* `ion-rangeslider` / `@types/ion-rangeslider`
* `selectize` / `@types/selectize`
* `strftime`

View File

@@ -1,11 +1,5 @@
import type {
BuildFailure,
BuildIncremental,
BuildOptions,
BuildResult,
WatchMode,
} from "esbuild";
import { build as esbuildBuild } from "esbuild";
import type { BuildOptions } from "esbuild";
import esbuild from "esbuild";
import { basename } from "path";
import process from "process";
@@ -29,9 +23,7 @@ const banner = {
css: bannerTxt,
};
async function build(
opts: BuildOptions
): Promise<BuildIncremental | BuildResult> {
async function build(opts: BuildOptions): Promise<void> {
const outFileNames = opts.outfile
? [basename(opts.outfile)]
: (opts.entryPoints as string[]).map((entry) => basename(entry));
@@ -48,7 +40,7 @@ async function build(
}
}
const onRebuild = function (error: BuildFailure | null) {
const onRebuild = function (error: any | null) {
if (error) {
console.error(printNames.join(", "), "watch build failed:\n", error);
} else {
@@ -59,29 +51,26 @@ async function build(
return;
};
let incremental = false;
let watch: WatchMode | false = false;
if (process.argv.length >= 3 && process.argv[2] == "--watch") {
incremental = true;
watch = {
onRebuild: onRebuild,
};
}
const watch = process.argv.length >= 3 && process.argv[2] == "--watch";
outFileNames.map((outFileName) => {
console.log("Building " + outFileName);
});
return esbuildBuild({
incremental: incremental,
watch: watch,
const ctx = await esbuild.context({
target: "es2021",
preserveSymlinks: true,
...opts,
}).then((x) => {
onRebuild(null);
return x;
});
if (watch) {
await ctx.watch();
onRebuild(null);
} else {
await ctx.rebuild();
onRebuild(null);
await ctx.dispose();
}
}
export { outDir, build, shinyDesc, banner };
export { banner, build, outDir, shinyDesc };

View File

@@ -1,11 +1,11 @@
// This build script must be executed from the root repo directory via
// ```
// yarn build
// npm run build
// ```
import { build, outDir } from "./_build";
import { readdir, unlink, writeFile } from "fs/promises";
import globalsPlugin from "esbuild-plugin-globals";
import { readdir, unlink, writeFile } from "fs/promises";
import { build, outDir } from "./_build";
const opts = {
bundle: false,

View File

@@ -1,63 +1,76 @@
// This build script must be executed from the root repo directory via
// ```
// yarn build
// npm run build
// ```
// - TypeScript -----------------------------------------------------------
import { banner, build, outDir } from "./_build";
build({
bundle: true,
sourcemap: true,
minify: true,
plugins: [],
banner: banner,
entryPoints: [
"srcts/extras/shiny-autoreload.ts",
"srcts/extras/shiny-showcase.ts",
"srcts/extras/shiny-testmode.ts",
],
outdir: outDir,
});
// - Sass -----------------------------------------------------------
import autoprefixer from "autoprefixer";
import sassPlugin from "esbuild-plugin-sass";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore; Type definitions are not found. This occurs when `strict: true` in tsconfig.json
import postCssPlugin from "@deanc/esbuild-plugin-postcss";
import { sassPlugin } from "esbuild-sass-plugin";
import postcss from "postcss";
import postcssPresetEnv from "postcss-preset-env";
import { banner, build, outDir } from "./_build.js";
const sassOpts = {
minify: true,
banner: banner,
plugins: [
sassPlugin(),
postCssPlugin({
plugins: [autoprefixer],
sassPlugin({
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async transform(source: string, resolveDir: string) {
const { css } = await postcss([
autoprefixer,
postcssPresetEnv({ stage: 0 }),
]).process(source, { from: undefined });
return css;
},
}),
],
};
build({
...sassOpts,
entryPoints: ["srcts/extras/shiny-showcase.scss"],
outfile: outDir + "shiny-showcase.css",
});
build({
...sassOpts,
entryPoints: [
// Must keep shiny.scss within `inst` to be able to use as htmldependency
outDir + "shiny_scss/shiny.scss",
],
outfile: outDir + "shiny.min.css",
});
build({
...sassOpts,
entryPoints: ["srcts/extras/busy-indicators/busy-indicators.scss"],
outfile: outDir + "busy-indicators/busy-indicators.css",
plugins: [sassPlugin()],
bundle: false,
metafile: true,
async function main(): Promise<void> {
await Promise.all([
// - TypeScript -----------------------------------------------------------
// TypeScript builds
build({
bundle: true,
sourcemap: true,
minify: true,
plugins: [],
banner: banner,
entryPoints: [
"srcts/extras/shiny-autoreload.ts",
"srcts/extras/shiny-showcase.ts",
"srcts/extras/shiny-testmode.ts",
],
outdir: outDir,
}),
// Sass builds
build({
...sassOpts,
entryPoints: ["srcts/extras/shiny-showcase.scss"],
outfile: outDir + "shiny-showcase.css",
}),
build({
...sassOpts,
entryPoints: [
// Must keep shiny.scss within `inst` to be able to use as htmldependency
outDir + "shiny_scss/shiny.scss",
],
outfile: outDir + "shiny.min.css",
}),
build({
...sassOpts,
entryPoints: ["srcts/extras/busy-indicators/busy-indicators.scss"],
outfile: outDir + "busy-indicators/busy-indicators.css",
plugins: [sassPlugin()],
bundle: false,
metafile: true,
}),
]);
}
main().catch((err) => {
console.error("Error:\n" + err);
process.exit(1);
});

View File

@@ -1,6 +1,6 @@
// This build script must be executed from the root repo directory via
// ```
// yarn build
// npm run build
// ```
import type { BuildOptions } from "esbuild";
@@ -29,6 +29,7 @@ const opts: BuildOptions = {
// Make sure all ts files contain jquery import statements before building
verifyJqueryImport("srcts/src")
.then(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Promise.all([
build({
...opts,

View File

@@ -15,11 +15,14 @@ const animateMs = 400;
// If the given count is bigger than the number of characters contained by
// the node and its siblings, returns a null node and the number of
// characters found.
function findTextColPoint(node: Node, col: number) {
function findTextColPoint(
node: Node,
col: number,
): { element: Node | null; offset: number } {
let cols = 0;
if (node.nodeType === 3) {
const nchar = node.nodeValue.replace(/\n/g, "").length;
const nchar = node.nodeValue?.replace(/\n/g, "").length ?? 0;
if (nchar >= col) {
return { element: node, offset: col };
@@ -44,7 +47,11 @@ function findTextColPoint(node: Node, col: number) {
//
// If the given line and column are not found, returns a null element and
// the number of lines found.
function findTextPoint(el: Node, line: number, col: number) {
function findTextPoint(
el: Node,
line: number,
col: number,
): { element: Node | null; offset: number } {
let newlines = 0;
for (let childId = 0; childId < el.childNodes.length; childId++) {
@@ -56,7 +63,7 @@ function findTextPoint(el: Node, line: number, col: number) {
const newlinere = /\n/g;
let match: ReturnType<RegExp["exec"]>;
while ((match = newlinere.exec(child.nodeValue)) !== null) {
while ((match = newlinere.exec(child.nodeValue!)) !== null) {
newlines++;
// Found the desired line, now find the column.
if (newlines === line) {
@@ -82,7 +89,7 @@ function findTextPoint(el: Node, line: number, col: number) {
// refs.
function highlightSrcref(
srcref: ShowcaseSrcMessage["srcref"],
srcfile: ShowcaseSrcMessage["srcfile"]
srcfile: ShowcaseSrcMessage["srcfile"],
) {
// Check to see if the browser supports text ranges (IE8 doesn't)
if (!document.createRange) return;
@@ -112,7 +119,7 @@ function highlightSrcref(
// the SPANs.
if (
start.element.parentNode.nodeName === "SPAN" &&
start.element.parentNode?.nodeName === "SPAN" &&
start.element !== end.element
) {
range.setStartBefore(start.element.parentNode);
@@ -120,7 +127,7 @@ function highlightSrcref(
range.setStart(start.element, start.offset);
}
if (
end.element.parentNode.nodeName === "SPAN" &&
end.element.parentNode?.nodeName === "SPAN" &&
start.element !== end.element
) {
range.setEndAfter(end.element.parentNode);
@@ -136,14 +143,14 @@ function highlightSrcref(
// If this is the main Shiny window, wire up our custom message handler.
// TODO-barret, this should work
if (Shiny) {
Shiny.addCustomMessageHandler(
if (window.Shiny) {
window.Shiny.addCustomMessageHandler(
"showcase-src",
function (message: ShowcaseSrcMessage) {
if (message.srcref && message.srcfile) {
highlightSrcref(message.srcref, message.srcfile);
}
}
},
);
}
@@ -174,10 +181,24 @@ const setCodePosition = function (above: boolean, animate: boolean) {
}
// hide the new element before doing anything to it
if (newHostElement === null || currentHostElement === null) {
console.warn(
"Could not find the host elements for the code tabs. " +
"This is likely a bug in the showcase app.",
);
return;
}
$(newHostElement).hide();
$(currentHostElement).fadeOut(animateCodeMs, function () {
const tabs = document.getElementById("showcase-code-tabs");
if (tabs === null) {
console.warn(
"Could not find the code tabs element. This is likely a bug in the showcase app.",
);
return;
}
currentHostElement.removeChild(tabs);
newHostElement.appendChild(tabs);
@@ -185,7 +206,9 @@ const setCodePosition = function (above: boolean, animate: boolean) {
if (above) {
setCodeHeightFromDocHeight();
} else {
document.getElementById("showcase-code-content").removeAttribute("style");
document
.getElementById("showcase-code-content")
?.removeAttribute("style");
}
$(newHostElement).fadeIn(animateCodeMs);
@@ -194,27 +217,29 @@ const setCodePosition = function (above: boolean, animate: boolean) {
// scroll smoothly down to the code's new home
document
.getElementById("showcase-app-container")
.removeAttribute("style");
if (animate)
$(document.body).animate({
scrollTop: $(newHostElement).offset().top,
});
?.removeAttribute("style");
if (animate) {
const top = $(newHostElement).offset()?.top;
if (top !== undefined) {
$(document.body).animate({ scrollTop: top });
}
}
}
// if there's a readme, move it either alongside the code or beneath
// the app
const readme = document.getElementById("readme-md");
if (readme !== null) {
readme.parentElement.removeChild(readme);
readme.parentElement?.removeChild(readme);
if (above) {
currentHostElement.appendChild(readme);
$(currentHostElement).fadeIn(animateCodeMs);
} else
document.getElementById("showcase-app-metadata").appendChild(readme);
document.getElementById("showcase-app-metadata")?.appendChild(readme);
}
// change the text on the toggle button to reflect the new state
document.getElementById("showcase-code-position-toggle").innerHTML = above
document.getElementById("showcase-code-position-toggle")!.innerHTML = above
? '<i class="fa fa-level-down"></i> show below'
: '<i class="fa fa-level-up"></i> show with app';
});
@@ -230,7 +255,7 @@ function setAppCodeSxsWidths(animate: boolean) {
const appTargetWidth = 960;
let appWidth = appTargetWidth;
let zoom = 1.0;
const totalWidth = document.getElementById("showcase-app-code").offsetWidth;
const totalWidth = document.getElementById("showcase-app-code")!.offsetWidth;
if (totalWidth / 2 > appTargetWidth) {
// If the app can use only half the available space and still meet its
@@ -246,14 +271,12 @@ function setAppCodeSxsWidths(animate: boolean) {
appWidth = totalWidth * 0.66;
zoom = appWidth / appTargetWidth;
}
const app = document.getElementById("showcase-app-container");
$(app).animate(
$("#showcase-app-container").animate(
{
width: appWidth + "px",
zoom: zoom * 100 + "%",
},
animate ? animateMs : 0
animate ? animateMs : 0,
);
}
@@ -272,7 +295,7 @@ const setInitialCodePosition = function () {
// make the code scrollable to about the height of the browser, less space
// for the tabs
function setCodeHeightFromDocHeight() {
document.getElementById("showcase-code-content").style.height =
document.getElementById("showcase-code-content")!.style.height =
$(window).height() + "px";
}
@@ -288,7 +311,7 @@ function renderMarkdown() {
const showdownConverter = (window as any).Showdown
.converter as showdown.ConverterStatic;
document.getElementById("readme-md").innerHTML =
document.getElementById("readme-md")!.innerHTML =
new showdownConverter().makeHtml(content);
}
}

View File

@@ -11,7 +11,7 @@ type ActionButtonReceiveMessageData = {
};
class ActionButtonInputBinding extends InputBinding {
find(scope: HTMLElement): JQuery<HTMLElement> {
find(scope: HTMLElement): JQuery {
return $(scope).find(".action-button");
}
getValue(el: HTMLElement): number {
@@ -22,7 +22,7 @@ class ActionButtonInputBinding extends InputBinding {
}
getType(el: HTMLElement): string {
return "shiny.action";
el;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
subscribe(el: HTMLElement, callback: (x: boolean) => void): void {
$(el).on(
@@ -35,7 +35,7 @@ class ActionButtonInputBinding extends InputBinding {
$el.data("val", val + 1);
callback(false);
}
},
);
}
getState(el: HTMLElement): { value: number } {
@@ -43,11 +43,11 @@ class ActionButtonInputBinding extends InputBinding {
}
async receiveMessage(
el: HTMLElement,
data: ActionButtonReceiveMessageData
data: ActionButtonReceiveMessageData,
): Promise<void> {
if (hasDefinedProperty(data, "icon")) {
let iconContainer = el.querySelector<HTMLElement>(
":scope > .action-icon"
":scope > .action-icon",
);
// If no container exists yet, create one
if (!iconContainer) {
@@ -55,19 +55,19 @@ class ActionButtonInputBinding extends InputBinding {
iconContainer.className = "action-icon";
el.prepend(iconContainer);
}
await renderContent(iconContainer, data.icon);
await renderContent(iconContainer, data.icon!);
}
if (hasDefinedProperty(data, "label")) {
let labelContainer = el.querySelector<HTMLElement>(
":scope > .action-label"
":scope > .action-label",
);
if (!labelContainer) {
labelContainer = document.createElement("span");
labelContainer.className = "action-label";
el.appendChild(labelContainer);
}
await renderContent(labelContainer, data.label);
await renderContent(labelContainer, data.label!);
}
if (hasDefinedProperty(data, "disabled")) {
@@ -77,6 +77,7 @@ class ActionButtonInputBinding extends InputBinding {
el.removeAttribute("disabled");
}
}
return;
}
unsubscribe(el: HTMLElement): void {

View File

@@ -39,17 +39,17 @@ class CheckboxInputBinding extends InputBinding {
}
async receiveMessage(
el: CheckedHTMLElement,
data: CheckboxReceiveMessageData
data: CheckboxReceiveMessageData,
): Promise<void> {
if (hasDefinedProperty(data, "value")) {
el.checked = data.value;
el.checked = data.value!;
}
// checkboxInput()'s label works different from other
// input labels...the label container should always exist
if (hasDefinedProperty(data, "label")) {
const labelSpan = $(el).parent().find("span");
await renderContent(labelSpan, data.label);
await renderContent(labelSpan, data.label!);
}
$(el).trigger("change");
@@ -57,4 +57,4 @@ class CheckboxInputBinding extends InputBinding {
}
export { CheckboxInputBinding };
export type { CheckedHTMLElement, CheckboxReceiveMessageData };
export type { CheckboxReceiveMessageData, CheckedHTMLElement };

View File

@@ -77,7 +77,7 @@ class CheckboxGroupInputBinding extends InputBinding {
$escape(el.id) +
'"][value="' +
$escape(value[i]) +
'"]'
'"]',
).prop("checked", true);
}
// Else assume it's a single value
@@ -87,7 +87,7 @@ class CheckboxGroupInputBinding extends InputBinding {
$escape(el.id) +
'"][value="' +
$escape(value) +
'"]'
'"]',
).prop("checked", true);
}
}
@@ -97,7 +97,7 @@ class CheckboxGroupInputBinding extends InputBinding {
options: ValueLabelObject[];
} {
const $objs = $(
'input:checkbox[name="' + $escape(el.id) + '"]'
'input:checkbox[name="' + $escape(el.id) + '"]',
) as JQuery<CheckboxGroupHTMLElement>;
// Store options in an array of objects, each with with value and label
@@ -115,7 +115,7 @@ class CheckboxGroupInputBinding extends InputBinding {
}
async receiveMessage(
el: CheckboxGroupHTMLElement,
data: CheckboxGroupReceiveMessageData
data: CheckboxGroupReceiveMessageData,
): Promise<void> {
const $el = $(el);
@@ -125,11 +125,11 @@ class CheckboxGroupInputBinding extends InputBinding {
$el.find("div.shiny-options-group").remove();
// Backward compatibility: for HTML generated by shinybootstrap2 package
$el.find("label.checkbox").remove();
$el.append(data.options);
$el.append(data.options!);
}
if (hasDefinedProperty(data, "value")) {
this.setValue(el, data.value);
this.setValue(el, data.value!);
}
await updateLabel(data.label, getLabelNode(el));
@@ -138,7 +138,7 @@ class CheckboxGroupInputBinding extends InputBinding {
}
subscribe(
el: CheckboxGroupHTMLElement,
callback: (x: boolean) => void
callback: (x: boolean) => void,
): void {
$(el).on("change.checkboxGroupInputBinding", function () {
callback(false);

View File

@@ -15,10 +15,10 @@ declare global {
bsDatepicker(methodName: "getUTCDate"): Date;
// Infinity is not allowed as a literal return type. Using `1e9999` as a placeholder that resolves to Infinity
// https://github.com/microsoft/TypeScript/issues/32277
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
bsDatepicker(methodName: "getStartDate"): Date | -1e9999;
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
bsDatepicker(methodName: "getEndDate"): Date | 1e9999;
bsDatepicker(methodName: "getStartDate"): Date | -1e9999; // eslint-disable-line no-loss-of-precision
bsDatepicker(methodName: "getEndDate"): Date | 1e9999; // eslint-disable-line no-loss-of-precision
bsDatepicker(methodName: string): void;
bsDatepicker(methodName: string, params: Date | null): void;
}
@@ -37,7 +37,7 @@ class DateInputBindingBase extends InputBinding {
}
getType(el: HTMLElement): string {
return "shiny.date";
el;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
subscribe(el: HTMLElement, callback: (x: boolean) => void): void {
// Don't update when in the middle of typing; listening on keyup or input
@@ -50,7 +50,7 @@ class DateInputBindingBase extends InputBinding {
// Send immediately when clicked
// Or if typing, when enter pressed or focus lost
callback(false);
}
},
);
}
unsubscribe(el: HTMLElement): void {
@@ -66,8 +66,8 @@ class DateInputBindingBase extends InputBinding {
setValue(el: HTMLElement, data: unknown): void {
throw "not implemented";
el;
data;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
data; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
initialize(el: HTMLElement): void {
const $input = $(el).find("input");
@@ -294,20 +294,20 @@ class DateInputBinding extends DateInputBindingBase {
}
async receiveMessage(
el: HTMLElement,
data: DateReceiveMessageData
data: DateReceiveMessageData,
): Promise<void> {
const $input = $(el).find("input");
await updateLabel(data.label, this._getLabelNode(el));
if (hasDefinedProperty(data, "min")) this._setMin($input[0], data.min);
if (hasDefinedProperty(data, "min")) this._setMin($input[0], data.min!);
if (hasDefinedProperty(data, "max")) this._setMax($input[0], data.max);
if (hasDefinedProperty(data, "max")) this._setMax($input[0], data.max!);
// Must set value only after min and max have been set. If new value is
// outside the bounds of the previous min/max, then the result will be a
// blank input.
if (hasDefinedProperty(data, "value")) this.setValue(el, data.value);
if (hasDefinedProperty(data, "value")) this.setValue(el, data.value!);
$(el).trigger("change");
}

View File

@@ -108,7 +108,7 @@ class DateRangeInputBinding extends DateInputBindingBase {
}
async receiveMessage(
el: HTMLElement,
data: DateRangeReceiveMessageData
data: DateRangeReceiveMessageData,
): Promise<void> {
const $el = $(el);
const $inputs = $el.find("input");
@@ -118,20 +118,20 @@ class DateRangeInputBinding extends DateInputBindingBase {
await updateLabel(data.label, getLabelNode(el));
if (hasDefinedProperty(data, "min")) {
this._setMin($startinput[0], data.min);
this._setMin($endinput[0], data.min);
this._setMin($startinput[0], data.min!);
this._setMin($endinput[0], data.min!);
}
if (hasDefinedProperty(data, "max")) {
this._setMax($startinput[0], data.max);
this._setMax($endinput[0], data.max);
this._setMax($startinput[0], data.max!);
this._setMax($endinput[0], data.max!);
}
// Must set value only after min and max have been set. If new value is
// outside the bounds of the previous min/max, then the result will be a
// blank input.
if (hasDefinedProperty(data, "value")) {
this.setValue(el, data.value);
this.setValue(el, data.value!);
}
$el.trigger("change");
@@ -174,7 +174,7 @@ class DateRangeInputBinding extends DateInputBindingBase {
// Send immediately when clicked
// Or if typing, when enter pressed or focus lost
callback(false);
}
},
);
}
unsubscribe(el: HTMLElement): void {

View File

@@ -88,6 +88,7 @@ function canSetFiles(fileList: FileList): boolean {
testEl.files = fileList;
} catch (e) {
return false;
e; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
return true;
}
@@ -99,7 +100,7 @@ function handleDrop(e: JQuery.DragEventBase, el: HTMLInputElement): void {
// 1. The FileList object isn't supported by this browser, and
// there's nothing else we can try. (< IE 10)
console.log(
"Dropping files is not supported on this browser. (no FileList)"
"Dropping files is not supported on this browser. (no FileList)",
);
} else if (!canSetFiles(files)) {
// 2. The browser doesn't support assigning a type=file input's .files
@@ -146,7 +147,7 @@ function abortCurrentUpload($el: JQuery<EventTarget>) {
function uploadDroppedFilesIE10Plus(
el: HTMLInputElement,
files: FileList
files: FileList,
): void {
const $el = $(el);
@@ -158,7 +159,7 @@ function uploadDroppedFilesIE10Plus(
// Start the new upload and put the uploader in 'currentUploader'.
$el.data(
"currentUploader",
new FileUploader(shinyShinyApp(), fileInputBindingGetId(el), files, el)
new FileUploader(shinyShinyApp(), fileInputBindingGetId(el), files, el),
);
}
@@ -178,7 +179,7 @@ function uploadFiles(evt: JQuery.DragEvent): void {
// Start the new upload and put the uploader in 'currentUploader'.
$el.data(
"currentUploader",
new FileUploader(shinyShinyApp(), id, files, evt.target)
new FileUploader(shinyShinyApp(), id, files, evt.target),
);
}
@@ -237,17 +238,18 @@ class FileInputBinding extends InputBinding {
}
setValue(el: HTMLElement, value: void): void {
// Not implemented
el;
value;
return;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
value; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
getType(el: HTMLElement): string {
// This will be used only when restoring a file from a saved state.
return "shiny.file";
el;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
subscribe(el: HTMLInputElement, callback: (x: boolean) => void): void {
callback;
callback; // eslint-disable-line @typescript-eslint/no-unused-expressions
$(el).on("change.fileInputBinding", uploadFiles);
// Here we try to set up the necessary events for Drag and Drop ("DnD").
@@ -257,8 +259,9 @@ class FileInputBinding extends InputBinding {
enableDraghover($zone).on({
"draghover:enter.draghover": (e) => {
e;
$zone.addClass(zoneOver);
return;
e; // eslint-disable-line @typescript-eslint/no-unused-expressions
},
"draghover:leave.draghover": (e) => {
$zone.removeClass(zoneOver);
@@ -267,8 +270,9 @@ class FileInputBinding extends InputBinding {
e.stopPropagation();
},
"draghover:drop.draghover": (e, dropEvent) => {
e;
handleDrop(dropEvent, el);
return;
e; // eslint-disable-line @typescript-eslint/no-unused-expressions
},
});
}

View File

@@ -31,7 +31,7 @@ function initInputBindings(): {
inputBindings.register(new CheckboxInputBinding(), "shiny.checkboxInput");
inputBindings.register(
new CheckboxGroupInputBinding(),
"shiny.checkboxGroupInput"
"shiny.checkboxGroupInput",
);
inputBindings.register(new RadioInputBinding(), "shiny.radioInput");
inputBindings.register(new SliderInputBinding(), "shiny.sliderInput");
@@ -40,11 +40,11 @@ function initInputBindings(): {
inputBindings.register(new SelectInputBinding(), "shiny.selectInput");
inputBindings.register(
new ActionButtonInputBinding(),
"shiny.actionButtonInput"
"shiny.actionButtonInput",
);
inputBindings.register(
new BootstrapTabInputBinding(),
"shiny.bootstrapTabInput"
"shiny.bootstrapTabInput",
);
const fileInputBinding = new FileInputBinding();

View File

@@ -24,7 +24,7 @@ class InputBinding {
// descendants of scope that match this binding
find(scope: BindScope): JQuery<HTMLElement> {
throw "Not implemented";
scope; // unused var
scope; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
getId(el: HTMLElement): string {
@@ -35,21 +35,23 @@ class InputBinding {
// to deserialize the JSON correctly
getType(el: HTMLElement): string | null {
return null;
el; // unused var
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
getValue(el: HTMLElement): any {
throw "Not implemented";
el; // unused var
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
subscribe(el: HTMLElement, callback: InputSubscribeCallback): void {
// empty
el; // unused var
callback; // unused var
return;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
callback; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
unsubscribe(el: HTMLElement): void {
// empty
el; // unused var
return;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
// This is used for receiving messages that tell the input object to do
@@ -59,19 +61,19 @@ class InputBinding {
// trigger a change event.
receiveMessage(el: HTMLElement, data: unknown): Promise<void> | void {
throw "Not implemented";
el; // unused var
data; // unused var
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
data; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
getState(el: HTMLElement): unknown {
throw "Not implemented";
el; // unused var
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
getRatePolicy(
el: HTMLElement
el: HTMLElement,
): { policy: RatePolicyModes; delay: number } | null {
return null;
el; // unused var
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
// Some input objects need initialization before being bound. This is
@@ -81,13 +83,15 @@ class InputBinding {
// This is called before the input is bound.
initialize(el: HTMLElement): void {
//empty
el;
return;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
// This is called after unbinding the output.
dispose(el: HTMLElement): void {
//empty
el;
return;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
}

View File

@@ -25,7 +25,7 @@ class NumberInputBinding extends TextInputBindingBase {
}
getValue(
el: NumberHTMLElement
el: NumberHTMLElement,
): string[] | number | string | null | undefined {
const numberVal = $(el).val();
@@ -49,11 +49,11 @@ class NumberInputBinding extends TextInputBindingBase {
}
getType(el: NumberHTMLElement): string {
return "shiny.number";
el;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
async receiveMessage(
el: NumberHTMLElement,
data: NumberReceiveMessageData
data: NumberReceiveMessageData,
): Promise<void> {
// Setting values to `""` will remove the attribute value from the DOM element.
// The attr key will still remain, but there is not value... ex: `<input id="foo" type="number" min max/>`

View File

@@ -10,7 +10,7 @@ class PasswordInputBinding extends TextInputBinding {
getType(el: HTMLElement): string {
return "shiny.password";
el;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
}

View File

@@ -52,11 +52,11 @@ class RadioInputBinding extends InputBinding {
return $(scope).find(".shiny-input-radiogroup");
}
getValue(
el: RadioHTMLElement
el: RadioHTMLElement,
): string[] | number | string | null | undefined {
// Select the radio objects that have name equal to the grouping div's id
const checkedItems = $(
'input:radio[name="' + $escape(el.id) + '"]:checked'
'input:radio[name="' + $escape(el.id) + '"]:checked',
);
if (checkedItems.length === 0) {
@@ -77,7 +77,7 @@ class RadioInputBinding extends InputBinding {
$escape(el.id) +
'"][value="' +
$escape(value) +
'"]'
'"]',
).prop("checked", true);
}
}
@@ -87,7 +87,7 @@ class RadioInputBinding extends InputBinding {
options: ValueLabelObject[];
} {
const $objs = $(
'input:radio[name="' + $escape(el.id) + '"]'
'input:radio[name="' + $escape(el.id) + '"]',
) as JQuery<RadioHTMLElement>;
// Store options in an array of objects, each with with value and label
@@ -105,7 +105,7 @@ class RadioInputBinding extends InputBinding {
}
async receiveMessage(
el: RadioHTMLElement,
data: RadioReceiveMessageData
data: RadioReceiveMessageData,
): Promise<void> {
const $el = $(el);
// This will replace all the options
@@ -122,7 +122,7 @@ class RadioInputBinding extends InputBinding {
}
if (hasDefinedProperty(data, "value")) {
this.setValue(el, data.value);
this.setValue(el, data.value!);
}
await updateLabel(data.label, getLabelNode(el));

View File

@@ -30,7 +30,7 @@ function getLabelNode(el: SelectHTMLElement): JQuery<HTMLElement> {
.find('label[for="' + escapedId + '"]');
}
// Return true if it's a selectize input, false if it's a regular select input.
// eslint-disable-next-line camelcase
function isSelectize(el: HTMLElement): boolean {
const config = $(el)
.parent()
@@ -85,7 +85,7 @@ class SelectInputBinding extends InputBinding {
} {
// Store options in an array of objects, each with with value and label
const options: Array<{ value: string; label: string }> = new Array(
el.length
el.length,
);
for (let i = 0; i < el.length; i++) {
@@ -104,7 +104,7 @@ class SelectInputBinding extends InputBinding {
}
async receiveMessage(
el: SelectHTMLElement,
data: SelectInputReceiveMessageData
data: SelectInputReceiveMessageData,
): Promise<void> {
const $el = $(el);
@@ -116,7 +116,7 @@ class SelectInputBinding extends InputBinding {
// selectize will restore the original select
selectize?.destroy();
// Clear existing options and add each new one
$el.empty().append(data.options);
$el.empty().append(data.options!);
this._selectize(el);
}
@@ -125,7 +125,7 @@ class SelectInputBinding extends InputBinding {
$el
.parent()
.find('script[data-for="' + $escape(el.id) + '"]')
.replaceWith(data.config);
.replaceWith(data.config!);
this._selectize(el, true);
}
@@ -154,7 +154,6 @@ class SelectInputBinding extends InputBinding {
selectize.settings.load = function (query: string, callback: CallbackFn) {
const settings = selectize.settings;
/* eslint-disable-next-line @typescript-eslint/no-floating-promises */
$.ajax({
url: data.url,
data: {
@@ -202,6 +201,7 @@ class SelectInputBinding extends InputBinding {
selectize.settings.load.apply(selectize, ["", callback]);
});
} else if (hasDefinedProperty(data, "value")) {
// @ts-expect-error; data.value is currently a never type
this.setValue(el, data.value);
}
@@ -221,7 +221,7 @@ class SelectInputBinding extends InputBinding {
return;
}
callback(false);
}
},
);
}
unsubscribe(el: HTMLElement): void {
@@ -232,7 +232,7 @@ class SelectInputBinding extends InputBinding {
}
protected _selectize(
el: SelectHTMLElement,
update = false
update = false,
): SelectizeInfo | undefined {
// Apps like 008-html do not have the selectize js library
// Safe-guard against missing the selectize js library
@@ -256,7 +256,7 @@ class SelectInputBinding extends InputBinding {
valueField: "value",
searchField: ["label"],
},
JSON.parse(config.html())
JSON.parse(config.html()),
);
// selectize created from selectInput()
@@ -271,7 +271,7 @@ class SelectInputBinding extends InputBinding {
$("<option/>", {
value: value,
selected: true,
})
}),
)
.trigger("change");
},

View File

@@ -61,7 +61,7 @@ type Prettify = (num: number) => string;
function getTypePrettifyer(
dataType: string,
timeFormat: string,
timezone: string
timezone: string,
) {
let timeFormatter: TimeFormatter;
let prettify: Prettify;
@@ -121,7 +121,7 @@ class SliderInputBinding extends TextInputBindingBase {
else return null;
}
getValue(
el: TextHTMLElement
el: TextHTMLElement,
): number | string | [number | string, number | string] {
const $el = $(el);
const result = $(el).data("ionRangeSlider").result as IonRangeSliderEvent;
@@ -153,7 +153,7 @@ class SliderInputBinding extends TextInputBindingBase {
}
setValue(
el: HTMLElement,
value: number | string | [number | string, number | string]
value: number | string | [number | string, number | string],
): void {
const $el = $(el);
const slider = $el.data("ionRangeSlider");
@@ -181,7 +181,7 @@ class SliderInputBinding extends TextInputBindingBase {
}
async receiveMessage(
el: HTMLElement,
data: SliderReceiveMessageData
data: SliderReceiveMessageData,
): Promise<void> {
const $el = $(el);
const slider = $el.data("ionRangeSlider");
@@ -242,7 +242,7 @@ class SliderInputBinding extends TextInputBindingBase {
const elem = domElements[i];
if (hasDefinedProperty(data, elem)) {
$el.data(elem, data[elem]);
$el.data(elem, data[elem]!);
}
}
@@ -266,12 +266,13 @@ class SliderInputBinding extends TextInputBindingBase {
policy: "debounce",
delay: 250,
};
el;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
// TODO-barret Why not implemented?
getState(el: HTMLInputElement): void {
// empty
el;
return;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
initialize(el: HTMLElement): void {
@@ -297,14 +298,14 @@ class SliderInputBinding extends TextInputBindingBase {
function formatNumber(
num: number,
thousandSep = ",",
decimalSep = "."
decimalSep = ".",
): string {
const parts = num.toString().split(".");
// Add separators to portion before decimal mark.
parts[0] = parts[0].replace(
/(\d{1,3}(?=(?:\d\d\d)+(?!\d)))/g,
"$1" + thousandSep
"$1" + thousandSep,
);
if (parts.length === 1) return parts[0];
@@ -375,14 +376,14 @@ $(document).on("click", ".slider-animate-button", function (evt: Event) {
const val: { from: number; to?: number } = {
from: Math.min(
slider.result.max,
slider.result.from + slider.options.step
slider.result.from + slider.options.step,
),
};
if (slider.options.type === "double")
val.to = Math.min(
slider.result.max,
slider.result.to + slider.options.step
slider.result.to + slider.options.step,
);
slider.update(val);

View File

@@ -65,7 +65,7 @@ class BootstrapTabInputBinding extends InputBinding {
// event: Event
function () {
callback(false);
}
},
);
}
unsubscribe(el: HTMLElement): void {

View File

@@ -23,7 +23,7 @@ function getLabelNode(el: HTMLElement): JQuery<HTMLElement> {
class TextInputBindingBase extends InputBinding {
find(scope: HTMLElement): JQuery<HTMLElement> {
const $inputs = $(scope).find(
'input[type="text"], input[type="search"], input[type="url"], input[type="email"]'
'input[type="text"], input[type="search"], input[type="url"], input[type="email"]',
);
// selectize.js 0.12.4 inserts a hidden text input with an
// id that ends in '-selectized'. The .not() selector below
@@ -41,12 +41,12 @@ class TextInputBindingBase extends InputBinding {
getValue(el: TextHTMLElement): unknown {
throw "not implemented";
el;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
setValue(el: TextHTMLElement, value: unknown): void {
throw "not implemented";
el;
value;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
value; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
subscribe(el: TextHTMLElement, callback: (x: boolean) => void): void {
@@ -59,7 +59,7 @@ class TextInputBindingBase extends InputBinding {
// event: Event
function () {
callback(true);
}
},
);
} else if (updateOn === "blur") {
$el.on("blur.textInputBinding", function () {
@@ -88,13 +88,13 @@ class TextInputBindingBase extends InputBinding {
receiveMessage(el: TextHTMLElement, data: unknown): void {
throw "not implemented";
el;
data;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
data; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
getState(el: TextHTMLElement): unknown {
throw "not implemented";
el;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
getRatePolicy(el: HTMLElement): { policy: "debounce"; delay: 250 } {
@@ -102,7 +102,7 @@ class TextInputBindingBase extends InputBinding {
policy: "debounce",
delay: 250,
};
el;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
}
@@ -126,16 +126,19 @@ class TextInputBinding extends TextInputBindingBase {
placeholder: el.placeholder,
};
}
async receiveMessage(
el: TextHTMLElement,
data: TextReceiveMessageData
data: TextReceiveMessageData,
): Promise<void> {
if (hasDefinedProperty(data, "value")) this.setValue(el, data.value);
if (hasDefinedProperty(data, "value")) this.setValue(el, data.value!);
await updateLabel(data.label, getLabelNode(el));
if (hasDefinedProperty(data, "placeholder"))
if (hasDefinedProperty(data, "placeholder")) {
// @ts-expect-error; data.value is currently a never type
el.placeholder = data.placeholder;
}
$(el).trigger("change");
}

View File

@@ -31,7 +31,7 @@ class DatatableOutputBinding extends OutputBinding {
evalOptions?: string[];
callback?: string;
searchDelay?: number;
} | null
} | null,
): void {
const $el = $(el).empty();
@@ -89,7 +89,9 @@ class DatatableOutputBinding extends OutputBinding {
url: data.action,
type: "POST",
data: function (d: NonNullable<typeof data.options>) {
d.search || (d.search = {});
if (!d.search) {
d.search = {};
}
d.search.caseInsensitive = searchCI;
// Copy from the R value (`data.escape`) to the escape option
// (`d.escape`) similar to `data.options.escape`;
@@ -100,8 +102,8 @@ class DatatableOutputBinding extends OutputBinding {
},
},
},
data.options
)
data.options,
),
);
// the table object may need post-processing
@@ -120,7 +122,7 @@ class DatatableOutputBinding extends OutputBinding {
.keyup(
debounce(data.searchDelay, function (this: HTMLInputElement) {
oTable.search(this.value).draw();
})
}),
);
const searchInputs = $el.find("tfoot input");
@@ -134,7 +136,7 @@ class DatatableOutputBinding extends OutputBinding {
searchInputs.keyup(
debounce(data.searchDelay, function (this: HTMLInputElement) {
oTable.column(searchInputs.index(this)).search(this.value).draw();
})
}),
);
}
// FIXME: ugly scrollbars in tab panels b/c Bootstrap uses 'visible: auto'

View File

@@ -16,8 +16,8 @@ class DownloadLinkOutputBinding extends OutputBinding {
// (progress will be shown as a page level pulse instead)
showProgress(el: HTMLElement, show: boolean): void {
return;
el;
show;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
show; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
}
@@ -32,14 +32,15 @@ $(document).on(
"click.shinyDownloadLink",
"a.shiny-download-link",
function (e: Event) {
e;
const evt: FileDownloadEvent = $.Event("shiny:filedownload");
evt.name = this.id;
evt.href = this.href;
$(document).trigger(evt);
}
return;
e; // eslint-disable-line @typescript-eslint/no-unused-expressions
},
);
export { DownloadLinkOutputBinding };

View File

@@ -15,7 +15,7 @@ class HtmlOutputBinding extends OutputBinding {
}
override async renderValue(
el: HTMLElement,
data: Parameters<typeof renderContentAsync>[1]
data: Parameters<typeof renderContentAsync>[1],
): Promise<void> {
await renderContentAsync(el, data);
}

View File

@@ -5,6 +5,7 @@ import {
createClickInfo,
createHoverHandler,
disableDrag,
findImageOutputs,
initCoordmap,
} from "../../imageutils";
import type { CoordmapInit } from "../../imageutils/initCoordmap";
@@ -21,7 +22,7 @@ import { OutputBinding } from "./outputBinding";
class ImageOutputBinding extends OutputBinding {
find(scope: HTMLElement): JQuery<HTMLElement> {
return $(scope).find(".shiny-image-output, .shiny-plot-output");
return findImageOutputs(scope);
}
renderValue(
@@ -29,7 +30,7 @@ class ImageOutputBinding extends OutputBinding {
data: {
coordmap: CoordmapInit;
error?: string;
} & { [key: string]: string }
} & { [key: string]: string },
): void {
// The overall strategy:
// * Clear out existing image and event handlers.
@@ -81,7 +82,7 @@ class ImageOutputBinding extends OutputBinding {
hoverDelay: ifUndefined($el.data("hover-delay"), 300),
hoverNullOutside: ifUndefined(
strToBool($el.data("hover-null-outside")),
false
false,
),
brushId: $el.data("brush-id"),
@@ -94,7 +95,7 @@ class ImageOutputBinding extends OutputBinding {
brushDirection: ifUndefined($el.data("brush-direction"), "xy"),
brushResetOnNew: ifUndefined(
strToBool($el.data("brush-reset-on-new")),
false
false,
),
coordmap: data.coordmap,
@@ -167,7 +168,7 @@ class ImageOutputBinding extends OutputBinding {
const clickInfo = createClickInfo(
$el,
opts.dblclickId,
opts.dblclickDelay
opts.dblclickDelay,
);
$el.on("mousedown.image_output", clickInfo.mousedown);
@@ -185,7 +186,7 @@ class ImageOutputBinding extends OutputBinding {
const clickHandler = createClickHandler(
opts.clickId,
opts.clickClip,
optsCoordmap
optsCoordmap,
);
$el.on("mousedown2.image_output", clickHandler.mousedown);
@@ -205,7 +206,7 @@ class ImageOutputBinding extends OutputBinding {
const dblclickHandler = createClickHandler(
opts.dblclickId,
opts.clickClip,
optsCoordmap
optsCoordmap,
);
$el.on("dblclick2.image_output", dblclickHandler.mousedown);
@@ -223,7 +224,7 @@ class ImageOutputBinding extends OutputBinding {
opts.hoverDelayType,
opts.hoverClip,
opts.hoverNullOutside,
optsCoordmap
optsCoordmap,
);
$el.on("mousemove.image_output", hoverHandler.mousemove);
@@ -241,7 +242,7 @@ class ImageOutputBinding extends OutputBinding {
$el,
opts,
optsCoordmap,
outputId
outputId,
);
$el.on("mousedown.image_output", brushHandler.mousedown);
@@ -285,12 +286,12 @@ class ImageOutputBinding extends OutputBinding {
resize(
el: HTMLElement,
width: number | string,
height: number | string
height: number | string,
): void {
$(el).find("img").trigger("resize");
return;
width;
height;
width; // eslint-disable-line @typescript-eslint/no-unused-expressions
height; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
}

View File

@@ -16,11 +16,11 @@ function initOutputBindings(): InitOutputBindings {
outputBindings.register(new TextOutputBinding(), "shiny.textOutput");
outputBindings.register(
new DownloadLinkOutputBinding(),
"shiny.downloadLink"
"shiny.downloadLink",
);
outputBindings.register(
new DatatableOutputBinding(),
"shiny.datatableOutput"
"shiny.datatableOutput",
);
outputBindings.register(new HtmlOutputBinding(), "shiny.htmlOutput");
outputBindings.register(imageOutputBinding, "shiny.imageOutput");
@@ -28,4 +28,4 @@ function initOutputBindings(): InitOutputBindings {
return { outputBindings };
}
export { OutputBinding, initOutputBindings };
export { initOutputBindings, OutputBinding };

View File

@@ -9,12 +9,12 @@ class OutputBinding {
// descendants of scope that match this binding
find(scope: HTMLElement | JQuery<HTMLElement>): JQuery<HTMLElement> {
throw "Not implemented";
scope;
scope; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
renderValue(el: HTMLElement, data: unknown): Promise<void> | void {
throw "Not implemented";
el;
data;
el; // eslint-disable-line @typescript-eslint/no-unused-expressions
data; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
getId(el: HTMLElement): string {

View File

@@ -6,7 +6,7 @@ interface OutpuBindingWithResize extends OutputBinding {
resize?: (
el: HTMLElement,
width: number | string,
height: number | string
height: number | string,
) => void;
}
@@ -22,7 +22,6 @@ class OutputBindingAdapter {
// onResize with a version that does a makeResizeFilter on the element.
if (binding.resize) {
this.onResize = makeResizeFilter(el, function (width, height) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
binding.resize!(el, width, height);
});
}

View File

@@ -1,8 +1,6 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { css, html, LitElement } from "lit";
import { Shiny } from "..";
import { ShinyClientError } from "../shiny/error";
import { isShinyInDevMode } from "../utils";
const buttonStyles = css`
button {
@@ -57,16 +55,17 @@ class ShinyErrorConsole extends LitElement {
--shadow-color: 220 3% 15%;
--shadow-strength: 1%;
--shadow-3: 0 -1px 3px 0 hsl(var(--shadow-color) /
calc(var(--shadow-strength) + 2%)),
0 1px 2px -5px hsl(var(--shadow-color) /
calc(var(--shadow-strength) + 2%)),
0 2px 5px -5px hsl(var(--shadow-color) /
calc(var(--shadow-strength) + 4%)),
0 4px 12px -5px hsl(var(--shadow-color) /
calc(var(--shadow-strength) + 5%)),
0 12px 15px -5px hsl(var(--shadow-color) /
calc(var(--shadow-strength) + 7%));
--shadow-3:
0 -1px 3px 0
hsl(var(--shadow-color) / calc(var(--shadow-strength) + 2%)),
0 1px 2px -5px
hsl(var(--shadow-color) / calc(var(--shadow-strength) + 2%)),
0 2px 5px -5px
hsl(var(--shadow-color) / calc(var(--shadow-strength) + 4%)),
0 4px 12px -5px
hsl(var(--shadow-color) / calc(var(--shadow-strength) + 5%)),
0 12px 15px -5px
hsl(var(--shadow-color) / calc(var(--shadow-strength) + 7%));
--ring-shadow: 0 0 0 1px var(--gray-2);
@@ -231,7 +230,7 @@ class ShinyErrorConsole extends LitElement {
}
this.appendChild(
ShinyErrorConsole.createClientMessageElement({ headline, message })
ShinyErrorConsole.createClientMessageElement({ headline, message }),
);
return;
}
@@ -305,10 +304,8 @@ export class ShinyErrorMessage extends LitElement {
font-size: var(--font-md);
position: relative;
--icon-size: var(--font-lg)
/* Reset box sizing */
box-sizing: border-box;
--icon-size: var(--font-lg) /* Reset box sizing */
box-sizing: border-box;
}
.container {
@@ -327,7 +324,6 @@ export class ShinyErrorMessage extends LitElement {
}
:host(:last-of-type) .contents {
padding-block-end: var(--space-1);
}
@@ -375,7 +371,7 @@ export class ShinyErrorMessage extends LitElement {
position: absolute;
width: var(--dot-size);
height: var(--dot-size);
top: calc(-1px + var(--dot-size) / 2);
top: calc(-1px + var(--dot-size) / 2);
left: calc(50% - var(--dot-size) / 2);
border-radius: 100%;
transform: scale(var(--scale, 1));
@@ -553,7 +549,7 @@ function showShinyClientMessage({
break;
}
if (!Shiny.inDevMode()) {
if (!isShinyInDevMode()) {
return;
}
@@ -606,7 +602,7 @@ window.addEventListener("shiny:client-message", (ev: Event) => {
const { headline, message, status } = ev.detail;
if (!message) {
throw new Error(
"[shiny] shiny:client-message expected a `message` property in `event.detail`."
"[shiny] shiny:client-message expected a `message` property in `event.detail`.",
);
}
showShinyClientMessage({ headline, message, status });

View File

@@ -8,7 +8,7 @@ function triggerFileInputChanged(
binding: FileInputBinding,
el: HTMLElement,
inputType: string,
onEl: typeof document
onEl: typeof document,
): ShinyEventInputChanged {
const evt = $.Event("shiny:inputchanged") as ShinyEventInputChanged;

View File

@@ -1,5 +1,4 @@
// Used to avoid isolated module warning
import type { JQueryEventHandlerBase } from "bootstrap";
import "jquery";
type EvtPrefix<T extends string> = `${T}.${string}`;
@@ -11,32 +10,32 @@ declare global {
on(
events: EvtPrefix<"mousdown">,
handler: EvtFn<JQuery.MouseDownEvent>
handler: EvtFn<JQuery.MouseDownEvent>,
): this;
on(
events: EvtPrefix<"dblclick">,
handler: EvtFn<JQuery.DoubleClickEvent>
handler: EvtFn<JQuery.DoubleClickEvent>,
): this;
on(
events: EvtPrefix<"dblclick2">,
// Note: This may not be the _right type_, but it is how it is handled internally
handler: EvtFn<JQuery.MouseDownEvent>
handler: EvtFn<JQuery.MouseDownEvent>,
): this;
on(
events: EvtPrefix<"mousemove">,
handler: EvtFn<JQuery.MouseMoveEvent>
handler: EvtFn<JQuery.MouseMoveEvent>,
): this;
on(
events: EvtPrefix<"mouseout">,
handler: EvtFn<JQuery.MouseOutEvent>
handler: EvtFn<JQuery.MouseOutEvent>,
): this;
on(
events: EvtPrefix<"mousedown">,
handler: EvtFn<JQuery.MouseDownEvent>
handler: EvtFn<JQuery.MouseDownEvent>,
): this;
on(
events: EvtPrefix<"mousedown2">,
handler: EvtFn<JQuery.MouseDownEvent>
handler: EvtFn<JQuery.MouseDownEvent>,
): this;
on(events: EvtPrefix<"mouseup">, handler: EvtFn<JQuery.MouseUpEvent>): this;
on(events: EvtPrefix<"resize">, handler: EvtFn<JQuery.ResizeEvent>): this;
@@ -46,11 +45,11 @@ declare global {
selector: string,
handler: (
this: HTMLElement,
e: JQueryEventHandlerBase<HTMLElement, any>
e: JQuery.EventHandlerBase<HTMLElement, any>,
// e: JQuery.Event & {
// namespace: string;
// }
) => void
) => void,
): this;
}
}

View File

@@ -32,9 +32,9 @@ interface ShinyEventMessage extends JQuery.Event {
}
export type {
ShinyEventError,
ShinyEventInputChanged,
ShinyEventMessage,
ShinyEventUpdateInput,
ShinyEventValue,
ShinyEventError,
ShinyEventMessage,
};

View File

@@ -31,12 +31,14 @@ class FileProcessor {
// Begin callbacks. Subclassers/cloners may override any or all of these.
onBegin(files: File[], cont: () => void): void {
files;
setTimeout(cont, 0);
return;
files; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
onFile(file: File, cont: () => void): void {
file;
setTimeout(cont, 0);
return;
file; // eslint-disable-line @typescript-eslint/no-unused-expressions
}
onComplete(): void {
return;
@@ -108,7 +110,7 @@ class FileUploader extends FileProcessor {
shinyapp: ShinyApp,
id: string,
files: FileList,
el: HTMLElement
el: HTMLElement,
) {
// Init super with files, do not execute `this.$run()` before setting variables
super(files, false);
@@ -123,7 +125,7 @@ class FileUploader extends FileProcessor {
args: Array<Array<{ name: string; size: number; type: string }>>,
onSuccess: (value: UploadInitValue) => void,
onFailure: Parameters<ShinyApp["makeRequest"]>[3],
blobs: Parameters<ShinyApp["makeRequest"]>[4]
blobs: Parameters<ShinyApp["makeRequest"]>[4],
): void;
makeRequest(
method: "uploadEnd",
@@ -131,14 +133,14 @@ class FileUploader extends FileProcessor {
// UploadEndValue can not be used as the type will not conform
onSuccess: (value: unknown) => void,
onFailure: Parameters<ShinyApp["makeRequest"]>[3],
blobs: Parameters<ShinyApp["makeRequest"]>[4]
blobs: Parameters<ShinyApp["makeRequest"]>[4],
): void;
makeRequest(
method: string,
args: unknown[],
onSuccess: Parameters<ShinyApp["makeRequest"]>[2],
onFailure: Parameters<ShinyApp["makeRequest"]>[3],
blobs: Parameters<ShinyApp["makeRequest"]>[4]
blobs: Parameters<ShinyApp["makeRequest"]>[4],
): void {
this.shinyapp.makeRequest(method, args, onSuccess, onFailure, blobs);
}
@@ -174,13 +176,12 @@ class FileUploader extends FileProcessor {
(error) => {
this.onError(error);
},
undefined
undefined,
);
}
onFile(file: File, cont: () => void): void {
this.onProgress(file, 0);
/* eslint-disable-next-line @typescript-eslint/no-floating-promises */
$.ajax(this.uploadUrl, {
type: "POST",
cache: false,
@@ -195,7 +196,7 @@ class FileUploader extends FileProcessor {
if (e.lengthComputable) {
this.onProgress(
file,
(this.progressBytes + e.loaded) / this.totalBytes
(this.progressBytes + e.loaded) / this.totalBytes,
);
}
};
@@ -210,8 +211,9 @@ class FileUploader extends FileProcessor {
cont();
},
error: (jqXHR, textStatus, errorThrown) => {
errorThrown;
this.onError(jqXHR.responseText || textStatus);
return;
errorThrown; // eslint-disable-line @typescript-eslint/no-unused-expressions
},
});
}
@@ -222,7 +224,7 @@ class FileUploader extends FileProcessor {
size: file.size,
type: file.type,
};
i;
i; // eslint-disable-line @typescript-eslint/no-unused-expressions
});
// Trigger shiny:inputchanged. Unlike a normal shiny:inputchanged event,
@@ -234,7 +236,7 @@ class FileUploader extends FileProcessor {
getFileInputBinding(),
this.el,
"shiny.fileupload",
document
document,
);
this.makeRequest(
@@ -251,7 +253,7 @@ class FileUploader extends FileProcessor {
(error) => {
this.onError(error);
},
undefined
undefined,
);
this.$bar().text("Finishing upload");
}
@@ -273,7 +275,7 @@ class FileUploader extends FileProcessor {
return $(
"#" +
$escape(this.id) +
"_progress.shiny-file-input-progress .progress-bar"
"_progress.shiny-file-input-progress .progress-bar",
);
}
$setVisible(visible: boolean): void {
@@ -292,4 +294,4 @@ class FileUploader extends FileProcessor {
}
export { FileUploader };
export type { UploadInitValue, UploadEndValue };
export type { UploadEndValue, UploadInitValue };

View File

@@ -109,7 +109,7 @@ function createBrush(
$el: JQuery<HTMLElement>,
opts: BrushOpts,
coordmap: Coordmap,
expandPixels: number
expandPixels: number,
): Brush {
// Number of pixels outside of brush to allow start resizing
const resizeExpand = 10;
@@ -306,7 +306,6 @@ function createBrush(
let minCss: Offset = { x: boxCss.xmin, y: boxCss.ymin };
let maxCss: Offset = { x: boxCss.xmax, y: boxCss.ymax };
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const panel = state.panel!;
const panelBoundsImg = panel.range;
@@ -343,15 +342,15 @@ function createBrush(
// Round to 14 significant digits to avoid spurious changes in FP values
// (#1634).
state.boundsData = mapValues(state.boundsData, (val) =>
roundSignif(val, 14)
roundSignif(val, 14),
);
// We also need to attach the data bounds and panel as data attributes, so
// that if the image is re-sent, we can grab the data bounds to create a new
// brush. This should be fast because it doesn't actually modify the DOM.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$div!.data("bounds-data", state.boundsData);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$div!.data("panel", state.panel);
return undefined;
}
@@ -364,7 +363,6 @@ function createBrush(
return { ...state.boundsData };
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
let boxCss = imgToCss(state.panel!.scaleDataToImg(boxData));
// Round to 13 significant digits to avoid spurious changes in FP values
// (#2197).
@@ -424,7 +422,7 @@ function createBrush(
$div
.offset(
// @ts-expect-error; This is a jQuery Typing issue
{ x: 0, y: 0 }
{ x: 0, y: 0 },
)
.width(0)
.outerHeight(0);
@@ -437,7 +435,6 @@ function createBrush(
const imgOffsetCss = findOrigin($el.find("img"));
const b = state.boundsCss;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$div!
.offset({
top: imgOffsetCss.y + b.ymin,
@@ -480,7 +477,7 @@ function createBrush(
function brushTo(offsetCss: Offset) {
boundsCss(findBox(state.down, offsetCss));
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$div!.show();
updateDiv();
}
@@ -527,12 +524,12 @@ function createBrush(
xvalsImg = shiftToRange(
xvalsImg,
panelBoundsImg.left,
panelBoundsImg.right
panelBoundsImg.right,
);
yvalsImg = shiftToRange(
yvalsImg,
panelBoundsImg.top,
panelBoundsImg.bottom
panelBoundsImg.bottom,
);
// Convert back to bounds format
@@ -580,7 +577,7 @@ function createBrush(
const xminImg = shiftToRange(
bImg.xmin + dImg.x,
panelBoundsImg.left,
bImg.xmax
bImg.xmax,
)[0];
bImg.xmin = xminImg;
@@ -588,7 +585,7 @@ function createBrush(
const xmaxImg = shiftToRange(
bImg.xmax + dImg.x,
bImg.xmin,
panelBoundsImg.right
panelBoundsImg.right,
)[0];
bImg.xmax = xmaxImg;
@@ -598,7 +595,7 @@ function createBrush(
const yminImg = shiftToRange(
bImg.ymin + dImg.y,
panelBoundsImg.top,
bImg.ymax
bImg.ymax,
)[0];
bImg.ymin = yminImg;
@@ -606,7 +603,7 @@ function createBrush(
const ymaxImg = shiftToRange(
bImg.ymax + dImg.y,
bImg.ymin,
panelBoundsImg.bottom
panelBoundsImg.bottom,
)[0];
bImg.ymax = ymaxImg;
@@ -656,4 +653,4 @@ function createBrush(
}
export { createBrush };
export type { Bounds, BrushOpts, BoundsCss };
export type { Bounds, BoundsCss, BrushOpts };

View File

@@ -9,7 +9,7 @@ import $ from "jquery";
function createClickInfo(
$el: JQuery<HTMLElement>,
dblclickId: string,
dblclickDelay: number
dblclickDelay: number,
): {
mousedown: (e: JQuery.MouseDownEvent) => void;
dblclickIE8: (e: JQuery.DoubleClickEvent) => void;
@@ -21,7 +21,7 @@ function createClickInfo(
// it with the information stored in this.e.
function triggerEvent(
newEventType: string,
e: JQuery.DoubleClickEvent | JQuery.MouseDownEvent
e: JQuery.DoubleClickEvent | JQuery.MouseDownEvent,
) {
// Extract important info from e and construct a new event with type
// eventType.

View File

@@ -1,11 +1,11 @@
import $ from "jquery";
import { imageOutputBinding } from "../bindings/output/image";
import type { InputRatePolicy } from "../inputPolicies";
import { shinySetInputValue } from "../shiny/initedMethods";
import { Debouncer, Throttler } from "../time";
import type { Bounds, BoundsCss, BrushOpts } from "./createBrush";
import { createBrush } from "./createBrush";
import type { Offset } from "./findbox";
import { findImageOutputs } from "./imageBindingUtils";
import type { Coordmap } from "./initCoordmap";
import type { Panel } from "./initPanelScales";
@@ -53,7 +53,7 @@ type NullOutside = Parameters<Coordmap["mouseCoordinateSender"]>[2];
function createClickHandler(
inputId: InputId,
clip: Clip,
coordmap: Coordmap
coordmap: Coordmap,
): CreateHandler {
const clickInfoSender = coordmap.mouseCoordinateSender(inputId, clip);
@@ -79,12 +79,12 @@ function createHoverHandler(
delayType: string | "throttle",
clip: Clip,
nullOutside: NullOutside,
coordmap: Coordmap
coordmap: Coordmap,
): CreateHandler {
const sendHoverInfo = coordmap.mouseCoordinateSender(
inputId,
clip,
nullOutside
nullOutside,
);
let hoverInfoSender: InputRatePolicy<typeof sendHoverInfo>;
@@ -127,7 +127,7 @@ function createBrushHandler(
$el: JQuery<HTMLElement>,
opts: BrushOpts,
coordmap: Coordmap,
outputId: BrushInfo["outputId"]
outputId: BrushInfo["outputId"],
): CreateHandler {
// Parameter: expand the area in which a brush can be started, by this
// many pixels in all directions. (This should probably be a brush option)
@@ -168,10 +168,10 @@ function createBrushHandler(
| "nesw-resize"
| "ns-resize"
| "nwse-resize"
| null
| null,
) {
$el.removeClass(
"crosshair grabbable grabbing ns-resize ew-resize nesw-resize nwse-resize"
"crosshair grabbable grabbing ns-resize ew-resize nesw-resize nwse-resize",
);
if (style) $el.addClass(style);
@@ -184,27 +184,25 @@ function createBrushHandler(
if (isNaN(coords.xmin)) {
shinySetInputValue(inputId, null);
// Must tell other brushes to clear.
imageOutputBinding
.find(document.documentElement)
.trigger("shiny-internal:brushed", {
findImageOutputs(document.documentElement).trigger(
"shiny-internal:brushed",
{
brushId: inputId,
outputId: null,
});
},
);
return;
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const panel = brush.getPanel()!;
// Add the panel (facet) variables, if present
$.extend(coords, panel.panel_vars);
// eslint-disable-next-line camelcase
coords.coords_css = brush.boundsCss();
// eslint-disable-next-line camelcase
coords.coords_img = coordmap.scaleCssToImg(coords.coords_css);
// eslint-disable-next-line camelcase
coords.img_css_ratio = coordmap.cssToImgScalingRatio();
// Add variable name mappings
@@ -224,9 +222,10 @@ function createBrushHandler(
shinySetInputValue(inputId, coords);
$el.data("mostRecentBrush", true);
imageOutputBinding
.find(document.documentElement)
.trigger("shiny-internal:brushed", coords);
findImageOutputs(document.documentElement).trigger(
"shiny-internal:brushed",
coords,
);
}
let brushInfoSender:
@@ -265,7 +264,6 @@ function createBrushHandler(
brush.down(offsetCss);
if (brush.isInResizeArea(offsetCss)) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error; TODO-barret; Remove the variable? it is not used
brush.startResizing(offsetCss);
@@ -439,5 +437,5 @@ function createBrushHandler(
};
}
export { createClickHandler, createHoverHandler, createBrushHandler };
export { createBrushHandler, createClickHandler, createHoverHandler };
export type { BrushInfo };

View File

@@ -1,6 +1,6 @@
function disableDrag(
$el: JQuery<HTMLElement>,
$img: JQuery<HTMLElement>
$img: JQuery<HTMLElement>,
): void {
// Make image non-draggable (Chrome, Safari)
$img.css("-webkit-user-drag", "none");

View File

@@ -18,5 +18,5 @@ function findBox(offset1: Offset, offset2: Offset): Bounds {
};
}
export type { Offset };
export { findBox };
export type { Offset };

View File

@@ -0,0 +1,7 @@
import $ from "jquery";
export function findImageOutputs(
scope: HTMLElement = document.documentElement,
): JQuery<HTMLElement> {
return $(scope).find(".shiny-image-output, .shiny-plot-output");
}

View File

@@ -7,19 +7,21 @@ import {
} from "./createHandlers";
import { disableDrag } from "./disableDrag";
import { findBox } from "./findbox";
import { findImageOutputs } from "./imageBindingUtils";
import { initCoordmap } from "./initCoordmap";
import { initPanelScales } from "./initPanelScales";
import { shiftToRange } from "./shiftToRange";
export {
disableDrag,
initPanelScales,
initCoordmap,
findBox,
shiftToRange,
createClickInfo,
createClickHandler,
createHoverHandler,
createBrushHandler,
createBrush,
createBrushHandler,
createClickHandler,
createClickInfo,
createHoverHandler,
disableDrag,
findBox,
findImageOutputs,
initCoordmap,
initPanelScales,
shiftToRange,
};

View File

@@ -16,15 +16,13 @@ function findScalingRatio($el: JQuery<HTMLElement>) {
const boundingRect = $el[0].getBoundingClientRect();
return {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
x: boundingRect.width / $el.outerWidth()!,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
y: boundingRect.height / $el.outerHeight()!,
};
}
function findOrigin($el: JQuery<HTMLElement>): Offset {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const offset = $el.offset()!;
const scalingRatio = findScalingRatio($el);
@@ -53,9 +51,8 @@ function findDims($el: JQuery<HTMLElement>) {
// If there's any padding/border, we need to find the ratio of the actual
// element content compared to the element plus padding and border.
const contentRatio = {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
x: $el.width()! / $el.outerWidth()!,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
y: $el.height()! / $el.outerHeight()!,
};
@@ -125,7 +122,7 @@ type Coordmap = {
mouseCoordinateSender: (
inputId: string,
clip?: boolean,
nullOutside?: boolean
nullOutside?: boolean,
) => (e: JQuery.MouseDownEvent | JQuery.MouseMoveEvent | null) => void;
};
@@ -150,7 +147,7 @@ type Coordmap = {
// than the other two, because there can be multiple panels (as in facets).
function initCoordmap(
$el: JQuery<HTMLElement>,
coordmap_: CoordmapInit
coordmap_: CoordmapInit,
): Coordmap {
const $img = $el.find("img");
const img = $img[0];
@@ -350,7 +347,7 @@ function initCoordmap(
coordmap.mouseCoordinateSender = function (
inputId,
clip = true,
nullOutside = false
nullOutside = false,
) {
return function (e) {
if (e === null) {
@@ -377,7 +374,7 @@ function initCoordmap(
shinySetInputValue(inputId, coords, { priority: "event" });
return;
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const panel = coordmap.getPanelCss(coordsCss)!;
const coordsImg = coordmap.scaleCssToImg(coordsCss);

View File

@@ -11,7 +11,7 @@ function mapLinear(
domainMax: number,
rangeMin: number,
rangeMax: number,
clip = true
clip = true,
) {
// By default, clip to range
clip = clip || true;
@@ -36,7 +36,7 @@ function scaler1D(
domainMax: number,
rangeMin: number,
rangeMax: number,
logbase: number | null
logbase: number | null,
) {
return {
scale: function (val: number, clip?: boolean) {
@@ -107,7 +107,7 @@ function addScaleFuns(panel_: PanelInit): Panel {
// };
function scaleDataToImg(
val: Bounds,
clip?: Parameters<typeof xscaler.scale>[1]
clip?: Parameters<typeof xscaler.scale>[1],
): Bounds {
return mapValues(val, (value, key) => {
const prefix = key.substring(0, 1);
@@ -168,5 +168,5 @@ function initPanelScales(panels: PanelInit[]): Panel[] {
return panels.map((panel) => addScaleFuns(panel));
}
export type { Panel, PanelInit };
export { initPanelScales };
export type { Panel, PanelInit };

View File

@@ -5,7 +5,7 @@
function shiftToRange(
vals: number[] | number,
min: number,
max: number
max: number,
): number[] {
if (!(vals instanceof Array)) vals = [vals];

View File

@@ -10,7 +10,7 @@ function getIEVersion() {
// IE 10 or older => return version number
return parseInt(
userAgent.substring(msie + 5, userAgent.indexOf(".", msie)),
10
10,
);
}
const trident = userAgent.indexOf("Trident/");
@@ -21,7 +21,7 @@ function getIEVersion() {
return parseInt(
userAgent.substring(rv + 3, userAgent.indexOf(".", rv)),
10
10,
);
}
return -1;

View File

@@ -10,10 +10,10 @@ import type { InputRatePolicy } from "./inputRatePolicy";
export {
InputBatchSender,
InputDeferDecorator,
InputEventDecorator,
InputNoResendDecorator,
InputRateDecorator,
InputDeferDecorator,
InputValidateDecorator,
};
export type { InputPolicy, EventPriority, InputRatePolicy };
export type { EventPriority, InputPolicy, InputRatePolicy };

View File

@@ -16,4 +16,4 @@ interface InputPolicy {
setInput(name: string, value: unknown, opts: InputPolicyOpts): void;
}
export type { InputPolicy, EventPriority, InputPolicyOpts };
export type { EventPriority, InputPolicy, InputPolicyOpts };

View File

@@ -33,7 +33,7 @@ class InputRateDecorator implements InputPolicy {
setRatePolicy(
nameType: string,
mode: RatePolicyModes,
millis?: number
millis?: number,
): void {
const { name: inputName } = splitInputNameType(nameType);
@@ -43,13 +43,13 @@ class InputRateDecorator implements InputPolicy {
this.inputRatePolicies[inputName] = new Debouncer(
this,
this._doSetInput,
millis
millis,
);
} else if (mode === "throttle") {
this.inputRatePolicies[inputName] = new Throttler(
this,
this._doSetInput,
millis
millis,
);
}
}
@@ -59,7 +59,7 @@ class InputRateDecorator implements InputPolicy {
private _doSetInput(
nameType: string,
value: unknown,
opts: InputPolicyOpts
opts: InputPolicyOpts,
): void {
this.target.setInput(nameType, value, opts);
}

View File

@@ -14,7 +14,7 @@ function addDefaultInputOpts(opts: Partial<InputPolicyOpts>): InputPolicyOpts {
break;
default:
throw new Error(
"Unexpected input value mode: '" + newOpts.priority + "'"
"Unexpected input value mode: '" + newOpts.priority + "'",
);
}
@@ -30,7 +30,7 @@ class InputValidateDecorator implements InputPolicy {
setInput(
nameType: string,
value: unknown,
opts: Partial<InputPolicyOpts> = {}
opts: Partial<InputPolicyOpts> = {},
): void {
if (!nameType) throw "Can't set input with empty name.";
@@ -40,4 +40,4 @@ class InputValidateDecorator implements InputPolicy {
}
}
export { InputValidateDecorator, addDefaultInputOpts };
export { addDefaultInputOpts, InputValidateDecorator };

View File

@@ -1,5 +1,4 @@
import $ from "jquery";
import { Shiny } from "..";
import type { InputBinding, OutputBinding } from "../bindings";
import type { SubscribeEventPriority } from "../bindings/input/inputBinding";
import { OutputBindingAdapter } from "../bindings/outputAdapter";
@@ -29,7 +28,7 @@ function valueChangeCallback(
inputs: InputValidateDecorator,
binding: InputBinding,
el: HTMLElement,
priority?: SubscribeEventPriority
priority?: SubscribeEventPriority,
) {
let id = binding.getId(el);
@@ -48,7 +47,7 @@ function valueChangeCallback(
// Narrow the type of the subscribe callback value to EventPriority
function normalizeEventPriority(
priority?: SubscribeEventPriority
priority?: SubscribeEventPriority,
): EventPriority {
if (priority === false || priority === undefined) {
return "immediate";
@@ -233,10 +232,11 @@ type BindInputsCtx = {
sendOutputHiddenState: () => void;
maybeAddThemeObserver: (el: HTMLElement) => void;
initDeferredIframes: () => void;
outputIsRecalculating: (id: string) => boolean;
};
function bindInputs(
shinyCtx: BindInputsCtx,
scope: BindScope = document.documentElement
scope: BindScope = document.documentElement,
): {
[key: string]: {
value: ReturnType<InputBinding["getValue"]>;
@@ -300,7 +300,7 @@ function bindInputs(
inputsRate.setRatePolicy(
effectiveId,
ratePolicy.policy,
ratePolicy.delay
ratePolicy.delay,
);
}
@@ -322,8 +322,9 @@ async function bindOutputs(
sendOutputHiddenState,
maybeAddThemeObserver,
outputBindings,
outputIsRecalculating,
}: BindInputsCtx,
scope: BindScope = document.documentElement
scope: BindScope = document.documentElement,
): Promise<void> {
const $scope = $(scope);
@@ -367,7 +368,7 @@ async function bindOutputs(
$el.addClass("shiny-bound-output");
if (!$el.attr("aria-live")) $el.attr("aria-live", "polite");
if (Shiny.shinyapp?.$outputProgress.isRecalculating(id)) {
if (outputIsRecalculating(id)) {
bindingAdapter.showProgress(true);
}
@@ -388,7 +389,7 @@ async function bindOutputs(
function unbindInputs(
scope: BindScope = document.documentElement,
includeSelf = false
includeSelf = false,
) {
const inputs: Array<HTMLElement | JQuery<HTMLElement>> = $(scope)
.find(".shiny-bound-input")
@@ -420,7 +421,7 @@ function unbindInputs(
function unbindOutputs(
{ sendOutputHiddenState }: BindInputsCtx,
scope: BindScope = document.documentElement,
includeSelf = false
includeSelf = false,
) {
const outputs: Array<HTMLElement | JQuery<HTMLElement>> = $(scope)
.find(".shiny-bound-output")
@@ -459,7 +460,7 @@ function unbindOutputs(
// eslint-disable-next-line @typescript-eslint/naming-convention
async function _bindAll(
shinyCtx: BindInputsCtx,
scope: BindScope
scope: BindScope,
): Promise<ReturnType<typeof bindInputs>> {
await bindOutputs(shinyCtx, scope);
const currentInputs = bindInputs(shinyCtx, scope);
@@ -476,14 +477,14 @@ async function _bindAll(
function unbindAll(
shinyCtx: BindInputsCtx,
scope: BindScope,
includeSelf = false
includeSelf = false,
): void {
unbindInputs(scope, includeSelf);
unbindOutputs(shinyCtx, scope, includeSelf);
}
async function bindAll(
shinyCtx: BindInputsCtx,
scope: BindScope
scope: BindScope,
): Promise<void> {
// _bindAll returns input values; it doesn't send them to the server.
// Shiny.bindAll needs to send the values to the server.
@@ -502,5 +503,5 @@ async function bindAll(
shinyCtx.initDeferredIframes();
}
export { unbindAll, bindAll, _bindAll };
export type { BindScope, BindInputsCtx };
export { _bindAll, bindAll, unbindAll };
export type { BindInputsCtx, BindScope };

View File

@@ -25,12 +25,13 @@ import {
getComputedLinkColor,
getStyle,
hasDefinedProperty,
isShinyInDevMode,
mapValues,
pixelRatio,
} from "../utils";
import { createInitStatus, type InitStatusPromise } from "../utils/promise";
import type { BindInputsCtx, BindScope } from "./bind";
import { bindAll, unbindAll, _bindAll } from "./bind";
import { _bindAll, bindAll, unbindAll } from "./bind";
import type {
shinyBindAll,
shinyForgetLastInputValue,
@@ -156,10 +157,7 @@ class ShinyClass {
* @returns `true` if Shiny is running in development mode, `false` otherwise.
*/
inDevMode(): boolean {
if ("__SHINY_DEV_MODE__" in window)
return Boolean(window.__SHINY_DEV_MODE__);
return false;
return isShinyInDevMode();
}
async initialize(): Promise<void> {
@@ -197,7 +195,7 @@ class ShinyClass {
this.setInputValue = this.onInputChange = function (
name: string,
value: unknown,
opts: Partial<InputPolicyOpts> = {}
opts: Partial<InputPolicyOpts> = {},
): void {
const newOpts = addDefaultInputOpts(opts);
@@ -218,7 +216,7 @@ class ShinyClass {
const inputBindings = this.inputBindings;
const outputBindings = this.outputBindings;
function shinyBindCtx(): BindInputsCtx {
const shinyBindCtx = (): BindInputsCtx => {
return {
inputs,
inputsRate,
@@ -227,8 +225,10 @@ class ShinyClass {
inputBindings,
outputBindings,
initDeferredIframes,
outputIsRecalculating: (id: string) =>
this.shinyapp?.$outputProgress.isRecalculating(id) ?? false,
};
}
};
this.bindAll = async function (scope: BindScope) {
await bindAll(shinyBindCtx(), scope);
@@ -282,7 +282,7 @@ class ShinyClass {
// GC'd.
const initialValues = mapValues(
await _bindAll(shinyBindCtx(), document.documentElement),
(x) => x.value
(x) => x.value,
);
// The server needs to know the size of each image and plot output element,
@@ -296,11 +296,11 @@ class ShinyClass {
initialValues[".clientdata_output_" + id + "_width"] = rect.width;
initialValues[".clientdata_output_" + id + "_height"] = rect.height;
}
}
},
);
function getComputedBgColor(
el: HTMLElement | null
el: HTMLElement | null,
): string | null | undefined {
if (!el) {
// Top of document, can't recurse further
@@ -311,7 +311,7 @@ class ShinyClass {
if (!bgColor) return bgColor;
const m = bgColor.match(
/^rgba\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)$/
/^rgba\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)$/,
);
if (bgColor === "transparent" || (m && parseFloat(m[4]) === 0)) {
@@ -349,14 +349,14 @@ class ShinyClass {
getComputedBgColor(el);
initialValues[".clientdata_output_" + id + "_fg"] = getStyle(
el,
"color"
"color",
);
initialValues[".clientdata_output_" + id + "_accent"] =
getComputedLinkColor(el);
initialValues[".clientdata_output_" + id + "_font"] =
getComputedFont(el);
maybeAddThemeObserver(el);
}
},
);
// Resend computed styles if *an output element's* class or style attribute changes.
@@ -389,7 +389,7 @@ class ShinyClass {
const observerCallback = new Debouncer(null, () => doSendTheme(el), 100);
const observer = new MutationObserver(() =>
observerCallback.normalCall()
observerCallback.normalCall(),
);
const config = { attributes: true, attributeFilter: ["style", "class"] };
@@ -406,19 +406,19 @@ class ShinyClass {
inputs.setInput(
".clientdata_output_" + id + "_bg",
getComputedBgColor(el)
getComputedBgColor(el),
);
inputs.setInput(
".clientdata_output_" + id + "_fg",
getStyle(el, "color")
getStyle(el, "color"),
);
inputs.setInput(
".clientdata_output_" + id + "_accent",
getComputedLinkColor(el)
getComputedLinkColor(el),
);
inputs.setInput(
".clientdata_output_" + id + "_font",
getComputedFont(el)
getComputedFont(el),
);
}
@@ -432,16 +432,16 @@ class ShinyClass {
inputs.setInput(".clientdata_output_" + id + "_width", rect.width);
inputs.setInput(
".clientdata_output_" + id + "_height",
rect.height
rect.height,
);
}
}
},
);
$(".shiny-image-output, .shiny-plot-output, .shiny-report-theme").each(
function () {
doSendTheme(this);
}
},
);
$(".shiny-bound-output").each(function () {
@@ -528,7 +528,7 @@ class ShinyClass {
const sendOutputHiddenStateDebouncer = new Debouncer(
null,
doSendOutputHiddenState,
0
0,
);
function sendOutputHiddenState() {
@@ -584,7 +584,7 @@ class ShinyClass {
$(document.body).on(
"shown.bs." + classname + ".sendImageSize",
"*",
filterEventsByNamespace("bs", sendImageSizeFns.regular)
filterEventsByNamespace("bs", sendImageSizeFns.regular),
);
$(document.body).on(
"shown.bs." +
@@ -594,7 +594,7 @@ class ShinyClass {
classname +
".sendOutputHiddenState",
"*",
filterEventsByNamespace("bs", sendOutputHiddenState)
filterEventsByNamespace("bs", sendOutputHiddenState),
);
});
@@ -604,7 +604,7 @@ class ShinyClass {
$(document.body).on(
"shown.sendOutputHiddenState hidden.sendOutputHiddenState",
"*",
sendOutputHiddenState
sendOutputHiddenState,
);
// Send initial pixel ratio, and update it if it changes
@@ -625,13 +625,13 @@ class ShinyClass {
$(window).on("pushstate", function (e) {
inputs.setInput(".clientdata_url_search", window.location.search);
return;
e;
e; // eslint-disable-line @typescript-eslint/no-unused-expressions
});
$(window).on("popstate", function (e) {
inputs.setInput(".clientdata_url_search", window.location.search);
return;
e;
e; // eslint-disable-line @typescript-eslint/no-unused-expressions
});
// This is only the initial value of the hash. The hash can change, but
@@ -644,19 +644,19 @@ class ShinyClass {
$(window).on("hashchange", function (e) {
inputs.setInput(".clientdata_url_hash", window.location.hash);
return;
e;
e; // eslint-disable-line @typescript-eslint/no-unused-expressions
});
// The server needs to know what singletons were rendered as part of
// the page loading
const singletonText = (initialValues[".clientdata_singletons"] = $(
'script[type="application/shiny-singletons"]'
'script[type="application/shiny-singletons"]',
).text());
singletonsRegisterNames(singletonText.split(/,/));
const dependencyText = $(
'script[type="application/html-dependencies"]'
'script[type="application/html-dependencies"]',
).text();
$.each(dependencyText.split(/;/), function (i, depStr) {

View File

@@ -42,7 +42,7 @@ function validateShinyHasBeenSet(): FullShinyDef {
function shinySetInputValue(
name: string,
value: unknown,
opts?: { priority?: EventPriority }
opts?: { priority?: EventPriority },
): void {
validateShinyHasBeenSet().setInputValue(name, value, opts);
}
@@ -67,14 +67,14 @@ function shinyInitializeInputs(scope: BindScope): void {
async function shinyAppBindOutput(
id: string,
binding: OutputBindingAdapter
binding: OutputBindingAdapter,
): Promise<void> {
await shinyShinyApp().bindOutput(id, binding);
}
function shinyAppUnbindOutput(
id: string,
binding: OutputBindingAdapter
binding: OutputBindingAdapter,
): boolean {
return shinyShinyApp().unbindOutput(id, binding);
}
@@ -97,18 +97,18 @@ function getShinyCreateWebsocket(): (() => WebSocket) | void {
}
export {
getFileInputBinding,
getShinyCreateWebsocket,
getShinyOnCustomMessage,
setFileInputBinding,
setShinyObj,
shinySetInputValue,
shinyShinyApp,
setShinyUser,
shinyForgetLastInputValue,
shinyBindAll,
shinyUnbindAll,
shinyInitializeInputs,
shinyAppBindOutput,
shinyAppUnbindOutput,
getShinyOnCustomMessage,
getFileInputBinding,
setFileInputBinding,
getShinyCreateWebsocket,
shinyBindAll,
shinyForgetLastInputValue,
shinyInitializeInputs,
shinySetInputValue,
shinyShinyApp,
shinyUnbindAll,
};

View File

@@ -84,4 +84,4 @@ function remove(): void {
}
}
export { show as showModal, remove as removeModal };
export { remove as removeModal, show as showModal };

View File

@@ -145,7 +145,7 @@ function create(id: string): JQuery<HTMLElement> {
`<div id="shiny-notification-${id}" class="shiny-notification">` +
'<div class="shiny-notification-close">&times;</div>' +
'<div class="shiny-notification-content"></div>' +
"</div>"
"</div>",
);
$notification.find(".shiny-notification-close").on("click", (e) => {
@@ -185,4 +185,4 @@ function clearRemovalCallback(id: string) {
}
}
export { show as showNotification, remove as removeNotification };
export { remove as removeNotification, show as showNotification };

View File

@@ -146,7 +146,7 @@ class OutputProgressReporter {
default:
throw new Error(
`Shiny server sent a message that the output '${name}' is recalculating,
but the output is in an unexpected state of: '${state}'.`
but the output is in an unexpected state of: '${state}'.`,
);
}
}
@@ -159,7 +159,7 @@ class OutputProgressReporter {
default:
throw new Error(
`Shiny server sent a message that the output '${name}' has been recalculated,
but the output is in an unexpected state of: '${state}'.`
but the output is in an unexpected state of: '${state}'.`,
);
}
}
@@ -190,7 +190,7 @@ class OutputProgressReporter {
default:
throw new Error(
`Shiny server sent a flush message, and after processing the values and errors,
the output '${name}' has an unexpected ending state of: '${state}'.`
the output '${name}' has an unexpected ending state of: '${state}'.`,
);
}
}
@@ -207,7 +207,7 @@ class OutputProgressReporter {
default:
throw new Error(
`Shiny server has sent a 'persistent progress' message for ${id},
but the output is in an unexpected state of: ${state}`
but the output is in an unexpected state of: ${state}`,
);
}
} else {
@@ -222,7 +222,7 @@ class OutputProgressReporter {
default:
throw new Error(
`Shiny server has sent a progress message for ${id},
but the output is in an unexpected state of: ${state}`
but the output is in an unexpected state of: ${state}`,
);
}
}
@@ -232,7 +232,7 @@ class OutputProgressReporter {
// be moving from Idle to Value/Error state.
#updateStateFromValueOrError(
name: string,
type: OutputStates.Error | OutputStates.Value
type: OutputStates.Error | OutputStates.Value,
): void {
const state = this.#getState(name);
switch (state) {
@@ -242,7 +242,7 @@ class OutputProgressReporter {
default:
throw new Error(
`Shiny server has sent a ${type} for the output '${name}',
but the output is in an unexpected state of: '${state}'.`
but the output is in an unexpected state of: '${state}'.`,
);
}
}

View File

@@ -50,7 +50,7 @@ function initReactlog(): void {
window.escape(shinyAppConfig().sessionId);
// send notification
/* eslint-disable-next-line @typescript-eslint/no-floating-promises */
$.get(url, function (result: "marked" | void) {
if (result !== "marked") return;

View File

@@ -50,4 +50,4 @@ function hideReconnectDialog(): void {
removeNotification("reconnect");
}
export { showReconnectDialog, hideReconnectDialog };
export { hideReconnectDialog, showReconnectDialog };

View File

@@ -1,6 +1,6 @@
import $ from "jquery";
import { asArray, hasDefinedProperty } from "../utils";
import { isIE } from "../utils/browser";
import { asArray, hasDefinedProperty } from "../utils/object";
import type { BindScope } from "./bind";
import {
shinyBindAll,
@@ -38,7 +38,7 @@ import { renderHtml as singletonsRenderHtml } from "./singletons";
async function renderContentAsync(
el: BindScope,
content: string | { html: string; deps?: HtmlDep[] } | null,
where: WherePosition = "replace"
where: WherePosition = "replace",
): Promise<void> {
if (where === "replace") {
shinyUnbindAll(el);
@@ -82,7 +82,7 @@ async function renderContentAsync(
function renderContent(
el: BindScope,
content: string | { html: string; deps?: HtmlDep[] } | null,
where: WherePosition = "replace"
where: WherePosition = "replace",
): Promise<void> {
if (where === "replace") {
shinyUnbindAll(el);
@@ -131,7 +131,7 @@ async function renderHtmlAsync(
html: string,
el: BindScope,
dependencies: HtmlDep[],
where: WherePosition = "replace"
where: WherePosition = "replace",
): Promise<ReturnType<typeof singletonsRenderHtml>> {
await renderDependenciesAsync(dependencies);
return singletonsRenderHtml(html, el, where);
@@ -142,7 +142,7 @@ function renderHtml(
html: string,
el: BindScope,
dependencies: HtmlDep[],
where: WherePosition = "replace"
where: WherePosition = "replace",
): ReturnType<typeof singletonsRenderHtml> {
renderDependencies(dependencies);
return singletonsRenderHtml(html, el, where);
@@ -152,7 +152,7 @@ function renderHtml(
// renderDependencies
// =============================================================================
async function renderDependenciesAsync(
dependencies: HtmlDep[] | null
dependencies: HtmlDep[] | null,
): Promise<void> {
if (dependencies) {
for (const dep of dependencies) {
@@ -372,14 +372,14 @@ function getStylesheetLinkTags(dep: HtmlDepNormalized): HTMLLinkElement[] {
// pass them through to `addStylesheetsAndRestyle` below.
return dep.stylesheet.map((x) => {
// Add "rel" and "type" fields if not already present.
if (!hasDefinedProperty(x, "rel")) x.rel = "stylesheet";
if (!hasDefinedProperty(x, "type")) x.type = "text/css";
if (x.rel === undefined) x.rel = "stylesheet";
if (x.type === undefined) x.type = "text/css";
const link = document.createElement("link");
Object.entries(x).forEach(function ([attr, val]: [
string,
string | undefined
string | undefined,
]) {
if (attr === "href") {
val = encodeURI(val as string);
@@ -394,7 +394,7 @@ function getStylesheetLinkTags(dep: HtmlDepNormalized): HTMLLinkElement[] {
function appendStylesheetLinkTags(
dep: HtmlDepNormalized,
$head: JQuery<HTMLElement>
$head: JQuery<HTMLElement>,
): void {
const stylesheetLinks = getStylesheetLinkTags(dep);
@@ -468,7 +468,7 @@ async function appendScriptTagsAsync(dep: HtmlDepNormalized): Promise<void> {
function appendMetaTags(
dep: HtmlDepNormalized,
$head: JQuery<HTMLElement>
$head: JQuery<HTMLElement>,
): void {
dep.meta.forEach((x) => {
const meta = document.createElement("meta");
@@ -482,7 +482,7 @@ function appendMetaTags(
function appendAttachmentLinkTags(
dep: HtmlDepNormalized,
$head: JQuery<HTMLElement>
$head: JQuery<HTMLElement>,
): void {
dep.attachment.forEach((x) => {
const link = $("<link rel='attachment'>")
@@ -495,7 +495,7 @@ function appendAttachmentLinkTags(
function appendExtraHeadContent(
dep: HtmlDepNormalized,
$head: JQuery<HTMLElement>
$head: JQuery<HTMLElement>,
): void {
if (dep.head) {
const $newHead = $("<head></head>");
@@ -684,12 +684,12 @@ function normalizeHtmlDependency(dep: HtmlDep): HtmlDepNormalized {
}
export {
renderContentAsync,
renderContent,
renderHtmlAsync,
renderHtml,
renderDependenciesAsync,
renderDependencies,
registerDependency,
renderContent,
renderContentAsync,
renderDependencies,
renderDependenciesAsync,
renderHtml,
renderHtmlAsync,
};
export type { HtmlDep };

View File

@@ -9,7 +9,7 @@ class SendImageSize {
setImageSend(
inputBatchSender: InputBatchSender,
doSendImageSize: () => void
doSendImageSize: () => void,
): Debouncer<typeof doSendImageSize> {
const sendImageSizeDebouncer = new Debouncer(null, doSendImageSize, 0);

View File

@@ -212,7 +212,7 @@ class ShinyApp {
defaultPath += "websocket/";
const ws: ShinyWebSocket = new WebSocket(
protocol + "//" + window.location.host + defaultPath
protocol + "//" + window.location.host + defaultPath,
);
ws.binaryType = "arraybuffer";
@@ -238,7 +238,7 @@ class ShinyApp {
JSON.stringify({
method: "init",
data: this.$initialInput,
})
}),
);
while (this.$pendingMessages.length) {
@@ -278,7 +278,6 @@ class ShinyApp {
}
async startActionQueueLoop(): Promise<void> {
// eslint-disable-next-line no-constant-condition
while (true) {
try {
const action = await this.taskQueue.dequeue();
@@ -361,7 +360,6 @@ class ShinyApp {
// only be used for testing.
if (
(this.$allowReconnect === true &&
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.$socket!.allowReconnect === true) ||
this.$allowReconnect === "force"
) {
@@ -407,7 +405,7 @@ class ShinyApp {
args: unknown[],
onSuccess: OnSuccessRequest,
onError: OnErrorRequest,
blobs: Array<ArrayBuffer | Blob | string> | undefined
blobs: Array<ArrayBuffer | Blob | string> | undefined,
): void {
let requestId = this.$nextRequestId;
@@ -455,8 +453,8 @@ class ShinyApp {
payload.push(
uint32ToBuf(
(blob as ArrayBuffer).byteLength || (blob as Blob).size || 0
)
(blob as ArrayBuffer).byteLength || (blob as Blob).size || 0,
),
);
payload.push(blob);
}
@@ -522,7 +520,7 @@ class ShinyApp {
async bindOutput(
id: string,
binding: OutputBindingAdapter
binding: OutputBindingAdapter,
): Promise<OutputBindingAdapter> {
if (!id) throw new Error("Can't bind an element with no ID");
this.$bindings[id] = binding;
@@ -549,7 +547,7 @@ class ShinyApp {
// necessary.
private _narrowScopeComponent<T>(
scopeComponent: { [key: string]: T },
nsPrefix: string
nsPrefix: string,
) {
return Object.keys(scopeComponent)
.filter((k) => k.indexOf(nsPrefix) === 0)
@@ -569,7 +567,7 @@ class ShinyApp {
input: InputValues;
output: { [key: string]: any };
},
nsPrefix: string
nsPrefix: string,
) {
if (nsPrefix) {
return {
@@ -672,7 +670,7 @@ class ShinyApp {
await this._sendMessagesToHandlers(
evt.message,
messageHandlers,
messageHandlerOrder
messageHandlerOrder,
);
this.$updateConditionals();
@@ -685,7 +683,7 @@ class ShinyApp {
private async _sendMessagesToHandlers(
msgObj: { [key: string]: unknown },
handlers: { [key: string]: Handler },
handlerOrder: string[]
handlerOrder: string[],
): Promise<void> {
// Dispatch messages to handlers, if handler is present
for (let i = 0; i < handlerOrder.length; i++) {
@@ -737,7 +735,7 @@ class ShinyApp {
this.receiveError(key, message[key]);
}
}
}
},
);
addMessageHandler(
@@ -763,13 +761,13 @@ class ShinyApp {
} catch (error) {
console.error(
"[shiny] Error in inputBinding.receiveMessage()",
{ error, binding: inputBinding, message: evt.message }
{ error, binding: inputBinding, message: evt.message },
);
}
}
}
}
}
},
);
addMessageHandler("javascript", (message: string) => {
@@ -792,7 +790,7 @@ class ShinyApp {
if (handler) handler.call(this, message.message);
}
}
},
);
addMessageHandler(
@@ -801,12 +799,12 @@ class ShinyApp {
message:
| { type: "remove"; message: string }
| { type: "show"; message: Parameters<typeof showNotification>[0] }
| { type: void }
| { type: void },
) => {
if (message.type === "show") await showNotification(message.message);
else if (message.type === "remove") removeNotification(message.message);
else throw "Unkown notification type: " + message.type;
}
},
);
addMessageHandler(
@@ -815,13 +813,13 @@ class ShinyApp {
message:
| { type: "remove"; message: string }
| { type: "show"; message: Parameters<typeof showModal>[0] }
| { type: void }
| { type: void },
) => {
if (message.type === "show") await showModal(message.message);
// For 'remove', message content isn't used
else if (message.type === "remove") removeModal();
else throw "Unkown modal type: " + message.type;
}
},
);
addMessageHandler(
@@ -836,7 +834,7 @@ class ShinyApp {
request.onSuccess(message.value as UploadInitValue);
else request.onError(message.error as string);
}
}
},
);
addMessageHandler("allowReconnect", (message: "force" | false | true) => {
@@ -862,7 +860,7 @@ class ShinyApp {
await this._sendMessagesToHandlers(
message,
customMessageHandlers,
customMessageHandlerOrder
customMessageHandlerOrder,
);
});
@@ -875,7 +873,7 @@ class ShinyApp {
};
if (message.user) setShinyUser(message.user);
$(document).trigger("shiny:sessioninitialized");
}
},
);
addMessageHandler("busy", (message: "busy" | "idle") => {
@@ -906,13 +904,13 @@ class ShinyApp {
$().trigger("shiny:" + message.status);
}
}
}
},
);
addMessageHandler("reload", (message: true) => {
window.location.reload();
return;
message;
message; // eslint-disable-line @typescript-eslint/no-unused-expressions
});
addMessageHandler(
@@ -932,12 +930,12 @@ class ShinyApp {
console.warn(
'The selector you chose ("' +
message.selector +
'") could not be found in the DOM.'
'") could not be found in the DOM.',
);
await renderHtmlAsync(
message.content.html,
$([]),
message.content.deps
message.content.deps,
);
} else {
for (const target of targets) {
@@ -946,7 +944,7 @@ class ShinyApp {
if (message.multiple === false) break;
}
}
}
},
);
addMessageHandler(
@@ -962,7 +960,7 @@ class ShinyApp {
// returning nothing continues removing all remaining elements.
return message.multiple === false ? false : undefined;
});
}
},
);
addMessageHandler("frozen", (message: { ids: string[] }) => {
@@ -987,7 +985,7 @@ class ShinyApp {
function getTabContent($tabset: JQuery<HTMLElement>) {
const tabsetId = $tabset.attr("data-tabsetid") as string;
const $tabContent = $(
"div.tab-content[data-tabsetid='" + $escape(tabsetId) + "']"
"div.tab-content[data-tabsetid='" + $escape(tabsetId) + "']",
);
return $tabContent;
@@ -996,7 +994,7 @@ class ShinyApp {
function getTargetTabs(
$tabset: JQuery<HTMLElement>,
$tabContent: JQuery<HTMLElement>,
target: string
target: string,
) {
const dataValue = "[data-value='" + $escape(target) + "']";
const $aTag = $tabset.find("a" + dataValue);
@@ -1071,7 +1069,7 @@ class ShinyApp {
const targetInfo = getTargetTabs(
$tabset,
$tabContent,
message.target as string
message.target as string,
);
$targetLiTag = targetInfo.$liTag;
@@ -1184,7 +1182,7 @@ class ShinyApp {
*/
function getTabIndex(
$tabset: JQuery<HTMLElement>,
tabsetId: string | undefined
tabsetId: string | undefined,
) {
// The 0 is to ensure this works for empty tabsetPanels as well
const existingTabIds = [0];
@@ -1196,10 +1194,10 @@ class ShinyApp {
if ($tab.length > 0) {
// remove leading url if it exists. (copy of bootstrap url stripper)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const href = $tab.attr("href")!.replace(/.*(?=#[^\s]+$)/, "");
// remove tab id to get the index
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const index = href!.replace("#tab-" + tabsetId + "-", "");
existingTabIds.push(Number(index));
@@ -1218,7 +1216,7 @@ class ShinyApp {
const $dropdownATag = $(
"a.dropdown-toggle[data-value='" +
$escape(message.menuName) +
"']"
"']",
);
if ($dropdownATag.length === 0) {
@@ -1245,7 +1243,7 @@ class ShinyApp {
}
return null;
}
}
},
);
// If the given tabset has no active tabs, select the first one
@@ -1282,7 +1280,7 @@ class ShinyApp {
function tabApplyFunction(
target: ReturnType<typeof getTargetTabs>,
func: ($el: JQuery<HTMLElement>) => void,
liTags = false
liTags = false,
) {
$.each(target, function (key, el) {
if (key === "$liTag") {
@@ -1294,7 +1292,7 @@ class ShinyApp {
el as ReturnType<typeof getTargetTabs>["$divTags"],
function (i, div) {
func(div);
}
},
);
} else if (liTags && key === "$liTags") {
// $liTags is always an array (even if length = 0)
@@ -1302,7 +1300,7 @@ class ShinyApp {
el as ReturnType<typeof getTargetTabs>["$liTags"],
function (i, div) {
func(div);
}
},
);
}
});
@@ -1323,7 +1321,7 @@ class ShinyApp {
shinyUnbindAll($el, true);
$el.remove();
}
}
},
);
addMessageHandler(
@@ -1348,7 +1346,7 @@ class ShinyApp {
$el.removeClass("active");
}
}
}
},
);
addMessageHandler(
@@ -1405,14 +1403,14 @@ class ShinyApp {
// This event needs to be triggered manually because pushState() never
// causes a hashchange event to be fired,
if (what === "hash") $(document).trigger("hashchange");
}
},
);
addMessageHandler(
"resetBrush",
(message: { brushId: Parameters<typeof resetBrush>[0] }) => {
resetBrush(message.brushId);
}
},
);
}
@@ -1422,7 +1420,7 @@ class ShinyApp {
// Progress for a particular object
binding: function (
this: ShinyApp,
message: { id: string; persistent: boolean }
message: { id: string; persistent: boolean },
): void {
const key = message.id;
const binding = this.$bindings[key];
@@ -1483,7 +1481,7 @@ class ShinyApp {
'<span class="progress-message">message</span>' +
'<span class="progress-detail"></span>' +
"</div>" +
"</div>"
"</div>",
);
$progress.attr("id", message.id);
@@ -1495,7 +1493,7 @@ class ShinyApp {
if ($progressBar) {
$progressBar.css(
"top",
depth * ($progressBar.height() as number) + "px"
depth * ($progressBar.height() as number) + "px",
);
// Stack text objects
@@ -1505,7 +1503,7 @@ class ShinyApp {
"top",
3 * ($progressBar.height() as number) +
depth * ($progressText.outerHeight() as number) +
"px"
"px",
);
$progress.hide();
@@ -1596,10 +1594,8 @@ class ShinyApp {
}
url +=
"/session/" +
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
encodeURIComponent(this.config!.sessionId) +
"/dataobj/shinytest?w=" +
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
encodeURIComponent(this.config!.workerId) +
"&nonce=" +
randomId();
@@ -1608,5 +1604,5 @@ class ShinyApp {
}
}
export { ShinyApp, addCustomMessageHandler };
export type { Handler, ErrorsMessageValue, ShinyWebSocket };
export { addCustomMessageHandler, ShinyApp };
export type { ErrorsMessageValue, Handler, ShinyWebSocket };

Some files were not shown because too many files have changed in this diff Show More