Source: QfqPage.js

/**
                * @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
                */

                /* global $ */
                /* global console */
                /* @depend QfqEvents.js */

                /**
                * Qfq Namespace
                *
                * @namespace QfqNS
                */
                var QfqNS = QfqNS || {};

                (function (n) {
                'use strict';

                /**
                *
                * @param settings
                * @constructor
                *
                * @name QfqNS.QfqPage
                */
                n.QfqPage = function (settings) {
                this.settings = $.extend(
                {
                tabsId: "qfqTabs",
                formId: "qfqForm",
                submitTo: "typo3conf/ext/qfq/qfq/api/save.php",
                deleteUrl: "typo3conf/ext/qfq/qfq/api/delete.php",
                refreshUrl: "typo3conf/ext/qfq/qfq/api/load.php",
                fileUploadTo: "typo3conf/ext/qfq/qfq/api/upload.php",
                fileDeleteUrl: "typo3conf/ext/qfq/qfq/api/filedelete.php",
                pageState: new n.PageState()
                }, settings
                );

                this.intentionalClose = false;

                try {
                this.bsTabs = new n.BSTabs(this.settings.tabsId);

                var currentState = this.settings.pageState.getPageState();
                if (currentState !== "") {
                this.bsTabs.activateTab(currentState);
                n.PageTitle.setSubTitle(this.bsTabs.getTabName(currentState));
                } else {
                this.settings.pageState.setPageState(this.bsTabs.getCurrentTab(), n.PageTitle.get());
                }

                this.bsTabs.on('bootstrap.tab.shown', this.tabShowHandler.bind(this));
                this.settings.pageState.on('pagestate.state.popped', this.popStateHandler.bind(this));
                } catch (e) {
                n.Log.message(e.message);
                this.bsTabs = null;
                }

                try {
                this.qfqForm = new n.QfqForm(
                this.settings.formId,
                this.settings.submitTo,
                this.settings.deleteUrl,
                this.settings.refreshUrl,
                this.settings.fileUploadTo,
                this.settings.fileDeleteUrl);
                this.qfqForm.setBsTabs(this.bsTabs);
                this.qfqForm.on('qfqform.destroyed', this.destroyFormHandler.bind(this));

                var that = this;
                this.qfqForm.on('qfqform.close-intentional', function () {
                that.intentionalClose = true;
                });

                window.addEventListener("beforeunload", this.beforeUnloadHandler.bind(this));
                } catch (e) {
                n.Log.error(e.message);
                this.qfqForm = null;
                }
                };

                /**
                * @private
                */
                n.QfqPage.prototype.beforeUnloadHandler = function (event) {
                var message = "\0/";
                if (this.qfqForm.isFormChanged() && !this.intentionalClose) {

                event.returnValue = message;
                return message;
                }
                };

                /**
                * @private
                */
                n.QfqPage.prototype.destroyFormHandler = function (obj) {
                this.settings.qfqForm = null;
                $('#' + this.settings.tabsId).remove();
                };

                n.QfqPage.prototype.tabShowHandler = function (obj) {
                // tabShowHandler will be called every time the tab will be shown, regardless of whether or not this
                happens
                // because of BSTabs.activateTab() or user interaction.
                //
                // Therefore, we have to make sure, that tabShowHandler() does not save the page state while we're
                restoring
                // a previous state, i.e. we're called because of the popStateHandler() below.
                if (this.settings.pageState.inPoppingHandler) {
                n.Log.debug("Prematurely terminating QfqPage.tabShowHandler(): called due to page state" +
                " restoration.");
                return;
                }
                var currentTabId = obj.target.getCurrentTab();
                n.Log.debug('Saving state: ' + currentTabId);
                n.PageTitle.setSubTitle(obj.target.getTabName(currentTabId));
                this.settings.pageState.setPageState(currentTabId, n.PageTitle.get());
                };

                n.QfqPage.prototype.popStateHandler = function (obj) {
                this.bsTabs.activateTab(obj.target.getPageState());
                n.PageTitle.set(obj.target.getPageData());
                };

                })(QfqNS);