PageSourceSearch

https://www.vb-bo.de/services_cloud/portal/js/hermes.js

js vb-bo.de collected 2026-10-02 19:09:54 UTC 5,762 bytes, 188 lines download raw bytes

1'use strict';
2
3(function (global, factory) {
4  if (typeof define === 'function' && define.amd) {
5    define([], factory);
6  } else {
7    global.hermes = factory();
8  }
9})(window, () => {
10  const callbacks = {};
11
12  function on(name, callback) {
13    if (!(name in callbacks)) {
14      callbacks[name] = [];
15    }
16    callbacks[name].push(callback);
17  }
18
19  function off(name, callback) {
20    if (name in callbacks) {
21      if (typeof callback === 'function') {
22        const index = callbacks[name].indexOf(callback);
23        callbacks[name].splice(index, 1);
24      }
25      if (typeof callback !== 'function' || callbacks[name].length === 0) {
26        delete callbacks[name];
27      }
28    }
29  }
30
31  function broadcast(name, data) {
32    if (name in callbacks) {
33      callbacks[name].forEach(function (callback) {
34        return callback(data);
35      });
36    }
37  }
38
39  function broadcastChannelApiFactory() {
40    /**
41     *  The BroadcastChannel API allows simple communication between
42     *  browsing contexts (including tabs), sort of like a PubSub that
43     *  works across different tabs. This is the ideal solution for
44     *  messaging between different tabs, but it is relatively new.
45     *
46     *  Support table for BroadcastChannel: http://caniuse.com/#feat=broadcastchannel
47     **/
48
49    const channel = new BroadcastChannel('hermes');
50    channel.onmessage = (e) => broadcast(e.data.name, e.data.data);
51
52    function send(name, data, ...args) {
53      const includeSelf =
54        args.length > 2 && args[2] !== undefined ? args[2] : false;
55
56      channel.postMessage({ name: name, data: data });
57      if (includeSelf) {
58        broadcast(name, data);
59      }
60    }
61
62    return { on: on, off: off, send: send };
63  }
64
65  function sharedWorkerApiFactory() {
66    /**
67     *  A SharedWorker is a script that is run by the browser in the
68     *  background. Different browsing contexts (including tabs) from the
69     *  same origin have shared accesss to the SharedWorker instance and
70     *  can communicate with it. We are taking advantage of these features
71     *  to use it as a messaging channel which simply forwards messages it
72     *  receives to the other connected tabs.
73     *
74     *  Support table for SharedWorker: http://caniuse.com/#feat=sharedworkers
75     **/
76
77    const selector = '[src$="hermes.js"],[src$="hermes.min.js"]';
78    const script = document.querySelector(selector);
79    const scriptUrl = new URL(script.src);
80    const workerPath = scriptUrl.pathname.replace(
81      /hermes(\.min)?\.js/,
82      'hermes-worker$1.js',
83    );
84
85    const worker = new SharedWorker(workerPath, 'hermes');
86
87    worker.port.start();
88    worker.port.onmessage = (e) => broadcast(e.data.name, e.data.data);
89
90    function send(name, data, ...args) {
91      const includeSelf =
92        args.length > 2 && args[2] !== undefined ? args[2] : false;
93
94      worker.port.postMessage({ name: name, data: data });
95      if (includeSelf) {
96        broadcast(name, data);
97      }
98    }
99
100    return { on: on, off: off, send: send };
101  }
102
103  function localStorageApiFactory() {
104    /**
105     *  The localStorage is a key-value pair storage, and browser tabs from
106     *  the same origin have shared access to it. Whenever something
107     *  changes in the localStorage, the window object emits the `storage`
108     *  event in the other tabs letting them know about the change.
109     *
110     *  Support table for localStorage: http://caniuse.com/#search=webstorage
111     **/
112
113    const storage = window.localStorage;
114    const prefix = '__hermes:';
115    const queue = {};
116
117    window.addEventListener('storage', function (e) {
118      if (e.key.indexOf(prefix) === 0 && e.oldValue === null) {
119        const name = e.key.replace(prefix, '');
120        const data = JSON.parse(e.newValue);
121        broadcast(name, data);
122      }
123    });
124
125    window.addEventListener('storage', function (e) {
126      if (e.key.indexOf(prefix) === 0 && e.newValue === null) {
127        const name = e.key.replace(prefix, '');
128        if (name in queue) {
129          send(name, queue[name].shift());
130          if (queue[name].length === 0) {
131            delete queue[name];
132          }
133        }
134      }
135    });
136
137    function send(name, data, ...args) {
138      const includeSelf =
139        args.length > 2 && args[2] !== undefined ? args[2] : false;
140
141      const key = prefix + name;
142      if (storage.getItem(key) === null) {
143        storage.setItem(key, JSON.stringify(data));
144        storage.removeItem(key);
145        if (includeSelf) {
146          broadcast(name, data);
147        }
148      } else {
149        // The queueing system ensures that multiple calls to the send
150        // function using the same name does not override each other's
151        // values and makes sure that the next value is sent only when
152        // the previous one has already been deleted from the storage.
153        // NOTE: This could just be trying to solve a problem that is
154        // very unlikely to occur.
155        if ((!key) in queue) {
156          queue[key] = [];
157        }
158        queue[key].push(data);
159      }
160    }
161
162    return { on: on, off: off, send: send };
163  }
164
165  function emptyApiFactory() {
166    /**
167     *  When the browser does not support any of the APIs that we're using
168     *  for messaging, just present an empty api that does just gives
169     *  warnings regarding the lack of support.
170     **/
171
172    function noop() {
173      console.warn('Hermes messaging is not supported.');
174    }
175
176    return { on: noop, off: noop, send: noop };
177  }
178
179  if ('BroadcastChannel' in window) {
180    return broadcastChannelApiFactory();
181  } else if ('SharedWorker' in window) {
182    return sharedWorkerApiFactory();
183  } else if ('localStorage' in window) {
184    return localStorageApiFactory();
185  } else {
186    return emptyApiFactory();
187  }
188});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.