UNPKG

web-atoms-core

Version:
490 lines • 23.9 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "../../App", "../../Atom", "../../core/AtomLoader", "../../core/AtomUri", "../../core/FormattedError", "../../core/FormattedString", "../../di/Inject", "../../di/RegisterSingleton", "../../di/ServiceCollection", "../../services/JsonService", "../../services/NavigationService", "../../view-model/AtomWindowViewModel", "../../web/core/AtomUI", "../controls/AtomAlertWindow", "../controls/AtomNotification", "../controls/AtomWindow", "../styles/AtomStyleSheet", "../styles/StyleBuilder"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var App_1 = require("../../App"); var Atom_1 = require("../../Atom"); var AtomLoader_1 = require("../../core/AtomLoader"); var AtomUri_1 = require("../../core/AtomUri"); var FormattedError_1 = require("../../core/FormattedError"); var FormattedString_1 = require("../../core/FormattedString"); var Inject_1 = require("../../di/Inject"); var RegisterSingleton_1 = require("../../di/RegisterSingleton"); var ServiceCollection_1 = require("../../di/ServiceCollection"); var JsonService_1 = require("../../services/JsonService"); var NavigationService_1 = require("../../services/NavigationService"); var AtomWindowViewModel_1 = require("../../view-model/AtomWindowViewModel"); var AtomUI_1 = require("../../web/core/AtomUI"); var AtomAlertWindow_1 = require("../controls/AtomAlertWindow"); var AtomNotification_1 = require("../controls/AtomNotification"); var AtomWindow_1 = require("../controls/AtomWindow"); var AtomStyleSheet_1 = require("../styles/AtomStyleSheet"); var StyleBuilder_1 = require("../styles/StyleBuilder"); var WindowService = /** @class */ (function (_super) { __extends(WindowService, _super); function WindowService(app, jsonService) { var _this = _super.call(this, app) || this; _this.jsonService = jsonService; _this.targetStack = []; _this.popups = []; _this.hostForElementFunc = []; _this.lastPopupID = 0; _this.screen = app.screen; var st = "desktop"; if (/mobile|android|ios/i.test(window.navigator.userAgent)) { st = "mobile"; if (/tablet/i.test(window.navigator.userAgent)) { st = "tablet"; } } _this.screen.screenType = st; if (window) { window.addEventListener("click", function (e) { // this.currentTarget = e.target as HTMLElement; _this.closePopup(e); }); var update_1 = function (e) { _this.refreshScreen(); }; // we don't do this in mobile.. if (st !== "mobile") { window.addEventListener("resize", update_1); window.addEventListener("scroll", update_1); document.body.addEventListener("scroll", update_1); document.body.addEventListener("resize", update_1); } setTimeout(function () { update_1(null); }, 1000); } return _this; } Object.defineProperty(WindowService.prototype, "currentTarget", { get: function () { var ts = this.targetStack; return ts.length > 0 ? ts[ts.length - 1] : undefined; }, set: function (v) { var ts = this.targetStack; var nts = []; if (v === null) { // special case... remove all non existent elements... for (var _i = 0, ts_1 = ts; _i < ts_1.length; _i++) { var iterator = ts_1[_i]; if (iterator.parentElement) { nts.push(iterator); } } this.targetStack = nts; return; } if (ts.length === 0 && ts[ts.length - 1] === v) { return; } ts.push(v); }, enumerable: true, configurable: true }); Object.defineProperty(WindowService.prototype, "title", { /** * Get current window title * * @type {string} * @memberof BrowserService */ get: function () { return window.document.title; }, /** * Set current window title * @memberof BrowserService */ set: function (v) { window.document.title = v; }, enumerable: true, configurable: true }); Object.defineProperty(WindowService.prototype, "location", { /** * Gets current location of browser, this does not return * actual location but it returns values of browser location. * This is done to provide mocking behavior for unit testing. * * @readonly * @type {AtomLocation} * @memberof BrowserService */ get: function () { return new AtomUri_1.AtomUri(location.href); }, set: function (v) { location.href = v.toString(); }, enumerable: true, configurable: true }); WindowService.prototype.registerHostForWindow = function (f) { var _this = this; this.hostForElementFunc.push(f); return { dispose: function () { _this.hostForElementFunc.remove(f); } }; }; /** * Navigate current browser to given url. * @param {string} url * @memberof BrowserService */ WindowService.prototype.navigate = function (url) { location.href = url; }; WindowService.prototype.back = function () { window.history.back(); }; WindowService.prototype.register = function (id, type) { ServiceCollection_1.ServiceCollection.instance.register(type, null, ServiceCollection_1.Scope.Transient, id); }; WindowService.prototype.confirm = function (message, title) { return this.openPage(AtomAlertWindow_1.default, { okTitle: "Yes", cancelTitle: "No", title: title || "Confirm", message: message }); }; WindowService.prototype.alert = function (message, title) { if (!(message instanceof FormattedString_1.default || typeof message === "string")) { if (message instanceof FormattedError_1.default) { message = message.formattedMessage; } else { message = message.message ? message.message : message.toString(); } } return this.openPage(AtomAlertWindow_1.default, { message: message, title: title, okTitle: "Ok", cancelTitle: "" }).catch(function (e) { // do nothing... // tslint:disable-next-line: no-console console.warn(e); }); }; WindowService.prototype.closePopup = function (e) { // need to simulate parent click if we are inside an iframe... var fe = typeof frameElement !== "undefined" ? frameElement : null; if (fe) { fe.click(); var pe = fe.ownerDocument ? fe.ownerDocument.defaultView : null; if (pe && pe.simulateParentClick) { pe.simulateParentClick(); } } var target = this.currentTarget; var et = e.target; if (!et.parentElement) { // probably the window/popup was just disposed.. // ignore it... // if mouse click was outside body and within the window // target element will be HTML // in that case we have to dispose the top popup if (!/html/i.test(et.tagName)) { return; } // we need to manually override target so popup will be disposed target = et; } this.currentTarget = e.target; if (!this.popups.length) { return; } var peek = this.popups[this.popups.length - 1]; var element = peek.element; while (target) { if (target === element) { // do not close this popup.... return; } if (element._logicalParent === target) { return; } target = target.parentElement; } this.remove(peek); }; WindowService.prototype.refresh = function () { location.reload(true); }; WindowService.prototype.getHostForElement = function () { var ce = this.currentTarget; if (!ce) { return null; } for (var _i = 0, _a = this.hostForElementFunc; _i < _a.length; _i++) { var iterator = _a[_i]; var e = iterator(ce); if (e) { return e; } } return null; }; WindowService.prototype.refreshScreen = function () { var height = this.screen.height = window.innerHeight || document.body.clientHeight; var width = this.screen.width = window.innerWidth || document.body.clientWidth; this.screen.scrollLeft = window.scrollX || document.body.scrollLeft || 0; this.screen.scrollTop = window.scrollY || document.body.scrollTop || 0; this.screen.orientation = width > height ? "landscape" : "portrait"; }; WindowService.prototype.notify = function (message, title, type, delay) { var _this = this; this.app.runAsync(function () { return _this.openPage(AtomNotification_1.default, { message: message, title: title, type: type || NavigationService_1.NotifyType.Information, timeout: delay }); }); }; WindowService.prototype.registerForPopup = function () { var _this = this; if (window) { window.addEventListener("click", function (e) { _this.closePopup(e); }); } }; WindowService.prototype.openWindow = function (url, options) { return __awaiter(this, void 0, void 0, function () { var lastTarget, _a, popup, returnPromise, disposables, cancelToken, e, isPopup, pvm, ce, theme, isNotification, sr, x, y, h, eHost, host_1; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: // this is because current target is not yet set return [4 /*yield*/, Atom_1.Atom.delay(1)]; case 1: // this is because current target is not yet set _b.sent(); lastTarget = this.currentTarget; return [4 /*yield*/, AtomLoader_1.AtomLoader.loadView(url, this.app, true, function () { return _this.app.resolve(AtomWindowViewModel_1.AtomWindowViewModel, true); })]; case 2: _a = _b.sent(), popup = _a.view, returnPromise = _a.returnPromise, disposables = _a.disposables; cancelToken = options.cancelToken; if (cancelToken) { if (cancelToken.cancelled) { this.app.callLater(function () { _this.remove(popup, true); }); } cancelToken.registerForCancel(function () { _this.remove(popup, true); }); } e = popup.element; isPopup = true; if (popup instanceof AtomWindow_1.AtomWindow) { isPopup = false; e.style.opacity = "0"; } e._logicalParent = lastTarget; e.sourceUrl = url; pvm = popup.viewModel; if (pvm) { ce = this.currentTarget; if (ce) { while (!ce.atomControl) { ce = ce.parentElement; if (!ce) { break; } } if (ce && ce.atomControl && ce.atomControl.viewModel) { pvm.parent = ce.atomControl.viewModel; } } } theme = this.app.get(AtomStyleSheet_1.AtomStyleSheet).popup; e.style.zIndex = 10000 + this.lastPopupID + ""; isNotification = popup instanceof AtomNotification_1.default; if (isPopup) { sr = AtomUI_1.AtomUI.screenOffset(this.currentTarget); x = sr.x; y = sr.y; h = sr.height; e.style.position = "absolute"; e.style.left = x + "px"; e.style.top = (y + h) + "px"; e.classList.add(theme.host.className); this.popups.push(popup); disposables.add(function () { _this.popups.remove(popup); }); document.body.appendChild(e); if (isNotification) { e.style.opacity = "0"; this.centerElement(popup); } } else { eHost = this.getHostForElement(); if (eHost) { eHost.appendChild(e); } else { host_1 = document.createElement("div"); document.body.appendChild(host_1); host_1.style.position = "absolute"; host_1.appendChild(e); disposables.add({ dispose: function () { host_1.remove(); } }); this.refreshScreen(); popup.bind(host_1, "styleLeft", [["this", "scrollLeft"]], false, StyleBuilder_1.cssNumberToString, this.screen); popup.bind(host_1, "styleTop", [["this", "scrollTop"]], false, StyleBuilder_1.cssNumberToString, this.screen); popup.bind(host_1, "styleWidth", [["this", "width"]], false, StyleBuilder_1.cssNumberToString, this.screen); popup.bind(host_1, "styleHeight", [["this", "height"]], false, StyleBuilder_1.cssNumberToString, this.screen); } } this.currentTarget = e; popup.bindEvent(document.body, "keyup", function (keyboardEvent) { if (keyboardEvent.key === "Escape") { _this.app.runAsync(function () { return _this.remove(popup); }); } }); disposables.add({ dispose: function () { e.innerHTML = ""; e.remove(); _this.currentTarget = null; } }); return [4 /*yield*/, returnPromise]; case 3: return [2 /*return*/, _b.sent()]; } }); }); }; WindowService.prototype.centerElement = function (c) { var _this = this; var e = c.element; var parent = e.parentElement; if (parent === window || parent === document.body) { setTimeout(function () { var ew = (document.body.offsetWidth - e.offsetWidth) / 2; var eh = window.scrollY + ((window.innerHeight - e.offsetHeight) / 2); e.style.left = ew + "px"; e.style.top = eh + "px"; e.style.removeProperty("opacity"); }, 200); return; } if (parent.offsetWidth <= 0 || parent.offsetHeight <= 0) { setTimeout(function () { _this.centerElement(c); }, 100); return; } if (e.offsetWidth <= 0 || e.offsetHeight <= 0) { setTimeout(function () { _this.centerElement(c); }, 100); return; } var x = (parent.offsetWidth - e.offsetWidth) / 2; var y = (parent.offsetHeight - e.offsetHeight) / 2; e.style.left = x + "px"; e.style.top = y + "px"; e.style.removeProperty("opacity"); }; /** * This is just to preload Alert window. */ WindowService.alertWindow = AtomAlertWindow_1.default; WindowService = __decorate([ RegisterSingleton_1.RegisterSingleton, __param(0, Inject_1.Inject), __param(1, Inject_1.Inject), __metadata("design:paramtypes", [App_1.App, JsonService_1.JsonService]) ], WindowService); return WindowService; }(NavigationService_1.NavigationService)); exports.WindowService = WindowService; }); //# sourceMappingURL=WindowService.js.map