| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- // TODO: This file was created by bulk-decaffeinate.
- // Sanity-check the conversion and remove this comment.
- /*
- * decaffeinate suggestions:
- * DS101: Remove unnecessary use of Array.from
- * DS102: Remove unnecessary code created because of implicit returns
- * DS103: Rewrite code to no longer use __guard__, or convert again using --optional-chaining
- * DS207: Consider shorter variations of null checks
- * DS208: Avoid top-level this
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
- */
- this.app = {
- _$: $,
- _$$: $$,
- _page: page,
- collections: {},
- models: {},
- templates: {},
- views: {},
- init() {
- try { this.initErrorTracking(); } catch (error) {}
- if (!this.browserCheck()) { return; }
- this.el = $('._app');
- this.localStorage = new LocalStorageStore;
- if (app.ServiceWorker.isEnabled()) { this.serviceWorker = new app.ServiceWorker; }
- this.settings = new app.Settings;
- this.db = new app.DB();
- this.settings.initLayout();
- this.docs = new app.collections.Docs;
- this.disabledDocs = new app.collections.Docs;
- this.entries = new app.collections.Entries;
- this.router = new app.Router;
- this.shortcuts = new app.Shortcuts;
- this.document = new app.views.Document;
- if (this.isMobile()) { this.mobile = new app.views.Mobile; }
- if (document.body.hasAttribute('data-doc')) {
- this.DOC = JSON.parse(document.body.getAttribute('data-doc'));
- this.bootOne();
- } else if (this.DOCS) {
- this.bootAll();
- } else {
- this.onBootError();
- }
- },
- browserCheck() {
- if (this.isSupportedBrowser()) { return true; }
- document.body.innerHTML = app.templates.unsupportedBrowser;
- this.hideLoadingScreen();
- return false;
- },
- initErrorTracking() {
- // Show a warning message and don't track errors when the app is loaded
- // from a domain other than our own, because things are likely to break.
- // (e.g. cross-domain requests)
- if (this.isInvalidLocation()) {
- new app.views.Notif('InvalidLocation');
- } else {
- if (this.config.sentry_dsn) {
- Raven.config(this.config.sentry_dsn, {
- release: this.config.release,
- whitelistUrls: [/devdocs/],
- includePaths: [/devdocs/],
- ignoreErrors: [/NPObject/, /NS_ERROR/, /^null$/, /EvalError/],
- tags: {
- mode: this.isSingleDoc() ? 'single' : 'full',
- iframe: (window.top !== window).toString(),
- electron: (!!__guard__(window.process != null ? window.process.versions : undefined, x => x.electron)).toString()
- },
- shouldSendCallback: () => {
- try {
- if (this.isInjectionError()) {
- this.onInjectionError();
- return false;
- }
- if (this.isAndroidWebview()) {
- return false;
- }
- } catch (error) {}
- return true;
- },
- dataCallback(data) {
- try {
- $.extend(data.user || (data.user = {}), app.settings.dump());
- if (data.user.docs) { data.user.docs = data.user.docs.split('/'); }
- if (app.lastIDBTransaction) { data.user.lastIDBTransaction = app.lastIDBTransaction; }
- data.tags.scriptCount = document.scripts.length;
- } catch (error) {}
- return data;
- }
- }).install();
- }
- this.previousErrorHandler = onerror;
- window.onerror = this.onWindowError.bind(this);
- CookiesStore.onBlocked = this.onCookieBlocked;
- }
- },
- bootOne() {
- this.doc = new app.models.Doc(this.DOC);
- this.docs.reset([this.doc]);
- this.doc.load(this.start.bind(this), this.onBootError.bind(this), {readCache: true});
- new app.views.Notice('singleDoc', this.doc);
- delete this.DOC;
- },
- bootAll() {
- const docs = this.settings.getDocs();
- for (var doc of Array.from(this.DOCS)) {
- (docs.indexOf(doc.slug) >= 0 ? this.docs : this.disabledDocs).add(doc);
- }
- this.migrateDocs();
- this.docs.load(this.start.bind(this), this.onBootError.bind(this), {readCache: true, writeCache: true});
- delete this.DOCS;
- },
- start() {
- let doc;
- for (doc of Array.from(this.docs.all())) { this.entries.add(doc.toEntry()); }
- for (doc of Array.from(this.disabledDocs.all())) { this.entries.add(doc.toEntry()); }
- for (doc of Array.from(this.docs.all())) { this.initDoc(doc); }
- this.trigger('ready');
- this.router.start();
- this.hideLoadingScreen();
- setTimeout(() => {
- if (!this.doc) { this.welcomeBack(); }
- return this.removeEvent('ready bootError');
- }
- , 50);
- },
- initDoc(doc) {
- for (var type of Array.from(doc.types.all())) { doc.entries.add(type.toEntry()); }
- this.entries.add(doc.entries.all());
- },
- migrateDocs() {
- let needsSaving;
- for (var slug of Array.from(this.settings.getDocs())) {
- if (!this.docs.findBy('slug', slug)) {var doc;
-
- needsSaving = true;
- if (slug === 'webpack~2') { doc = this.disabledDocs.findBy('slug', 'webpack'); }
- if (slug === 'angular~4_typescript') { doc = this.disabledDocs.findBy('slug', 'angular'); }
- if (slug === 'angular~2_typescript') { doc = this.disabledDocs.findBy('slug', 'angular~2'); }
- if (!doc) { doc = this.disabledDocs.findBy('slug_without_version', slug); }
- if (doc) {
- this.disabledDocs.remove(doc);
- this.docs.add(doc);
- }
- }
- }
- if (needsSaving) { this.saveDocs(); }
- },
- enableDoc(doc, _onSuccess, onError) {
- if (this.docs.contains(doc)) { return; }
- const onSuccess = () => {
- if (this.docs.contains(doc)) { return; }
- this.disabledDocs.remove(doc);
- this.docs.add(doc);
- this.docs.sort();
- this.initDoc(doc);
- this.saveDocs();
- if (app.settings.get('autoInstall')) {
- doc.install(_onSuccess, onError);
- } else {
- _onSuccess();
- }
- };
- doc.load(onSuccess, onError, {writeCache: true});
- },
- saveDocs() {
- this.settings.setDocs(Array.from(this.docs.all()).map((doc) => doc.slug));
- this.db.migrate();
- return (this.serviceWorker != null ? this.serviceWorker.updateInBackground() : undefined);
- },
- welcomeBack() {
- let visitCount = this.settings.get('count');
- this.settings.set('count', ++visitCount);
- if (visitCount === 5) { new app.views.Notif('Share', {autoHide: null}); }
- new app.views.News();
- new app.views.Updates();
- return this.updateChecker = new app.UpdateChecker();
- },
- reboot() {
- if ((location.pathname !== '/') && (location.pathname !== '/settings')) {
- window.location = `/#${location.pathname}`;
- } else {
- window.location = '/';
- }
- },
- reload() {
- this.docs.clearCache();
- this.disabledDocs.clearCache();
- if (this.serviceWorker) { this.serviceWorker.reload(); } else { this.reboot(); }
- },
- reset() {
- this.localStorage.reset();
- this.settings.reset();
- if (this.db != null) {
- this.db.reset();
- }
- if (this.serviceWorker != null) {
- this.serviceWorker.update();
- }
- window.location = '/';
- },
- showTip(tip) {
- if (this.isSingleDoc()) { return; }
- const tips = this.settings.getTips();
- if (tips.indexOf(tip) === -1) {
- tips.push(tip);
- this.settings.setTips(tips);
- new app.views.Tip(tip);
- }
- },
- hideLoadingScreen() {
- if ($.overlayScrollbarsEnabled()) { document.body.classList.add('_overlay-scrollbars'); }
- document.documentElement.classList.remove('_booting');
- },
- indexHost() {
- // Can't load the index files from the host/CDN when service worker is
- // enabled because it doesn't support caching URLs that use CORS.
- return this.config[this.serviceWorker && this.settings.hasDocs() ? 'index_path' : 'docs_origin'];
- },
- onBootError(...args) {
- this.trigger('bootError');
- this.hideLoadingScreen();
- },
- onQuotaExceeded() {
- if (this.quotaExceeded) { return; }
- this.quotaExceeded = true;
- new app.views.Notif('QuotaExceeded', {autoHide: null});
- },
- onCookieBlocked(key, value, actual) {
- if (this.cookieBlocked) { return; }
- this.cookieBlocked = true;
- new app.views.Notif('CookieBlocked', {autoHide: null});
- Raven.captureMessage(`CookieBlocked/${key}`, {level: 'warning', extra: {value, actual}});
- },
- onWindowError(...args) {
- if (this.cookieBlocked) { return; }
- if (this.isInjectionError(...Array.from(args || []))) {
- this.onInjectionError();
- } else if (this.isAppError(...Array.from(args || []))) {
- if (typeof this.previousErrorHandler === 'function') {
- this.previousErrorHandler(...Array.from(args || []));
- }
- this.hideLoadingScreen();
- if (!this.errorNotif) { this.errorNotif = new app.views.Notif('Error'); }
- this.errorNotif.show();
- }
- },
- onInjectionError() {
- if (!this.injectionError) {
- this.injectionError = true;
- alert(`\
- JavaScript code has been injected in the page which prevents DevDocs from running correctly.
- Please check your browser extensions/addons. `
- );
- Raven.captureMessage('injection error', {level: 'info'});
- }
- },
- isInjectionError() {
- // Some browser extensions expect the entire web to use jQuery.
- // I gave up trying to fight back.
- return (window.$ !== app._$) || (window.$$ !== app._$$) || (window.page !== app._page) || (typeof $.empty !== 'function') || (typeof page.show !== 'function');
- },
- isAppError(error, file) {
- // Ignore errors from external scripts.
- return file && (file.indexOf('devdocs') !== -1) && (file.indexOf('.js') === (file.length - 3));
- },
- isSupportedBrowser() {
- try {
- const features = {
- bind: !!Function.prototype.bind,
- pushState: !!history.pushState,
- matchMedia: !!window.matchMedia,
- insertAdjacentHTML: !!document.body.insertAdjacentHTML,
- defaultPrevented: document.createEvent('CustomEvent').defaultPrevented === false,
- cssVariables: !!__guardMethod__(CSS, 'supports', o => o.supports('(--t: 0)'))
- };
- for (var key in features) {
- var value = features[key];
- if (!value) {
- Raven.captureMessage(`unsupported/${key}`, {level: 'info'});
- return false;
- }
- }
- return true;
- } catch (error) {
- Raven.captureMessage('unsupported/exception', {level: 'info', extra: { error }});
- return false;
- }
- },
- isSingleDoc() {
- return document.body.hasAttribute('data-doc');
- },
- isMobile() {
- return this._isMobile != null ? this._isMobile : (this._isMobile = app.views.Mobile.detect());
- },
- isAndroidWebview() {
- return this._isAndroidWebview != null ? this._isAndroidWebview : (this._isAndroidWebview = app.views.Mobile.detectAndroidWebview());
- },
- isInvalidLocation() {
- return (this.config.env === 'production') && (location.host.indexOf(app.config.production_host) !== 0);
- }
- };
- $.extend(app, Events);
- function __guard__(value, transform) {
- return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined;
- }
- function __guardMethod__(obj, methodName, transform) {
- if (typeof obj !== 'undefined' && obj !== null && typeof obj[methodName] === 'function') {
- return transform(obj, methodName);
- } else {
- return undefined;
- }
- }
|