@anexia/platform-tools
Version:
Provides Ionic Framework way class mapping of current platform and orientation on the root document node ´html´ for usage inside scss or :host-context selecting.
92 lines • 13.6 kB
JavaScript
import { Injectable } from '@angular/core';
import { fromEvent } from "rxjs";
import { startWith, tap } from "rxjs/operators";
import * as i0 from "@angular/core";
export class PlatformToolsService {
constructor() {
setupPlatforms(window);
fromEvent(window, 'resize').pipe(startWith(true), tap(_ => updateOrientation(window))).subscribe();
}
}
PlatformToolsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.3", ngImport: i0, type: PlatformToolsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
PlatformToolsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.3", ngImport: i0, type: PlatformToolsService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.3", ngImport: i0, type: PlatformToolsService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return []; } });
export function updateOrientation(win) {
if (win.matchMedia("(orientation: portrait)").matches) {
win.document.documentElement.classList.add('is-portrait');
win.document.documentElement.classList.remove('is-landscape');
}
if (win.matchMedia("(orientation: landscape)").matches) {
win.document.documentElement.classList.add('is-landscape');
win.document.documentElement.classList.remove('is-portrait');
}
}
export const setupPlatforms = (win = window) => {
if (typeof win === 'undefined') {
return [];
}
let platforms = null;
platforms = detectPlatforms(win);
platforms.forEach(p => win.document.documentElement.classList.add(`plt-${p}`));
return platforms;
};
const detectPlatforms = (win) => Object.keys(PLATFORMS_MAP).filter(p => PLATFORMS_MAP[p](win));
const isMobileWeb = (win) => isMobile(win);
const isIpad = (win) => {
// iOS 12 and below
if (testUserAgent(win, /iPad/i)) {
return true;
}
// iOS 13+
if (testUserAgent(win, /Macintosh/i) && isMobile(win)) {
return true;
}
return false;
};
const isIphone = (win) => testUserAgent(win, /iPhone/i);
const isIOS = (win) => testUserAgent(win, /iPhone|iPod/i) || isIpad(win);
const isAndroid = (win) => testUserAgent(win, /android|sink/i);
const isAndroidTablet = (win) => {
return isAndroid(win) && !testUserAgent(win, /mobile/i);
};
const isPhablet = (win) => {
const width = win.innerWidth;
const height = win.innerHeight;
const smallest = Math.min(width, height);
const largest = Math.max(width, height);
return (smallest > 390 && smallest < 520) &&
(largest > 620 && largest < 800);
};
const isTablet = (win) => {
const width = win.innerWidth;
const height = win.innerHeight;
const smallest = Math.min(width, height);
const largest = Math.max(width, height);
return (isIpad(win) ||
isAndroidTablet(win) ||
((smallest > 460 && smallest < 820) &&
(largest > 780 && largest < 1400)));
};
const isMobile = (win) => matchMedia(win, '(any-pointer:coarse)');
const isDesktop = (win) => !isMobile(win);
const isPWA = (win) => !!(win.matchMedia('(display-mode: standalone)').matches || win.navigator.standalone);
export const testUserAgent = (win, expr) => expr.test(win.navigator.userAgent);
const matchMedia = (win, query) => win.matchMedia(query).matches;
const PLATFORMS_MAP = {
'ipad': isIpad,
'iphone': isIphone,
'ios': isIOS,
'android': isAndroid,
'phablet': isPhablet,
'tablet': isTablet,
'pwa': isPWA,
'mobile': isMobile,
'mobileweb': isMobileWeb,
'desktop': isDesktop
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhdGZvcm0tdG9vbHMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3BsYXRmb3JtLXRvb2xzL3NyYy9saWIvcGxhdGZvcm0tdG9vbHMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQzs7QUFPOUMsTUFBTSxPQUFPLG9CQUFvQjtJQUUvQjtRQUNFLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV2QixTQUFTLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FDOUIsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUNmLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQ3BDLENBQUMsU0FBUyxFQUFFLENBQUM7SUFFaEIsQ0FBQzs7aUhBVlUsb0JBQW9CO3FIQUFwQixvQkFBb0IsY0FGbkIsTUFBTTsyRkFFUCxvQkFBb0I7a0JBSGhDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COztBQWVELE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxHQUFTO0lBRXpDLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLE9BQU8sRUFBRTtRQUNyRCxHQUFHLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzFELEdBQUcsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7S0FDL0Q7SUFFRCxJQUFJLEdBQUcsQ0FBQyxVQUFVLENB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O0FBRXJDLE1BQU0sVUFBVSxHQUFHLENBQUMsR0FBVyxFQUFFLEtBQWEsRUFBVyxFQUFFLENBQ3pELEdBQUcsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDO0FBRWhDLE1BQU0sYUFBYSxHQUFHO0lBQ3BCLE1BQU0sRUFBRSxNQUFNO0lBQ2QsUUFBUSxFQUFFLFFBQVE7SUFDbEIsS0FBSyxFQUFFLEtBQUs7SUFDWixTQUFTLEVBQUUsU0FBUztJQUNwQixTQUFTLEVBQUUsU0FBUztJQUNwQixRQUFRLEVBQUUsUUFBUTtJQUNsQixLQUFLLEVBQUUsS0FBSztJQUNaLFFBQVEsRUFBRSxRQUFRO0lBQ2xCLFdBQVcsRUFBRSxXQUFXO0lBQ3hCLFNBQVMsRUFBRSxTQUFTO0NBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtmcm9tRXZlbnR9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQge3N0YXJ0V2l0aCwgdGFwfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcblxuZXhwb3J0IHR5cGUgUGxhdGZvcm1zID0ga2V5b2YgdHlwZW9mIFBMQVRGT1JNU19NQVA7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFBsYXRmb3JtVG9vbHNTZXJ2aWNlIHtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XG4gICAgc2V0dXBQbGF0Zm9ybXMod2luZG93KTtcblxuICAgIGZyb21FdmVudCh3aW5kb3csICdyZXNpemUnKS5waXBlKFxuICAgICAgc3RhcnRXaXRoKHRydWUpLFxuICAgICAgdGFwKF8gPT4gdXBkYXRlT3JpZW50YXRpb24od2luZG93KSlcbiAgICApLnN1YnNjcmliZSgpO1xuXG4gIH1cblxufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlT3JpZW50YXRpb24od2luPzogYW55KSB7XG5cbiAgaWYgKHdpbi5tYXRjaE1lZGlhKFwiKG9yaWVudGF0aW9uOiBwb3J0cmFpdClcIikubWF0Y2hlcykge1xuICAgIHdpbi5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnaXMtcG9ydHJhaXQnKTtcbiAgICB3aW4uZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2lzLWxhbmRzY2FwZScpO1xuICB9XG5cbiAgaWYgKHdpbi5tYXRjaE1lZGlhKFwiKG9yaWVudGF0aW9uOiBsYW5kc2NhcGUpXCIpLm1hdGNoZXMpIHtcbiAgICB3aW4uZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2lzLWxhbmRzY2FwZScpO1xuICAgIHdpbi5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnaXMtcG9ydHJhaXQnKTtcbiAgfVxuXG59XG5cbmV4cG9ydCBjb25zdCBzZXR1cFBsYXRmb3JtcyA9ICh3aW46IGFueSA9IHdpbmRvdykgPT4ge1xuICBpZiAodHlwZW9mIHdpbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBsZXQgcGxhdGZvcm1zOiBQbGF0Zm9ybXNbXSB8IHVuZGVmaW5lZCB8IG51bGwgPSBudWxsO1xuICBwbGF0Zm9ybXMgPSBkZXRlY3RQbGF0Zm9ybXMod2luKTtcbiAgcGxhdGZvcm1zLmZvckVhY2gocCA9PiB3aW4uZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoYHBsdC0ke3B9YCkpO1xuXG4gIHJldHVybiBwbGF0Zm9ybXM7XG59O1xuXG5jb25zdCBkZXRlY3RQbGF0Zm9ybXMgPSAod2luOiBXaW5kb3cpID0+XG4gIChPYmplY3Qua2V5cyhQTEFURk9STVNfTUFQKSBhcyBQbGF0Zm9ybXNbXSkuZmlsdGVyKHAgPT4gUExBVEZPUk1TX01BUFtwXSh3aW4pKTtcblxuY29uc3QgaXNNb2JpbGVXZWIgPSAod2luOiBXaW5kb3cpOiBib29sZWFuID0+XG4gIGlzTW9iaWxlKHdpbik7XG5cbmNvbnN0IGlzSXBhZCA9ICh3aW46IFdpbmRvdykgPT4ge1xuICAvLyBpT1MgMTIgYW5kIGJlbG93XG4gIGlmICh0ZXN0VXNlckFnZW50KHdpbiwgL2lQYWQvaSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIGlPUyAxMytcbiAgaWYgKHRlc3RVc2VyQWdlbnQod2luLCAvTWFjaW50b3NoL2kpICYmIGlzTW9iaWxlKHdpbikpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IGlzSXBob25lID0gKHdpbjogV2luZG93KSA9PlxuICB0ZXN0VXNlckFnZW50KHdpbiwgL2lQaG9uZS9pKTtcblxuY29uc3QgaXNJT1MgPSAod2luOiBXaW5kb3cpID0+XG4gIHRlc3RVc2VyQWdlbnQod2luLCAvaVBob25lfGlQb2QvaSkgfHwgaXNJcGFkKHdpbik7XG5cbmNvbnN0IGlzQW5kcm9pZCA9ICh3aW46IFdpbmRvdykgPT5cbiAgdGVzdFVzZXJBZ2VudCh3aW4sIC9hbmRyb2lkfHNpbmsvaSk7XG5cbmNvbnN0IGlzQW5kcm9pZFRhYmxldCA9ICh3aW46IFdpbmRvdykgPT4ge1xuICByZXR1cm4gaXNBbmRyb2lkKHdpbikgJiYgIXRlc3RVc2VyQWdlbnQod2luLCAvbW9iaWxlL2kpO1xufTtcblxuY29uc3QgaXNQaGFibGV0ID0gKHdpbjogV2luZG93KSA9PiB7XG4gIGNvbnN0IHdpZHRoID0gd2luLmlubmVyV2lkdGg7XG4gIGNvbnN0IGhlaWdodCA9IHdpbi5pbm5lckhlaWdodDtcbiAgY29uc3Qgc21hbGxlc3QgPSBNYXRoLm1pbih3aWR0aCwgaGVpZ2h0KTtcbiAgY29uc3QgbGFyZ2VzdCA9IE1hdGgubWF4KHdpZHRoLCBoZWlnaHQpO1xuXG4gIHJldHVybiAoc21hbGxlc3QgPiAzOTAgJiYgc21hbGxlc3QgPCA1MjApICYmXG4gICAgKGxhcmdlc3QgPiA2MjAgJiYgbGFyZ2VzdCA8IDgwMCk7XG59O1xuXG5jb25zdCBpc1RhYmxldCA9ICh3aW46IFdpbmRvdykgPT4ge1xuICBjb25zdCB3aWR0aCA9IHdpbi5pbm5lcldpZHRoO1xuICBjb25zdCBoZWlnaHQgPSB3aW4uaW5uZXJIZWlnaHQ7XG4gIGNvbnN0IHNtYWxsZXN0ID0gTWF0aC5taW4od2lkdGgsIGhlaWdodCk7XG4gIGNvbnN0IGxhcmdlc3QgPSBNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KTtcblxuICByZXR1cm4gKFxuICAgIGlzSXBhZCh3aW4pIHx8XG4gICAgaXNBbmRyb2lkVGFibGV0KHdpbikgfHxcbiAgICAoXG4gICAgICAoc21hbGxlc3QgPiA0NjAgJiYgc21hbGxlc3QgPCA4MjApICYmXG4gICAgICAobGFyZ2VzdCA+IDc4MCAmJiBsYXJnZXN0IDwgMTQwMClcbiAgICApXG4gICk7XG59O1xuXG5jb25zdCBpc01vYmlsZSA9ICh3aW46IFdpbmRvdykgPT5cbiAgbWF0Y2hNZWRpYSh3aW4sICcoYW55LXBvaW50ZXI6Y29hcnNlKScpO1xuXG5jb25zdCBpc0Rlc2t0b3AgPSAod2luOiBXaW5kb3cpID0+XG4gICFpc01vYmlsZSh3aW4pO1xuXG5jb25zdCBpc1BXQSA9ICh3aW46IFdpbmRvdyk6IGJvb2xlYW4gPT5cbiAgISEod2luLm1hdGNoTWVkaWEoJyhkaXNwbGF5LW1vZGU6IHN0YW5kYWxvbmUpJykubWF0Y2hlcyB8fCAod2luLm5hdmlnYXRvciBhcyBhbnkpLnN0YW5kYWxvbmUpO1xuXG5leHBvcnQgY29uc3QgdGVzdFVzZXJBZ2VudCA9ICh3aW46IFdpbmRvdywgZXhwcjogUmVnRXhwKSA9PlxuICBleHByLnRlc3Qod2luLm5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG5jb25zdCBtYXRjaE1lZGlhID0gKHdpbjogV2luZG93LCBxdWVyeTogc3RyaW5nKTogYm9vbGVhbiA9PlxuICB3aW4ubWF0Y2hNZWRpYShxdWVyeSkubWF0Y2hlcztcblxuY29uc3QgUExBVEZPUk1TX01BUCA9IHtcbiAgJ2lwYWQnOiBpc0lwYWQsXG4gICdpcGhvbmUnOiBpc0lwaG9uZSxcbiAgJ2lvcyc6IGlzSU9TLFxuICAnYW5kcm9pZCc6IGlzQW5kcm9pZCxcbiAgJ3BoYWJsZXQnOiBpc1BoYWJsZXQsXG4gICd0YWJsZXQnOiBpc1RhYmxldCxcbiAgJ3B3YSc6IGlzUFdBLFxuICAnbW9iaWxlJzogaXNNb2JpbGUsXG4gICdtb2JpbGV3ZWInOiBpc01vYmlsZVdlYixcbiAgJ2Rlc2t0b3AnOiBpc0Rlc2t0b3Bcbn07XG4iXX0=