Merge branch 'master' into fix-ExpandableToolMenu-props
This commit is contained in:
commit
ee68b7bcd3
@ -27,4 +27,4 @@ mv platform/viewer/dist/* .netlify/www/pwa -v
|
||||
echo 'Nothing left to see here. Go home, folks.'
|
||||
|
||||
# Build using react-scripts
|
||||
# npx cross-env PUBLIC_URL=/demo REACT_APP_CONFIG=config/netlify.js react-scripts --max_old_space_size=4096 build
|
||||
# npx cross-env PUBLIC_URL=/demo APP_CONFIG=config/netlify.js react-scripts --max_old_space_size=4096 build
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<!-- CORNERSTONE.js -->
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://www.npmjs.com/package/ohif-cornerstone-extension">
|
||||
<a href="https://www.npmjs.com/package/@ohif/extension-cornerstone">
|
||||
Cornerstone
|
||||
</a>
|
||||
</td>
|
||||
@ -22,7 +22,7 @@
|
||||
<!-- VTK.js -->
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://www.npmjs.com/package/ohif-vtk-extension">
|
||||
<a href="https://www.npmjs.com/package/@ohif/extension-vtk">
|
||||
VTK.js
|
||||
</a>
|
||||
</td>
|
||||
@ -33,30 +33,30 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="">HTML</a>
|
||||
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-html">DICOM HTML</a>
|
||||
</td>
|
||||
<td>
|
||||
Renders text and HTML content for <a href="https://github.com/OHIF/Viewers/blob/react/extensions/ohif-dicom-html-extension/src/OHIFDicomHtmlSopClassHandler.js#L7-L15">specific SopClassUIDs</a>.
|
||||
Renders text and HTML content for <a href="https://github.com/OHIF/Viewers/blob/master/extensions/dicom-html/src/OHIFDicomHtmlSopClassHandler.js#L4-L12">specific SopClassUIDs</a>.
|
||||
</td>
|
||||
<td>Viewport, SopClassHandler</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://www.npmjs.com/package/ohif-dicom-pdf-extension">PDF</a>
|
||||
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-pdf">DICOM PDF</a>
|
||||
</td>
|
||||
<td>
|
||||
Renders PDFs for a <a href="https://github.com/OHIF/Viewers/blob/react/extensions/ohif-dicom-pdf-extension/src/OHIFDicomPDFSopClassHandler.js#L8">specific SopClassUID</a>.
|
||||
Renders PDFs for a <a href="https://github.com/OHIF/Viewers/blob/master/extensions/dicom-pdf/src/OHIFDicomPDFSopClassHandler.js#L4-L6">specific SopClassUID</a>.
|
||||
</td>
|
||||
<td>Viewport, SopClassHandler</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://www.npmjs.com/package/ohif-dicom-microscopy-extension">Microscopy</a>
|
||||
<a href="https://www.npmjs.com/package/@ohif/extension-dicom-microscopy">DICOM Microscopy</a>
|
||||
</td>
|
||||
<td>
|
||||
Renders Microscopy images for a <a href="https://github.com/OHIF/Viewers/blob/react/extensions/ohif-dicom-microscopy-extension/src/DicomMicroscopySopClassHandler.js#L6">specific SopClassUID</a>.
|
||||
Renders Microscopy images for a <a href="https://github.com/OHIF/Viewers/blob/master/extensions/dicom-microscopy/src/DicomMicroscopySopClassHandler.js#L5-L7">specific SopClassUID</a>.
|
||||
</td>
|
||||
<td>Viewport, SopClassHandler</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
||||
@ -152,7 +152,7 @@ is used depends on:
|
||||
<center><i>An example of three Viewports</i></center>
|
||||
|
||||
For a complete example implementation,
|
||||
[check out the OHIFCornerstoneViewport](https://github.com/OHIF/Viewers/blob/react/extensions/ohif-cornerstone-extension/src/OHIFCornerstoneViewport.js).
|
||||
[check out the OHIFCornerstoneViewport](https://github.com/OHIF/Viewers/blob/master/extensions/cornerstone/src/OHIFCornerstoneViewport.js).
|
||||
|
||||
#### Toolbar
|
||||
|
||||
@ -168,7 +168,7 @@ store.
|
||||
Toolbar components are rendered in the `ToolbarRow` component.
|
||||
|
||||
For a complete example implementation,
|
||||
[check out the OHIFCornerstoneViewport's Toolbar Module](https://github.com/OHIF/Viewers/blob/react/extensions/ohif-cornerstone-extension/src/ToolbarModule.js).
|
||||
[check out the OHIFCornerstoneViewport's Toolbar Module](https://github.com/OHIF/Viewers/blob/master/extensions/cornerstone/src/toolbarModule.js).
|
||||
|
||||
#### SopClassHandler
|
||||
|
||||
@ -197,9 +197,9 @@ would like included at startup.
|
||||
_app.js_
|
||||
|
||||
```js
|
||||
import { createStore, combineReducers } from "redux";
|
||||
import OHIF from "@ohif/core";
|
||||
import OHIFCornerstoneExtension from "ohif-cornerstone-extension";
|
||||
import { createStore, combineReducers } from 'redux';
|
||||
import OHIF from '@ohif/core';
|
||||
import OHIFCornerstoneExtension from 'ohif-cornerstone-extension';
|
||||
|
||||
const combined = combineReducers(OHIF.redux.reducers);
|
||||
const store = createStore(combined);
|
||||
@ -214,8 +214,8 @@ ExtensionManager.registerExtensions(store, extensions);
|
||||
|
||||
A small number of powerful extensions for popular use cases are maintained by
|
||||
OHIF. They're co-located in the
|
||||
[`OHIF/Viewers`](https://github.com/OHIF/Viewers/tree/react/) repository, in the
|
||||
top level [`extensions/`](https://github.com/OHIF/Viewers/tree/react/extensions)
|
||||
[`OHIF/Viewers`](https://github.com/OHIF/Viewers) repository, in the top level
|
||||
[`extensions/`](https://github.com/OHIF/Viewers/tree/master/extensions)
|
||||
directory.
|
||||
|
||||
{% include "./_maintained-extensions-table.md" %}
|
||||
@ -225,6 +225,6 @@ directory.
|
||||
-->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
[example-ext-src]: https://github.com/OHIF/Viewers/blob/master/extensions/_ohif-example-extension/src/index.js)
|
||||
[module-types]: https://github.com/OHIF/ohif-core/blob/43c08a29eff3fb646a0e83a03a236ddd84f4a6e8/src/plugins.js#L1-L6
|
||||
[example-ext-src]: https://github.com/OHIF/Viewers/tree/master/extensions/_example/src
|
||||
[module-types]: https://github.com/OHIF/Viewers/blob/master/platform/core/src/extensions/MODULE_TYPES.js
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
@ -53,7 +53,7 @@ Images can even be transcoded on the fly if this is desired.
|
||||
```bash
|
||||
cd OHIFViewer
|
||||
yarn install
|
||||
REACT_APP_CONFIG=config/google.js yarn run dev
|
||||
APP_CONFIG=config/google.js yarn run dev
|
||||
```
|
||||
|
||||
## Running via Docker
|
||||
|
||||
@ -71,11 +71,11 @@ how to configure the project for your own imaging archive below.
|
||||
#### How it Works
|
||||
|
||||
The configuration for our project is in the `/public/config` directory. Our
|
||||
build process knows which configuration file to use based on the
|
||||
`REACT_APP_CONFIG` environment variable. By default, its value is
|
||||
[`default.js`](https://github.com/OHIF/Viewers/blob/react/public/config/default.js).
|
||||
When we build, the `%REACT_APP_CONFIG%` value in
|
||||
our[`/public/index.html`](https://github.com/OHIF/Viewers/blob/react/public/index.html#L12-L15)
|
||||
build process knows which configuration file to use based on the `APP_CONFIG`
|
||||
environment variable. By default, its value is
|
||||
[`default.js`](https://github.com/OHIF/Viewers/blob/master/platform/viewer/public/config/default.js).
|
||||
When we build, the `%APP_CONFIG%` value in
|
||||
our[`/public/index.html`](https://github.com/OHIF/Viewers/blob/master/platform/viewer/public/index.html)
|
||||
file is substituted for the correct configuration file's name. This sets
|
||||
the`window.config` equal to our configuration file's value.
|
||||
|
||||
@ -104,17 +104,17 @@ window.config = {
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
You can also create a new config file and specify its path relative to the build
|
||||
output's root by setting the `REACT_APP_CONFIG` environment variable. You can
|
||||
set the value of this environment variable a few different ways:
|
||||
output's root by setting the `APP_CONFIG` environment variable. You can set the
|
||||
value of this environment variable a few different ways:
|
||||
|
||||
- [Add a temporary environment variable in your shell](https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#adding-temporary-environment-variables-in-your-shell)
|
||||
- [Add environment specific variables in `.env` file(s)](https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#adding-development-environment-variables-in-env)
|
||||
- Using the `cross-env` package in an npm script:
|
||||
- `"build": "cross-env REACT_APP_CONFIG=config/my-config.js react-scripts build"`
|
||||
- `"build": "cross-env APP_CONFIG=config/my-config.js react-scripts build"`
|
||||
|
||||
After updating the configuration, `yarn run build:web` to generate updated build
|
||||
output.
|
||||
|
||||
@ -11,7 +11,7 @@ control.
|
||||
Do not use this recipe to host sensitive medical data on the open web. Depending
|
||||
on your company's policies, this may be an appropriate setup on an internal
|
||||
network when protected with a server's basic authentication. For a more robust
|
||||
setup, check out our [user account control recpie](./user-account-control.md)
|
||||
setup, check out our [user account control recipe](./user-account-control.md)
|
||||
that builds on the lessons learned here.
|
||||
|
||||
## Overview
|
||||
@ -51,7 +51,7 @@ We can solve this one of two ways:
|
||||
|
||||
This solution uses the first approach, but you can see an example of the second
|
||||
in the `docker-compose` bundled with this project for local development:
|
||||
[HERE](#)
|
||||
[HERE](https://github.com/OHIF/Viewers/blob/master/platform/viewer/.recipes/Nginx-Orthanc/docker-compose.yml)
|
||||
|
||||
You can read more about CORS in this Medium article: [Understanding
|
||||
CORS][understanding-cors]
|
||||
@ -124,10 +124,10 @@ likely want to update:
|
||||
The OHIF Viewer's configuration is imported from a static `.js` file and made
|
||||
available globally at `window.config`. The configuration we use is set to a
|
||||
specific file when we build the viewer, and determined by the env variable:
|
||||
`REACT_APP_CONFIG`. You can see where we set its value in the `dockerfile` for
|
||||
this solution:
|
||||
`APP_CONFIG`. You can see where we set its value in the `dockerfile` for this
|
||||
solution:
|
||||
|
||||
`ENV REACT_APP_CONFIG=config/docker_openresty-orthanc.js`
|
||||
`ENV APP_CONFIG=config/docker_openresty-orthanc.js`
|
||||
|
||||
You can find the configuration we're using here:
|
||||
`/public/config/docker_openresty-orthanc.js`
|
||||
|
||||
@ -125,10 +125,10 @@ likely want to update:
|
||||
The OHIF Viewer's configuration is imported from a static `.js` file and made
|
||||
available globally at `window.config`. The configuration we use is set to a
|
||||
specific file when we build the viewer, and determined by the env variable:
|
||||
`REACT_APP_CONFIG`. You can see where we set its value in the `dockerfile` for
|
||||
this solution:
|
||||
`APP_CONFIG`. You can see where we set its value in the `dockerfile` for this
|
||||
solution:
|
||||
|
||||
`ENV REACT_APP_CONFIG=config/docker_openresty-orthanc-keycloak.js`
|
||||
`ENV APP_CONFIG=config/docker_openresty-orthanc-keycloak.js`
|
||||
|
||||
You can find the configuration we're using here:
|
||||
`/public/config/docker_openresty-orthanc-keycloak.js`
|
||||
@ -281,9 +281,9 @@ community members put together:
|
||||
[orthanc-docs]: http://book.orthanc-server.com/users/configuration.html#configuration
|
||||
[lua-resty-openidc-docs]: https://github.com/zmartzone/lua-resty-openidc
|
||||
<!-- SRC -->
|
||||
[config]: #
|
||||
[dockerfile]: #
|
||||
[config-nginx]: #
|
||||
[config-orthanc]: #
|
||||
[config-keycloak]: #
|
||||
[config]: https://github.com/OHIF/Viewers/blob/master/platform/viewer/src/config.js
|
||||
[dockerfile]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
|
||||
[config-nginx]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
|
||||
[config-orthanc]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
|
||||
[config-keycloak]: https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
@ -7,11 +7,11 @@
|
||||
## How it Works
|
||||
|
||||
The configuration for our project is in the `/public/config` directory. Our
|
||||
build process knows which configuration file to use based on the
|
||||
`REACT_APP_CONFIG` environment variable. By default, its value is
|
||||
[`default.js`](https://github.com/OHIF/Viewers/blob/react/public/config/default.js).
|
||||
When we build, the `%REACT_APP_CONFIG%` value in
|
||||
our[`/public/index.html`](https://github.com/OHIF/Viewers/blob/react/public/index.html#L12-L15)
|
||||
build process knows which configuration file to use based on the `APP_CONFIG`
|
||||
environment variable. By default, its value is
|
||||
[`default.js`](https://github.com/OHIF/Viewers/blob/master/platform/viewer/public/config/default.js).
|
||||
When we build, the `%APP_CONFIG%` value in
|
||||
our[`/public/index.html`](https://github.com/OHIF/Viewers/blob/master/platform/viewer/public/index.html)
|
||||
file is substituted for the correct configuration file's name. This sets the
|
||||
`window.config` equal to our configuration file's value.
|
||||
|
||||
@ -40,17 +40,17 @@ window.config = {
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
You can also create a new config file and specify its path relative to the build
|
||||
output's root by setting the `REACT_APP_CONFIG` environment variable. You can
|
||||
set the value of this environment variable a few different ways:
|
||||
output's root by setting the `APP_CONFIG` environment variable. You can set the
|
||||
value of this environment variable a few different ways:
|
||||
|
||||
- [Add a temporary environment variable in your shell](https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#adding-temporary-environment-variables-in-your-shell)
|
||||
- [Add environment specific variables in `.env` file(s)](https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#adding-development-environment-variables-in-env)
|
||||
- Using the `cross-env` package in an npm script:
|
||||
- `"build": "cross-env REACT_APP_CONFIG=config/my-config.js react-scripts build"`
|
||||
- `"build": "cross-env APP_CONFIG=config/my-config.js react-scripts build"`
|
||||
|
||||
After updating the configuration, `yarn run build:web` to generate updated build
|
||||
output.
|
||||
|
||||
@ -60,8 +60,8 @@ _Upload your first Study:_
|
||||
#### Orthanc: Learn More
|
||||
|
||||
You can see the `docker-compose.yml` file this command runs at
|
||||
[`<project-root>/docker/Nginx-Docker/`](#), and more on Orthanc for Docker in
|
||||
[Orthanc's documentation][orthanc-docker].
|
||||
[`<project-root>/platform/viewer/.recipes/Nginx-Orthanc/`](https://github.com/OHIF/Viewers/tree/master/platform/viewer/.recipes/Nginx-Orthanc),
|
||||
and more on Orthanc for Docker in [Orthanc's documentation][orthanc-docker].
|
||||
|
||||
### Connecting to Orthanc
|
||||
|
||||
@ -87,19 +87,18 @@ is running the `dev:orthanc` script in our project's `package.json`. That script
|
||||
is:
|
||||
|
||||
```js
|
||||
cross-env PORT=5000 REACT_APP_CONFIG=config/docker_nginx-orthanc.js react-scripts start
|
||||
cross-env PORT=5000 APP_CONFIG=config/docker_nginx-orthanc.js react-scripts start
|
||||
```
|
||||
|
||||
- `cross-env` sets two environment variables
|
||||
- PORT: 5000
|
||||
- REACT_APP_CONFIG: `config/docker_nginx-orthanc.js`
|
||||
- APP_CONFIG: `config/docker_nginx-orthanc.js`
|
||||
- `react-scripts` runs it's `start` script. This is [the de-facto
|
||||
way][cra-start] to run a "Create React App" in development mode.
|
||||
|
||||
The `REACT_APP_CONFIG` value tells our app which file to load on to
|
||||
`window.config`. By default, our app uses the file at
|
||||
`<project-root>/public/config/default.js`. Here is what that configuration looks
|
||||
like:
|
||||
The `APP_CONFIG` value tells our app which file to load on to `window.config`.
|
||||
By default, our app uses the file at `<project-root>/public/config/default.js`.
|
||||
Here is what that configuration looks like:
|
||||
|
||||
```js
|
||||
window.config = {
|
||||
|
||||
@ -37,8 +37,8 @@ Some tips for filing a new issue:
|
||||
At the moment we are in the process of defining our roadmap and will do our best
|
||||
to communicate this to the community. If your requested feature is on the
|
||||
roadmap, then it will most likely be built at some point. If it is not, you are
|
||||
welcome to build it yourself and [contribute it](../contributing.md). If you
|
||||
have resources and would like to fund the development of a feature, please
|
||||
welcome to build it yourself and [contribute it](contributing.md). If you have
|
||||
resources and would like to fund the development of a feature, please
|
||||
[contact us](http://www.ohif.org).
|
||||
|
||||
### Who should I contact about Academic Collaborations?
|
||||
|
||||
@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.50.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@0.50.2...@ohif/extension-vtk@0.50.3) (2019-08-22)
|
||||
|
||||
**Note:** Version bump only for package @ohif/extension-vtk
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.50.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@0.50.1...@ohif/extension-vtk@0.50.2) (2019-08-15)
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/extension-vtk",
|
||||
"version": "0.50.2",
|
||||
"version": "0.50.3",
|
||||
"description": "OHIF extension for VTK.js",
|
||||
"author": "OHIF",
|
||||
"license": "MIT",
|
||||
@ -52,7 +52,7 @@
|
||||
"vtk.js": "^9.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ohif/core": "^0.50.1",
|
||||
"@ohif/core": "^0.50.2",
|
||||
"@ohif/ui": "^0.50.1",
|
||||
"cornerstone-tools": "^3.13.0",
|
||||
"cornerstone-wado-image-loader": "^3.0.0",
|
||||
|
||||
@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.50.2](https://github.com/OHIF/Viewers/compare/@ohif/core@0.50.1...@ohif/core@0.50.2) (2019-08-22)
|
||||
|
||||
**Note:** Version bump only for package @ohif/core
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.50.1](https://github.com/OHIF/Viewers/compare/@ohif/core@0.50.0-alpha.10...@ohif/core@0.50.1) (2019-08-14)
|
||||
|
||||
**Note:** Version bump only for package @ohif/core
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/core",
|
||||
"version": "0.50.1",
|
||||
"version": "0.50.2",
|
||||
"description": "Generic business logic for web-based medical imaging applications",
|
||||
"author": "OHIF Core Team",
|
||||
"license": "MIT",
|
||||
|
||||
@ -18,8 +18,6 @@ import { StudyMetadataSource } from './StudyMetadataSource';
|
||||
import { StudyPrefetcher } from './StudyPrefetcher';
|
||||
import { TypeSafeCollection } from './TypeSafeCollection';
|
||||
|
||||
//import { StudySummary } from './metadata/StudySummary';
|
||||
|
||||
export {
|
||||
OHIFStudyMetadataSource,
|
||||
MetadataProvider,
|
||||
@ -27,7 +25,7 @@ export {
|
||||
HotkeysManager,
|
||||
ImageSet,
|
||||
StudyPrefetcher,
|
||||
//StudyLoadingListener,
|
||||
StudyLoadingListener,
|
||||
StackLoadingListener,
|
||||
DICOMFileLoadingListener,
|
||||
StudyMetadata,
|
||||
|
||||
@ -1,458 +0,0 @@
|
||||
var dialogPolyfill = (function() {
|
||||
var supportCustomEvent = window.CustomEvent;
|
||||
if (!supportCustomEvent || typeof supportCustomEvent == 'object') {
|
||||
supportCustomEvent = function CustomEvent(event, x) {
|
||||
x = x || {};
|
||||
var ev = document.createEvent('CustomEvent');
|
||||
ev.initCustomEvent(event, !!x.bubbles, !!x.cancelable, x.detail || null);
|
||||
return ev;
|
||||
};
|
||||
supportCustomEvent.prototype = window.Event.prototype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the nearest <dialog> from the passed element.
|
||||
*
|
||||
* @param {Element} el to search from
|
||||
* @param {HTMLDialogElement} dialog found
|
||||
*/
|
||||
function findNearestDialog(el) {
|
||||
while (el) {
|
||||
if (el.nodeName == 'DIALOG') {
|
||||
return el;
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
var dialogPolyfill = {};
|
||||
|
||||
dialogPolyfill.reposition = function(element) {
|
||||
var scrollTop =
|
||||
document.body.scrollTop || document.documentElement.scrollTop;
|
||||
var topValue = scrollTop + (window.innerHeight - element.offsetHeight) / 2;
|
||||
element.style.top = Math.max(0, topValue) + 'px';
|
||||
element.dialogPolyfillInfo.isTopOverridden = true;
|
||||
};
|
||||
|
||||
dialogPolyfill.inNodeList = function(nodeList, node) {
|
||||
for (var i = 0; i < nodeList.length; ++i) {
|
||||
if (nodeList[i] == node) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
dialogPolyfill.isInlinePositionSetByStylesheet = function(element) {
|
||||
for (var i = 0; i < document.styleSheets.length; ++i) {
|
||||
var styleSheet = document.styleSheets[i];
|
||||
var cssRules = null;
|
||||
// Some browsers throw on cssRules.
|
||||
try {
|
||||
cssRules = styleSheet.cssRules;
|
||||
} catch (e) {}
|
||||
if (!cssRules) continue;
|
||||
for (var j = 0; j < cssRules.length; ++j) {
|
||||
var rule = cssRules[j];
|
||||
var selectedNodes = null;
|
||||
// Ignore errors on invalid selector texts.
|
||||
try {
|
||||
selectedNodes = document.querySelectorAll(rule.selectorText);
|
||||
} catch (e) {}
|
||||
if (
|
||||
!selectedNodes ||
|
||||
!dialogPolyfill.inNodeList(selectedNodes, element)
|
||||
)
|
||||
continue;
|
||||
var cssTop = rule.style.getPropertyValue('top');
|
||||
var cssBottom = rule.style.getPropertyValue('bottom');
|
||||
if ((cssTop && cssTop != 'auto') || (cssBottom && cssBottom != 'auto'))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
dialogPolyfill.needsCentering = function(dialog) {
|
||||
var computedStyle = window.getComputedStyle(dialog);
|
||||
if (computedStyle.position != 'absolute') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We must determine whether the top/bottom specified value is non-auto. In
|
||||
// WebKit/Blink, checking computedStyle.top == 'auto' is sufficient, but
|
||||
// Firefox returns the used value. So we do this crazy thing instead: check
|
||||
// the inline style and then go through CSS rules.
|
||||
if (
|
||||
(dialog.style.top != 'auto' && dialog.style.top != '') ||
|
||||
(dialog.style.bottom != 'auto' && dialog.style.bottom != '')
|
||||
)
|
||||
return false;
|
||||
return !dialogPolyfill.isInlinePositionSetByStylesheet(dialog);
|
||||
};
|
||||
|
||||
dialogPolyfill.showDialog = function(isModal) {
|
||||
if (this.open) {
|
||||
throw 'InvalidStateError: showDialog called on open dialog';
|
||||
}
|
||||
this.open = true; // TODO: should be a getter mapped to attribute
|
||||
this.setAttribute('open', 'open');
|
||||
|
||||
if (isModal) {
|
||||
// Find element with `autofocus` attribute or first form control
|
||||
var first_form_ctrl = null;
|
||||
var autofocus = null;
|
||||
var findElementToFocus = function(root) {
|
||||
if (!root.children) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < root.children.length; i++) {
|
||||
var elem = root.children[i];
|
||||
if (
|
||||
first_form_ctrl === null &&
|
||||
!elem.disabled &&
|
||||
(elem.nodeName == 'BUTTON' ||
|
||||
elem.nodeName == 'INPUT' ||
|
||||
elem.nodeName == 'KEYGEN' ||
|
||||
elem.nodeName == 'SELECT' ||
|
||||
elem.nodeName == 'TEXTAREA')
|
||||
) {
|
||||
first_form_ctrl = elem;
|
||||
}
|
||||
if (elem.autofocus) {
|
||||
autofocus = elem;
|
||||
return;
|
||||
}
|
||||
findElementToFocus(elem);
|
||||
if (autofocus !== null) return;
|
||||
}
|
||||
};
|
||||
|
||||
findElementToFocus(this);
|
||||
|
||||
if (autofocus !== null) {
|
||||
autofocus.focus();
|
||||
} else if (first_form_ctrl !== null) {
|
||||
first_form_ctrl.focus();
|
||||
}
|
||||
}
|
||||
|
||||
if (dialogPolyfill.needsCentering(this)) dialogPolyfill.reposition(this);
|
||||
if (isModal) {
|
||||
this.dialogPolyfillInfo.modal = true;
|
||||
dialogPolyfill.dm.pushDialog(this);
|
||||
}
|
||||
|
||||
// IE sometimes complains when calling .focus() that it
|
||||
// "Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus."
|
||||
try {
|
||||
if (autofocus !== null) {
|
||||
autofocus.focus();
|
||||
} else if (first_form_ctrl !== null) {
|
||||
first_form_ctrl.focus();
|
||||
}
|
||||
} catch (e) {}
|
||||
this.style.zoom = 1;
|
||||
};
|
||||
|
||||
dialogPolyfill.close = function(retval) {
|
||||
if (!this.open && !window.HTMLDialogElement) {
|
||||
// Native implementations will set .open to false, so ignore this error.
|
||||
throw 'InvalidStateError: close called on closed dialog';
|
||||
}
|
||||
this.open = false;
|
||||
this.removeAttribute('open');
|
||||
|
||||
// Leave returnValue untouched in case it was set directly on the element
|
||||
if (typeof retval != 'undefined') {
|
||||
this.returnValue = retval;
|
||||
}
|
||||
|
||||
// This won't match the native <dialog> exactly because if the user sets top
|
||||
// on a centered polyfill dialog, that top gets thrown away when the dialog is
|
||||
// closed. Not sure it's possible to polyfill this perfectly.
|
||||
if (this.dialogPolyfillInfo.isTopOverridden) {
|
||||
this.style.top = 'auto';
|
||||
}
|
||||
|
||||
if (this.dialogPolyfillInfo.modal) {
|
||||
dialogPolyfill.dm.removeDialog(this);
|
||||
}
|
||||
|
||||
// Triggering "close" event for any attached listeners on the <dialog>
|
||||
var event;
|
||||
if (document.createEvent) {
|
||||
event = document.createEvent('HTMLEvents');
|
||||
event.initEvent('close', true, true);
|
||||
} else {
|
||||
event = new Event('close');
|
||||
}
|
||||
this.dispatchEvent(event);
|
||||
|
||||
return this.returnValue;
|
||||
};
|
||||
|
||||
dialogPolyfill.registerDialog = function(element) {
|
||||
if (element.show) {
|
||||
// console.warn("This browser already supports <dialog>, the polyfill " +
|
||||
// "may not work correctly.");
|
||||
}
|
||||
element.show = dialogPolyfill.showDialog.bind(element, false);
|
||||
element.showModal = dialogPolyfill.showDialog.bind(element, true);
|
||||
element.close = dialogPolyfill.close.bind(element);
|
||||
element.dialogPolyfillInfo = {};
|
||||
element.open = false;
|
||||
};
|
||||
|
||||
// The overlay is used to simulate how a modal dialog blocks the document. The
|
||||
// blocking dialog is positioned on top of the overlay, and the rest of the
|
||||
// dialogs on the pending dialog stack are positioned below it. In the actual
|
||||
// implementation, the modal dialog stacking is controlled by the top layer,
|
||||
// where z-index has no effect.
|
||||
var TOP_LAYER_ZINDEX = 100000;
|
||||
var MAX_PENDING_DIALOGS = 100000;
|
||||
|
||||
dialogPolyfill.DialogManager = function() {
|
||||
this.pendingDialogStack = [];
|
||||
this.overlay = document.createElement('div');
|
||||
this.overlay.style.width = '100%';
|
||||
this.overlay.style.height = '100%';
|
||||
this.overlay.style.position = 'fixed';
|
||||
this.overlay.style.left = '0px';
|
||||
this.overlay.style.top = '0px';
|
||||
this.overlay.style.backgroundColor = 'rgba(0,0,0,0.0)';
|
||||
|
||||
this.focusPageLast = this.createFocusable();
|
||||
this.overlay.appendChild(this.focusPageLast);
|
||||
|
||||
this.overlay.addEventListener('click', function(e) {
|
||||
var redirectedEvent = document.createEvent('MouseEvents');
|
||||
redirectedEvent.initMouseEvent(
|
||||
e.type,
|
||||
e.bubbles,
|
||||
e.cancelable,
|
||||
window,
|
||||
e.detail,
|
||||
e.screenX,
|
||||
e.screenY,
|
||||
e.clientX,
|
||||
e.clientY,
|
||||
e.ctrlKey,
|
||||
e.altKey,
|
||||
e.shiftKey,
|
||||
e.metaKey,
|
||||
e.button,
|
||||
e.relatedTarget
|
||||
);
|
||||
document.body.dispatchEvent(redirectedEvent);
|
||||
});
|
||||
|
||||
// TODO: Only install when any dialogs are open.
|
||||
document.addEventListener(
|
||||
'submit',
|
||||
function(ev) {
|
||||
var method = ev.target.getAttribute('method');
|
||||
method = method ? method.toLowerCase() : '';
|
||||
if (method != 'dialog') {
|
||||
return;
|
||||
}
|
||||
ev.preventDefault();
|
||||
|
||||
var dialog = findNearestDialog(ev.target);
|
||||
if (!dialog) {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: The original event doesn't contain the INPUT element used to
|
||||
// submit the form (if any). Look in some possible places.
|
||||
var returnValue;
|
||||
var cands = [document.activeElement, ev.explicitOriginalTarget];
|
||||
cands.some(function(cand) {
|
||||
if (cand && cand.nodeName == 'INPUT' && cand.form == ev.target) {
|
||||
returnValue = cand.value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
dialog.close(returnValue);
|
||||
},
|
||||
true
|
||||
);
|
||||
};
|
||||
|
||||
dialogPolyfill.DialogManager.prototype.createFocusable = function(tabIndex) {
|
||||
var span = document.createElement('span');
|
||||
span.tabIndex = tabIndex || 0;
|
||||
span.style.opacity = 0;
|
||||
span.style.position = 'static';
|
||||
return span;
|
||||
};
|
||||
|
||||
dialogPolyfill.DialogManager.prototype.blockDocument = function() {
|
||||
if (!document.body.contains(this.overlay)) {
|
||||
document.body.appendChild(this.overlay);
|
||||
|
||||
// On Safari/Mac (and possibly other browsers), the documentElement is
|
||||
// not focusable. This is required for modal dialogs as it is the first
|
||||
// element to be hit by a tab event, and further tabs are redirected to
|
||||
// the most visible dialog.
|
||||
if (this.needsDocumentElementFocus === undefined) {
|
||||
document.documentElement.focus();
|
||||
this.needsDocumentElementFocus =
|
||||
document.activeElement != document.documentElement;
|
||||
}
|
||||
if (this.needsDocumentElementFocus) {
|
||||
document.documentElement.tabIndex = 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dialogPolyfill.DialogManager.prototype.unblockDocument = function() {
|
||||
document.body.removeChild(this.overlay);
|
||||
if (this.needsDocumentElementFocus) {
|
||||
// TODO: Restore the previous tabIndex, rather than clearing it.
|
||||
document.documentElement.tabIndex = '';
|
||||
}
|
||||
};
|
||||
|
||||
dialogPolyfill.DialogManager.prototype.updateStacking = function() {
|
||||
if (this.pendingDialogStack.length == 0) {
|
||||
this.unblockDocument();
|
||||
return;
|
||||
}
|
||||
this.blockDocument();
|
||||
|
||||
var zIndex = TOP_LAYER_ZINDEX;
|
||||
for (var i = 0; i < this.pendingDialogStack.length; i++) {
|
||||
if (i == this.pendingDialogStack.length - 1)
|
||||
this.overlay.style.zIndex = zIndex++;
|
||||
var dialog = this.pendingDialogStack[i];
|
||||
dialog.dialogPolyfillInfo.backdrop.style.zIndex = zIndex++;
|
||||
dialog.style.zIndex = zIndex++;
|
||||
}
|
||||
};
|
||||
|
||||
dialogPolyfill.DialogManager.prototype.handleKey = function(event) {
|
||||
var dialogCount = this.pendingDialogStack.length;
|
||||
if (dialogCount == 0) {
|
||||
return;
|
||||
}
|
||||
var dialog = this.pendingDialogStack[dialogCount - 1];
|
||||
var pfi = dialog.dialogPolyfillInfo;
|
||||
|
||||
switch (event.keyCode) {
|
||||
case 9 /* tab */:
|
||||
var activeElement = document.activeElement;
|
||||
var forward = !event.shiftKey;
|
||||
if (forward) {
|
||||
// Tab forward, so look for document or fake last focus element.
|
||||
if (
|
||||
activeElement == document.documentElement ||
|
||||
activeElement == document.body ||
|
||||
activeElement == pfi.backdrop
|
||||
) {
|
||||
pfi.focusFirst.focus();
|
||||
} else if (activeElement == pfi.focusLast) {
|
||||
// TODO: Instead of wrapping to focusFirst, escape to browser chrome.
|
||||
pfi.focusFirst.focus();
|
||||
}
|
||||
} else {
|
||||
// Tab backwards, so look for fake first focus element.
|
||||
if (activeElement == pfi.focusFirst) {
|
||||
// TODO: Instead of wrapping to focusLast, escape to browser chrome.
|
||||
pfi.focusLast.focus();
|
||||
} else if (activeElement == this.focusPageLast) {
|
||||
// The focus element is at the end of the page (e.g., shift-tab from
|
||||
// the window chrome): move current focus to the last element in the
|
||||
// dialog instead.
|
||||
pfi.focusLast.focus();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 27 /* esc */:
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var cancelEvent = new supportCustomEvent('cancel', {
|
||||
bubbles: false,
|
||||
cancelable: true,
|
||||
});
|
||||
if (dialog.dispatchEvent(cancelEvent)) {
|
||||
dialog.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
dialogPolyfill.DialogManager.prototype.pushDialog = function(dialog) {
|
||||
if (this.pendingDialogStack.length >= MAX_PENDING_DIALOGS) {
|
||||
throw 'Too many modal dialogs';
|
||||
}
|
||||
|
||||
var backdrop = document.createElement('div');
|
||||
backdrop.className = 'backdrop';
|
||||
var clickEventListener = function(e) {
|
||||
var redirectedEvent = document.createEvent('MouseEvents');
|
||||
redirectedEvent.initMouseEvent(
|
||||
e.type,
|
||||
e.bubbles,
|
||||
e.cancelable,
|
||||
window,
|
||||
e.detail,
|
||||
e.screenX,
|
||||
e.screenY,
|
||||
e.clientX,
|
||||
e.clientY,
|
||||
e.ctrlKey,
|
||||
e.altKey,
|
||||
e.shiftKey,
|
||||
e.metaKey,
|
||||
e.button,
|
||||
e.relatedTarget
|
||||
);
|
||||
dialog.dispatchEvent(redirectedEvent);
|
||||
};
|
||||
backdrop.addEventListener('click', clickEventListener);
|
||||
dialog.parentNode.insertBefore(backdrop, dialog.nextSibling);
|
||||
dialog.dialogPolyfillInfo.backdrop = backdrop;
|
||||
dialog.dialogPolyfillInfo.clickEventListener = clickEventListener;
|
||||
this.pendingDialogStack.push(dialog);
|
||||
this.updateStacking();
|
||||
|
||||
dialog.dialogPolyfillInfo.focusFirst = this.createFocusable();
|
||||
dialog.dialogPolyfillInfo.focusLast = this.createFocusable();
|
||||
dialog.appendChild(dialog.dialogPolyfillInfo.focusLast);
|
||||
dialog.insertBefore(
|
||||
dialog.dialogPolyfillInfo.focusFirst,
|
||||
dialog.firstChild
|
||||
);
|
||||
};
|
||||
|
||||
dialogPolyfill.DialogManager.prototype.removeDialog = function(dialog) {
|
||||
var index = this.pendingDialogStack.indexOf(dialog);
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
this.pendingDialogStack.splice(index, 1);
|
||||
var backdrop = dialog.dialogPolyfillInfo.backdrop;
|
||||
var clickEventListener = dialog.dialogPolyfillInfo.clickEventListener;
|
||||
backdrop.removeEventListener('click', clickEventListener);
|
||||
backdrop.parentNode.removeChild(backdrop);
|
||||
dialog.dialogPolyfillInfo.backdrop = null;
|
||||
dialog.dialogPolyfillInfo.clickEventListener = null;
|
||||
this.updateStacking();
|
||||
|
||||
dialog.removeChild(dialog.dialogPolyfillInfo.focusFirst);
|
||||
dialog.removeChild(dialog.dialogPolyfillInfo.focusLast);
|
||||
dialog.dialogPolyfillInfo.focusFirst = null;
|
||||
dialog.dialogPolyfillInfo.focusLast = null;
|
||||
};
|
||||
|
||||
dialogPolyfill.dm = new dialogPolyfill.DialogManager();
|
||||
|
||||
document.addEventListener(
|
||||
'keydown',
|
||||
dialogPolyfill.dm.handleKey.bind(dialogPolyfill.dm)
|
||||
);
|
||||
|
||||
return dialogPolyfill;
|
||||
})();
|
||||
@ -1,34 +0,0 @@
|
||||
dialog
|
||||
position: absolute
|
||||
left: 0
|
||||
right: 0
|
||||
width: -moz-fit-content
|
||||
width: -webkit-fit-content
|
||||
width: fit-content
|
||||
height: -moz-fit-content
|
||||
height: -webkit-fit-content
|
||||
height: fit-content
|
||||
margin: auto
|
||||
border: solid
|
||||
padding: 1em
|
||||
background: white
|
||||
color: black
|
||||
display: none
|
||||
|
||||
dialog[open]
|
||||
display: block
|
||||
|
||||
dialog + .backdrop
|
||||
position: fixed
|
||||
top: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
left: 0
|
||||
background: rgba(0,0,0,0.1)
|
||||
|
||||
/* for small devices, modal dialogs go full-screen */
|
||||
@media screen and (max-width: 540px)
|
||||
dialog[_polyfill_modal]
|
||||
top: 0
|
||||
width: auto
|
||||
margin: 1em
|
||||
@ -1 +0,0 @@
|
||||
import './styleProperty.js';
|
||||
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* https://github.com/swederik/dragula/blob/ccc15d75186f5168e7abadbe3077cf12dab09f8b/styleProperty.js
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
const browserProps = {};
|
||||
|
||||
function eachVendor(prop, fn) {
|
||||
const prefixes = ['Webkit', 'Moz', 'ms', 'O'];
|
||||
fn(prop);
|
||||
for (let i = 0; i < prefixes.length; i++) {
|
||||
fn(prefixes[i] + prop.charAt(0).toUpperCase() + prop.slice(1));
|
||||
}
|
||||
}
|
||||
|
||||
function check(property, testValue) {
|
||||
const sandbox = document.createElement('iframe');
|
||||
const element = document.createElement('p');
|
||||
|
||||
document.body.appendChild(sandbox);
|
||||
sandbox.contentDocument.body.appendChild(element);
|
||||
const support = set(element, property, testValue);
|
||||
|
||||
// We have to do this because remove() is not supported by IE11 and below
|
||||
sandbox.parentElement.removeChild(sandbox);
|
||||
return support;
|
||||
}
|
||||
|
||||
function checkComputed(el, prop) {
|
||||
const computed = window.getComputedStyle(el).getPropertyValue(prop);
|
||||
return computed !== void 0 && computed.length > 0 && computed !== 'none';
|
||||
}
|
||||
|
||||
function set(el, prop, value) {
|
||||
let match = false;
|
||||
|
||||
if (browserProps[prop] === void 0) {
|
||||
eachVendor(prop, function(vendorProp) {
|
||||
if (el.style[vendorProp] !== void 0 && match === false) {
|
||||
el.style[vendorProp] = value;
|
||||
if (checkComputed(el, vendorProp)) {
|
||||
match = true;
|
||||
browserProps[prop] = vendorProp;
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
el.style[browserProps[prop]] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
const styleProperty = {
|
||||
check,
|
||||
set,
|
||||
};
|
||||
|
||||
OHIF.ui.styleProperty = styleProperty;
|
||||
})();
|
||||
|
||||
const { styleProperty } = OHIF.ui;
|
||||
|
||||
export { styleProperty };
|
||||
@ -1,150 +0,0 @@
|
||||
/*!
|
||||
* transition-to-from-auto 0.5.2
|
||||
* https://github.com/75lb/transition-to-from-auto
|
||||
* Copyright 2015 Lloyd Brookes <75pound@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
@module
|
||||
@alias transition
|
||||
*/
|
||||
(function(window, document) {
|
||||
'use strict';
|
||||
|
||||
var getComputedStyle = window.getComputedStyle;
|
||||
var isTransition = 'data-ttfaInTransition';
|
||||
|
||||
var elements = [];
|
||||
var data = [];
|
||||
|
||||
// Transition detecting
|
||||
var transitionProp = false;
|
||||
var transitionEnd = false;
|
||||
var testStyle = document.createElement('a').style;
|
||||
var testProp;
|
||||
|
||||
if (testStyle[(testProp = 'webkitTransition')] !== undefined) {
|
||||
transitionProp = testProp;
|
||||
transitionEnd = testProp + 'End';
|
||||
}
|
||||
|
||||
if (testStyle[(testProp = 'transition')] !== undefined) {
|
||||
transitionProp = testProp;
|
||||
transitionEnd = testProp + 'end';
|
||||
}
|
||||
|
||||
function process(options, data) {
|
||||
var el = options.element;
|
||||
var val = options.val;
|
||||
var prop = options.prop;
|
||||
var style = el.style;
|
||||
var startVal;
|
||||
var autoVal;
|
||||
|
||||
if (!transitionProp) {
|
||||
return (style[prop] = val);
|
||||
}
|
||||
|
||||
if (el.hasAttribute(isTransition)) {
|
||||
el.removeEventListener(transitionEnd, data.l);
|
||||
} else {
|
||||
style[transitionProp] = 'none';
|
||||
|
||||
startVal = getComputedStyle(el)[prop];
|
||||
style[prop] = 'auto';
|
||||
autoVal = getComputedStyle(el)[prop];
|
||||
|
||||
// Interrupt
|
||||
if (startVal === val || (val === 'auto' && startVal === autoVal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.auto = autoVal;
|
||||
el.setAttribute(isTransition, 1);
|
||||
|
||||
// Transition
|
||||
style[prop] = startVal;
|
||||
el.offsetWidth;
|
||||
style[transitionProp] = options.style;
|
||||
}
|
||||
|
||||
style[prop] = val === 'auto' ? data.auto : val;
|
||||
|
||||
data.l = function(e) {
|
||||
if (e.propertyName === prop) {
|
||||
el.removeAttribute(isTransition);
|
||||
el.removeEventListener(transitionEnd, data.l);
|
||||
if (val === 'auto') {
|
||||
/* avoid transition flashes in Safari */
|
||||
style[transitionProp] = 'none';
|
||||
style[prop] = val;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
el.addEventListener(transitionEnd, data.l);
|
||||
}
|
||||
|
||||
/**
|
||||
@param options {Object}
|
||||
@param options.element {string | element} - The DOM element or selector to transition
|
||||
@param options.val {string} - The value you want to transition to
|
||||
@param [options.prop] {string} - The CSS property to transition, defaults to `"height"`
|
||||
@param [options.style] {string} - The desired value for the `transition` CSS property (e.g. `"height 1s"`). If specified, this value is added inline and will override your CSS. Leave this value blank if you already have it defined in your stylesheet.
|
||||
@alias module:transition-to-from-auto
|
||||
*/
|
||||
function transition(options) {
|
||||
var element = options.element;
|
||||
var datum;
|
||||
var index;
|
||||
|
||||
if (typeof element === 'string') {
|
||||
element = document.querySelector(element);
|
||||
}
|
||||
|
||||
element = options.element = element instanceof Node ? element : false;
|
||||
options.prop = options.prop || 'height';
|
||||
options.style = options.style || '';
|
||||
|
||||
if (element) {
|
||||
index = elements.indexOf(element);
|
||||
if (~index) {
|
||||
datum = data[index];
|
||||
} else {
|
||||
datum = {};
|
||||
elements.push(element);
|
||||
data.push(datum);
|
||||
}
|
||||
|
||||
process(options, datum);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The name of the vendor-specific transition CSS property
|
||||
@type {string}
|
||||
@example
|
||||
el.style[transition.prop + 'Duration'] = '1s';
|
||||
*/
|
||||
transition.prop = transitionProp;
|
||||
|
||||
/**
|
||||
* The name of the [transition end event](https://developer.mozilla.org/en-US/docs/Web/Events/transitionend) in the current browser (typically `"transitionend"` or `"webkitTransitionEnd"`)
|
||||
* @type {string}
|
||||
* @example
|
||||
* el.addEventListener(transition.end, function(){
|
||||
* // the transition ended..
|
||||
* });
|
||||
*/
|
||||
transition.end = transitionEnd;
|
||||
|
||||
if (typeof module === 'object' && module.exports) {
|
||||
module.exports = transition;
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
define(function() {
|
||||
return transition;
|
||||
});
|
||||
} else {
|
||||
window.transition = transition;
|
||||
}
|
||||
})(window, document);
|
||||
@ -13,7 +13,6 @@ import metadata from './classes/metadata/';
|
||||
import object from './object.js';
|
||||
import redux from './redux/';
|
||||
import string from './string.js';
|
||||
//import './schema.js';
|
||||
import studies from './studies/';
|
||||
import ui from './ui';
|
||||
import user from './user.js';
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
//import SimpleSchema from 'simpl-schema'
|
||||
|
||||
/*
|
||||
Extend the available options on schema definitions:
|
||||
|
||||
* valuesLabels: Used in conjunction with allowedValues to define the text
|
||||
label for each value (used on forms)
|
||||
|
||||
* textOptional: Used to allow empty strings
|
||||
|
||||
*/
|
||||
/*SimpleSchema.extendOptions({
|
||||
valuesLabels: Match.Optional([String]),
|
||||
textOptional: Match.Optional(Boolean)
|
||||
});
|
||||
|
||||
// Add default required validation for empty strings which can be bypassed
|
||||
// using textOptional=true definition
|
||||
SimpleSchema.addValidator(function() {
|
||||
if (
|
||||
this.definition.optional !== true &&
|
||||
this.definition.textOptional !== true &&
|
||||
this.value === ''
|
||||
) {
|
||||
return 'required';
|
||||
}
|
||||
});*/
|
||||
|
||||
// Including [label] for some messages
|
||||
/*SimpleSchema.messages({
|
||||
maxCount: '[label] can not have more than [maxCount] values',
|
||||
minCount: '[label] must have at least [minCount] values',
|
||||
notAllowed: '[label] has an invalid value: "[value]"'
|
||||
});*/
|
||||
@ -1,320 +0,0 @@
|
||||
/*import SimpleSchema from 'simpl-schema';
|
||||
|
||||
const serverNameDefinitions = {
|
||||
type: String,
|
||||
label: 'Server Name',
|
||||
max: 100
|
||||
};
|
||||
|
||||
const serverTypeDefinitions = {
|
||||
type: String,
|
||||
label: 'Server Type',
|
||||
allowedValues: ['dicomWeb', 'dimse'],
|
||||
valuesLabels: ['DICOM Web', 'DIMSE'],
|
||||
optional: true
|
||||
};
|
||||
|
||||
const wadoUriRootDefinitions = {
|
||||
type: String,
|
||||
label: 'WADO URI root',
|
||||
max: 1000
|
||||
};
|
||||
|
||||
const availableMouseButtonTools = ['wwwc', 'zoom', 'pan', 'stackScroll'];
|
||||
|
||||
export const DICOMWebRequestOptions = new SimpleSchema({
|
||||
auth: {
|
||||
type: String,
|
||||
label: 'Authentication',
|
||||
defaultValue: 'orthanc:orthanc',
|
||||
optional: true
|
||||
},
|
||||
requestFromBrowser: {
|
||||
type: Boolean,
|
||||
label: 'Make DICOMWeb requests from the Browser',
|
||||
defaultValue: false,
|
||||
optional: true
|
||||
},
|
||||
logRequests: {
|
||||
type: Boolean,
|
||||
defaultValue: true,
|
||||
label: 'Requests'
|
||||
},
|
||||
logResponses: {
|
||||
type: Boolean,
|
||||
defaultValue: false,
|
||||
label: 'Responses'
|
||||
},
|
||||
logTiming: {
|
||||
type: Boolean,
|
||||
defaultValue: true,
|
||||
label: 'Timing'
|
||||
}
|
||||
});
|
||||
|
||||
export const DICOMWebServer = new SimpleSchema({
|
||||
name: serverNameDefinitions,
|
||||
type: serverTypeDefinitions,
|
||||
wadoUriRoot: wadoUriRootDefinitions,
|
||||
wadoRoot: {
|
||||
type: String,
|
||||
label: 'WADO root',
|
||||
max: 1000
|
||||
},
|
||||
imageRendering: {
|
||||
type: String,
|
||||
label: 'Image rendering',
|
||||
allowedValues: ['wadouri', 'wadors'],
|
||||
valuesLabels: ['WADO URI', 'WADO RS'],
|
||||
defaultValue: 'wadouri'
|
||||
},
|
||||
thumbnailRendering: {
|
||||
type: String,
|
||||
label: 'Thumbnail rendering',
|
||||
allowedValues: ['wadouri', 'wadors'],
|
||||
valuesLabels: ['WADO URI', 'WADO RS'],
|
||||
defaultValue: 'wadouri'
|
||||
},
|
||||
qidoRoot: {
|
||||
type: String,
|
||||
label: 'QIDO root',
|
||||
max: 1000
|
||||
},
|
||||
qidoSupportsIncludeField: {
|
||||
type: Boolean,
|
||||
label: 'QIDO supports "includefield" query key',
|
||||
defaultValue: false
|
||||
},
|
||||
requestOptions: {
|
||||
type: DICOMWebRequestOptions,
|
||||
label: 'Request Options'
|
||||
}
|
||||
});
|
||||
|
||||
export const DIMSEPeer = new SimpleSchema({
|
||||
aeTitle: {
|
||||
type: String,
|
||||
label: 'AE Title'
|
||||
},
|
||||
hostAE: {
|
||||
type: String,
|
||||
label: 'AE Host',
|
||||
optional: true
|
||||
},
|
||||
host: {
|
||||
type: String,
|
||||
label: 'Host Domain/IP',
|
||||
regEx: SimpleSchema.RegEx.WeakDomain
|
||||
},
|
||||
port: {
|
||||
type: Number,
|
||||
label: 'Port',
|
||||
min: 1,
|
||||
defaultValue: 11112,
|
||||
max: 65535
|
||||
},
|
||||
default: {
|
||||
type: Boolean,
|
||||
label: 'Default',
|
||||
defaultValue: false
|
||||
},
|
||||
server: {
|
||||
type: Boolean,
|
||||
label: 'Server',
|
||||
defaultValue: false
|
||||
},
|
||||
supportsInstanceRetrievalByStudyUid: {
|
||||
type: Boolean,
|
||||
label: 'Supports instance retrieval by StudyUid',
|
||||
defaultValue: true
|
||||
}
|
||||
});
|
||||
|
||||
export const DIMSEServer = new SimpleSchema({
|
||||
name: serverNameDefinitions,
|
||||
type: serverTypeDefinitions,
|
||||
wadoUriRoot: wadoUriRootDefinitions,
|
||||
requestOptions: {
|
||||
type: DICOMWebRequestOptions,
|
||||
label: 'Request Options'
|
||||
},
|
||||
peers: {
|
||||
type: [DIMSEPeer],
|
||||
label: 'Peer List',
|
||||
minCount: 1
|
||||
}
|
||||
});
|
||||
|
||||
export const UISettings = new SimpleSchema({
|
||||
studyListFunctionsEnabled: {
|
||||
type: Boolean,
|
||||
label: 'Study List Functions Enabled?',
|
||||
defaultValue: true
|
||||
},
|
||||
leftSidebarOpen: {
|
||||
type: Boolean,
|
||||
label: 'Left sidebar open by default?',
|
||||
defaultValue: false
|
||||
},
|
||||
leftSidebarDragAndDrop: {
|
||||
type: Boolean,
|
||||
label:
|
||||
'Left sidebar allows thumbnail drag and drop. If false, images will be loaded on single click.',
|
||||
defaultValue: true
|
||||
},
|
||||
displaySetNavigationLoopOverSeries: {
|
||||
type: Boolean,
|
||||
label:
|
||||
'The UP/DOWN display set navigation buttons will start over when reach the last display set in viewport?',
|
||||
defaultValue: true
|
||||
},
|
||||
displaySetNavigationMultipleViewports: {
|
||||
type: Boolean,
|
||||
label:
|
||||
'The UP/DOWN display set navigation buttons will iterate over all the viewports at once?',
|
||||
defaultValue: false
|
||||
},
|
||||
displayEchoUltrasoundWorkflow: {
|
||||
type: Boolean,
|
||||
label: 'Enable cine dialog enhancements for multiframe images.',
|
||||
defaultValue: false
|
||||
},
|
||||
autoPositionMeasurementsTextCallOuts: {
|
||||
type: String,
|
||||
label: 'Auto position text call-outs for measurements when creating them.',
|
||||
defaultValue: 'TRBL'
|
||||
},
|
||||
studyListDateFilterNumDays: {
|
||||
type: Number,
|
||||
label: 'Number of days to be used on Study List date filter',
|
||||
min: 1
|
||||
},
|
||||
showStackLoadingProgressBar: {
|
||||
type: Boolean,
|
||||
label:
|
||||
'Show a progress bar closest to the thumbnail showing how much the stack has loaded',
|
||||
defaultValue: true
|
||||
},
|
||||
cornerstoneRenderer: {
|
||||
type: String,
|
||||
label: 'Cornerstone default image renderer',
|
||||
defaultValue: 'webgl'
|
||||
},
|
||||
sortSeriesByIncomingOrder: {
|
||||
type: Boolean,
|
||||
label:
|
||||
"Define if the series' images shall be sorted by incoming order. Sort by Instance Number by default.",
|
||||
defaultValue: false
|
||||
},
|
||||
useMiddleSeriesInstanceAsThumbnail: {
|
||||
type: Boolean,
|
||||
label:
|
||||
'Define if the middle instance of a series will be used as thumbnail. If not, the first instance will be used.',
|
||||
defaultValue: true
|
||||
}
|
||||
});
|
||||
|
||||
export const PrefetchSchema = new SimpleSchema({
|
||||
order: {
|
||||
type: String,
|
||||
label: 'Prefetch Order',
|
||||
allowedValues: ['topdown', 'downward', 'closest'],
|
||||
optional: false
|
||||
},
|
||||
displaySetCount: {
|
||||
type: Number,
|
||||
label: 'Display Set Count',
|
||||
min: 1,
|
||||
defaultValue: 1
|
||||
}
|
||||
});
|
||||
|
||||
export const MouseButtonToolSchema = new SimpleSchema({
|
||||
left: {
|
||||
type: String,
|
||||
label: 'Left Mouse Button',
|
||||
allowedValues: availableMouseButtonTools,
|
||||
optional: true
|
||||
},
|
||||
right: {
|
||||
type: String,
|
||||
label: 'Right Mouse Button',
|
||||
allowedValues: availableMouseButtonTools,
|
||||
optional: true
|
||||
},
|
||||
middle: {
|
||||
type: String,
|
||||
label: 'Middle Mouse Button',
|
||||
allowedValues: availableMouseButtonTools,
|
||||
optional: true
|
||||
}
|
||||
});
|
||||
|
||||
export const PublicServerConfig = new SimpleSchema({
|
||||
verifyEmail: {
|
||||
type: Boolean,
|
||||
label: 'Verify Email',
|
||||
defaultValue: false
|
||||
},
|
||||
demoUserEnabled: {
|
||||
type: Boolean,
|
||||
label: 'Creates demo user on startup and show TestDrive button',
|
||||
defaultValue: true
|
||||
},
|
||||
userAuthenticationRoutesEnabled: {
|
||||
type: Boolean,
|
||||
label: 'Enables routing to /login page.',
|
||||
defaultValue: false
|
||||
},
|
||||
ui: {
|
||||
type: UISettings,
|
||||
label: 'UI Settings'
|
||||
},
|
||||
prefetch: {
|
||||
type: PrefetchSchema,
|
||||
label: 'Prefetch settings'
|
||||
},
|
||||
defaultMouseButtonTools: {
|
||||
type: MouseButtonToolSchema,
|
||||
label: 'Default Mouse Button Tools'
|
||||
}
|
||||
});
|
||||
|
||||
export const Servers = new SimpleSchema({
|
||||
dicomWeb: {
|
||||
type: [DICOMWebServer],
|
||||
label: 'DICOMWeb Servers',
|
||||
optional: true
|
||||
},
|
||||
dimse: {
|
||||
type: [DIMSEServer],
|
||||
label: 'DIMSE Servers',
|
||||
optional: true
|
||||
}
|
||||
});
|
||||
|
||||
export const ServerConfiguration = new SimpleSchema({
|
||||
servers: {
|
||||
type: Servers,
|
||||
label: 'Servers'
|
||||
},
|
||||
defaultServiceType: {
|
||||
type: String,
|
||||
label: 'Default Service Type',
|
||||
defaultValue: 'dicomWeb'
|
||||
},
|
||||
dropCollections: {
|
||||
type: Boolean,
|
||||
label: 'Drop database collections',
|
||||
defaultValue: false
|
||||
},
|
||||
public: {
|
||||
type: PublicServerConfig,
|
||||
label: 'Public Server Configuration'
|
||||
},
|
||||
origin: {
|
||||
type: String,
|
||||
label: 'Origin',
|
||||
optional: true
|
||||
}
|
||||
});*/
|
||||
@ -69,7 +69,7 @@ services:
|
||||
# - orthanc
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- REACT_APP_CONFIG=config/local_dcm4chee
|
||||
- APP_CONFIG=config/local_dcm4chee
|
||||
restart: always
|
||||
networks:
|
||||
- dcm4che_default
|
||||
|
||||
@ -28,7 +28,7 @@ FROM node:11.2.0-slim as builder
|
||||
RUN mkdir /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
ENV REACT_APP_CONFIG=config/docker_openresty-orthanc-keycloak.js
|
||||
ENV APP_CONFIG=config/docker_openresty-orthanc-keycloak.js
|
||||
ENV PATH /usr/src/app/node_modules/.bin:$PATH
|
||||
|
||||
COPY package.json /usr/src/app/package.json
|
||||
|
||||
@ -28,7 +28,7 @@ FROM node:11.2.0-slim as builder
|
||||
RUN mkdir /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
ENV REACT_APP_CONFIG=config/docker_openresty-orthanc.js
|
||||
ENV APP_CONFIG=config/docker_openresty-orthanc.js
|
||||
ENV PATH /usr/src/app/node_modules/.bin:$PATH
|
||||
|
||||
COPY package.json /usr/src/app/package.json
|
||||
|
||||
@ -3,6 +3,33 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.50.6](https://github.com/OHIF/Viewers/compare/@ohif/viewer@0.50.5...@ohif/viewer@0.50.6) (2019-08-22)
|
||||
|
||||
**Note:** Version bump only for package @ohif/viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.50.5](https://github.com/OHIF/Viewers/compare/@ohif/viewer@0.50.4...@ohif/viewer@0.50.5) (2019-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **StandaloneRouting:** Promise rejection - added `return` ([#791](https://github.com/OHIF/Viewers/issues/791)) ([d09fb4e](https://github.com/OHIF/Viewers/commit/d09fb4e))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.50.4](https://github.com/OHIF/Viewers/compare/@ohif/viewer@0.50.3...@ohif/viewer@0.50.4) (2019-08-20)
|
||||
|
||||
**Note:** Version bump only for package @ohif/viewer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.50.3](https://github.com/OHIF/Viewers/compare/@ohif/viewer@0.50.2...@ohif/viewer@0.50.3) (2019-08-15)
|
||||
|
||||
**Note:** Version bump only for package @ohif/viewer
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ohif/viewer",
|
||||
"version": "0.50.3",
|
||||
"version": "0.50.6",
|
||||
"description": "OHIF Viewer",
|
||||
"author": "OHIF Contributors",
|
||||
"license": "MIT",
|
||||
@ -44,12 +44,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"@ohif/core": "^0.50.1",
|
||||
"@ohif/core": "^0.50.2",
|
||||
"@ohif/extension-cornerstone": "^0.50.1",
|
||||
"@ohif/extension-dicom-html": "^0.50.1",
|
||||
"@ohif/extension-dicom-microscopy": "^0.50.1",
|
||||
"@ohif/extension-dicom-pdf": "^0.50.1",
|
||||
"@ohif/extension-vtk": "^0.50.2",
|
||||
"@ohif/extension-vtk": "^0.50.3",
|
||||
"@ohif/i18n": "^0.50.1",
|
||||
"@ohif/ui": "^0.50.1",
|
||||
"@tanem/react-nprogress": "^1.1.25",
|
||||
|
||||
@ -26,7 +26,7 @@ class StandaloneRouting extends Component {
|
||||
const url = query.url;
|
||||
|
||||
if (!url) {
|
||||
reject(new Error("No URL was specified. Use ?url=$yourURL"));
|
||||
return reject(new Error("No URL was specified. Use ?url=$yourURL"));
|
||||
}
|
||||
|
||||
// Define a request to the server to retrieve the study data
|
||||
|
||||
Loading…
Reference in New Issue
Block a user