diff --git a/nav-app/package-lock.json b/nav-app/package-lock.json index 2f16fffb5..c0cb837ca 100644 --- a/nav-app/package-lock.json +++ b/nav-app/package-lock.json @@ -27,8 +27,8 @@ "core-js": "^3.31.1", "d3": "^7.8.5", "d3-svg-legend": "^2.25.6", + "detect-browser": "^5.3.0", "file-saver": "^2.0.5", - "is_js": "^0.9.0", "load-json-file": "^7.0.1", "mathjs": "^12.4.2", "ngx-color-picker": "^16.0.0", @@ -7709,6 +7709,11 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-browser": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz", + "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==" + }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -9473,11 +9478,6 @@ "node": ">= 10" } }, - "node_modules/is_js": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", - "integrity": "sha512-8Y5EHSH+TonfUHX2g3pMJljdbGavg55q4jmHzghJCdqYDbdNROC8uw/YFQwIRCRqRJT1EY3pJefz+kglw+o7sg==" - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", diff --git a/nav-app/package.json b/nav-app/package.json index a420a3795..caa2b160c 100644 --- a/nav-app/package.json +++ b/nav-app/package.json @@ -34,8 +34,8 @@ "core-js": "^3.31.1", "d3": "^7.8.5", "d3-svg-legend": "^2.25.6", + "detect-browser": "^5.3.0", "file-saver": "^2.0.5", - "is_js": "^0.9.0", "load-json-file": "^7.0.1", "mathjs": "^12.4.2", "ngx-color-picker": "^16.0.0", diff --git a/nav-app/src/app/datatable/data-table.component.ts b/nav-app/src/app/datatable/data-table.component.ts index fa9506f8b..056dfe208 100755 --- a/nav-app/src/app/datatable/data-table.component.ts +++ b/nav-app/src/app/datatable/data-table.component.ts @@ -7,8 +7,8 @@ import { ViewModel } from '../classes'; import { DomSanitizer } from '@angular/platform-browser'; import { Subscription } from 'rxjs'; import * as Excel from 'exceljs/dist/exceljs.min.js'; -import * as is from 'is_js'; import tinycolor from 'tinycolor2'; +import { isIE } from '../utils/utils'; @Component({ selector: 'DataTable', @@ -104,7 +104,7 @@ export class DataTableComponent implements AfterViewInit, OnDestroy { * @param filename save as filename */ public saveBlob(blob, filename): void { - if (is.ie()) { + if (isIE()) { // internet explorer const nav = window.navigator as any; nav.msSaveOrOpenBlob(blob, filename); diff --git a/nav-app/src/app/services/viewmodels.service.ts b/nav-app/src/app/services/viewmodels.service.ts index 4cd26b64a..13398541e 100755 --- a/nav-app/src/app/services/viewmodels.service.ts +++ b/nav-app/src/app/services/viewmodels.service.ts @@ -2,7 +2,7 @@ import { EventEmitter, Injectable, Output } from '@angular/core'; import { Gradient, TechniqueVM, ViewModel } from '../classes'; import { DataService } from './data.service'; import { evaluate } from 'mathjs'; -import * as is from 'is_js'; +import { isBoolean, isNumber } from '../utils/utils'; @Injectable({ providedIn: 'root', @@ -98,10 +98,10 @@ export class ViewModelsService { // if it didn't except after this, it evaluated to a single result console.debug('score expression evaluated to single result to be applied to all techniques'); - if (is.boolean(result)) { + if (isBoolean(result)) { // boolean to binary result = result ? '1' : '0'; - } else if (is.not.number(result)) { + } else if (!isNumber(result)) { // unexpected user input throw Error('math result ( ' + result + ' ) is not a number'); } @@ -139,10 +139,10 @@ export class ViewModelsService { // did at least one technique have a score for this technique? if (misses < scoreVariables.size) { let mathResult = evaluate(opSettings.scoreExpression, scope); - if (is.boolean(mathResult)) { + if (isBoolean(mathResult)) { // boolean to binary mathResult = mathResult ? '1' : '0'; - } else if (is.not.number(mathResult)) { + } else if (!isNumber(mathResult)) { // unexpected user input throw Error('math result ( ' + mathResult + ' ) is not a number'); } diff --git a/nav-app/src/app/svg-export/svg-export.component.ts b/nav-app/src/app/svg-export/svg-export.component.ts index 701f6b741..665dd069d 100644 --- a/nav-app/src/app/svg-export/svg-export.component.ts +++ b/nav-app/src/app/svg-export/svg-export.component.ts @@ -5,7 +5,7 @@ import { ConfigService } from '../services/config.service'; import { DataService } from '../services/data.service'; import { RenderableMatrix, RenderableTactic, RenderableTechnique } from './renderable-objects'; import tinycolor from 'tinycolor2'; -import * as is from 'is_js'; +import { isIE } from '../utils/utils'; declare var d3: any; //d3js @Component({ @@ -62,7 +62,7 @@ export class SvgExportComponent implements OnInit { // browser compatibility public get isIE(): boolean { - return is.ie(); + return isIE(); } // getters for visibility of SVG header sections diff --git a/nav-app/src/app/tabs/tabs.component.spec.ts b/nav-app/src/app/tabs/tabs.component.spec.ts index 907f1cc34..6f35c2dcc 100755 --- a/nav-app/src/app/tabs/tabs.component.spec.ts +++ b/nav-app/src/app/tabs/tabs.component.spec.ts @@ -11,7 +11,6 @@ import { MatTabsModule } from "@angular/material/tabs"; import { ConfigService } from "../services/config.service"; import * as MockData from '../../tests/utils/mock-data'; import * as MockLayers from '../../tests/utils/mock-layers'; -import * as is from 'is_js'; import { of } from "rxjs"; import { ChangelogComponent } from "../changelog/changelog.component"; import { HelpComponent } from "../help/help.component"; @@ -93,22 +92,6 @@ describe('TabsComponent', () => { }); }); - describe('ngAfterViewInit', () => { - it('should open Safari warning for Safari version <= 13', () => { - spyOn(is, 'safari').withArgs('<=13').and.returnValue(true); - let dialogSpy = spyOn(dialog, 'open'); - component.ngAfterViewInit(); - expect(dialogSpy).toHaveBeenCalled(); - }); - - it('should not open Safari warning for Safari version > 13 or non-Safari browsers', () => { - spyOn(is, 'safari').withArgs('<=13').and.returnValue(false); - let dialogSpy = spyOn(dialog, 'open'); - component.ngAfterViewInit(); - expect(dialogSpy).not.toHaveBeenCalled(); - }); - }); - describe('loadTabs', () => { it('should load bundle when all fragment values are provided', async () => { let bundleURL = 'testbundleurl'; diff --git a/nav-app/src/app/tabs/tabs.component.ts b/nav-app/src/app/tabs/tabs.component.ts index ae23ea7cf..c0c117063 100755 --- a/nav-app/src/app/tabs/tabs.component.ts +++ b/nav-app/src/app/tabs/tabs.component.ts @@ -11,9 +11,9 @@ import { MatSnackBar } from '@angular/material/snack-bar'; import { HttpClient } from '@angular/common/http'; import { ChangelogComponent } from '../changelog/changelog.component'; import { Subscription, forkJoin } from 'rxjs'; -import * as is from 'is_js'; import * as globals from '../utils/globals'; import { LayerInformationComponent } from '../layer-information/layer-information.component'; +import { isSafari } from '../utils/utils'; @Component({ selector: 'tabs', @@ -94,7 +94,7 @@ export class TabsComponent implements AfterViewInit { } ngAfterViewInit(): void { - if (is.safari('<=13')) { + if (isSafari('<=13')) { // open safari version incompatibility warning this.safariDialogRef = this.dialog.open(this.safariWarning, { width: '350px', diff --git a/nav-app/src/app/utils/utils.ts b/nav-app/src/app/utils/utils.ts new file mode 100644 index 000000000..a371049d1 --- /dev/null +++ b/nav-app/src/app/utils/utils.ts @@ -0,0 +1,34 @@ +// utils.ts +import { detect } from "detect-browser"; + +let comparatorFn = { + '<': function(a, b) { return a < b; }, + '<=': function(a, b) { return a <= b; }, + '>': function(a, b) { return a > b; }, + '>=': function(a, b) { return a >= b; } +}; + +export function isBoolean(value: any): boolean { + return typeof value === 'boolean'; +} + +export function isNumber(value: any): boolean { + return typeof value === 'number'; +} + +export function isIE(): boolean { + const browser = detect(); + return browser.name == 'ie'; +} + +export function isSafari(compRange): boolean { + function compare(version, comp) { + let str = (comp + ''); + let n = +(/\d+/.exec(str) || NaN); + let op = /^[<>]=?/.exec(str)[0]; + return comparatorFn[op] ? comparatorFn[op](version, n) : (version == n || Number.isNaN(n)); + } + + const browser = detect(); + return browser.name == 'safari' && compare(browser.version.split('.')[0], compRange); +}