Das Plugin erzeugt einen Button in der Adresszeile. Bei click auf den Button erscheint dieses Popup
16 |
17 |
18 |
default
19 |
20 |
21 |
22 |
disabled
23 |
24 |
25 |
26 |
blacklisted
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/lib/worker_search.js:
--------------------------------------------------------------------------------
1 | if( typeof(importScripts) != 'undefined' ) importScripts("resource://gre/modules/workers/require.js");
2 |
3 | var _ = false;
4 |
5 | onmessage = function(e) {
6 | _ = require(e.data.basedir+'underscore.js');
7 | postMessage(do_search(e.data.names,e.data.bodytext));
8 | }
9 |
10 | function do_search(names,bodytext) {
11 | var stats ={};
12 | var search_start = new Date().getTime();
13 |
14 | var found_names = [];
15 | var searches = 0;
16 | _.each(names,function(person,uid){
17 | _.each(person.names,function(name,nameidx) {
18 | searches++;
19 | var result = bodytext.match(person.regexes[nameidx]);
20 | if( result ) {
21 | found_names.push({uid:uid,name:name});
22 | }
23 | })
24 | });
25 | stop = new Date().getTime();
26 | stats['searchtime'] = (stop-search_start);
27 | stats['hits'] = found_names.length;
28 | stats['searches'] = searches;
29 | return {found_names:found_names,stats:stats};
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012-13 Steve Sobel (honestbleeps)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/Safari.safariextension/worker_search.js:
--------------------------------------------------------------------------------
1 | if( typeof(importScripts) != 'undefined' ) importScripts("resource://gre/modules/workers/require.js");
2 |
3 | var _ = false;
4 |
5 | onmessage = function(e) {
6 | _ = require(e.data.basedir+'underscore.js');
7 | postMessage(do_search(e.data.names,e.data.bodytext));
8 | }
9 |
10 | function do_search(names,bodytext) {
11 | var stats ={};
12 | var search_start = new Date().getTime();
13 |
14 | var found_names = [];
15 | var searches = 0;
16 | _.each(names,function(person,uid){
17 | _.each(person.names,function(name,nameidx) {
18 | searches++;
19 | var result = bodytext.match(person.regexes[nameidx]);
20 | if( result ) {
21 | found_names.push({uid:uid,name:name,result:result});
22 | }
23 | })
24 | });
25 | stop = new Date().getTime();
26 | stats['searchtime'] = (stop-search_start);
27 | stats['hits'] = found_names.length;
28 | stats['searches'] = searches;
29 | console.log((stats['searchtime']/1000).toPrecision(2)+' s');
30 | return {found_names:found_names,stats:stats};
31 | }
32 |
--------------------------------------------------------------------------------
/test/iframe.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | iframe
6 |
7 |
8 |
Hello iframe
9 |
Thomas
10 |
Entwicklung der Braunschen Röhre durch Karl Ferdinand Braun.
11 |
georg
12 |
Karl-August Siepelmeyer
13 |
Hans-Joachim Ahnert
14 |
Hans-Joachim Wolff, Hans Joachim Wolff, Hans-Joachim Wolff
15 |
Karin Schüler
16 |
Klaus-Dieter Rennert
17 |
Reiner Assmann
18 |
Grüne Die Grünen
19 |
Peter Spary
20 |
21 |
22 |
some Orgs
23 |
24 |
Allianz
25 |
Allgemeiner Deutscher Fahrrad-Club (Bundesverband) e.V. - adfc
26 |
Arbeitgebervereinigung Nahrung und Genuß e.V.
27 |
Apotheker in Wissenschaft, Industrie und Verwaltungen (Fachgruppe WIV-Apotheker)
28 |
Arbeitsgemeinschaft Kino - Gilde deutscher Filmkunsttheater e.V AG Kino-Gilde
');
37 | });
38 | $('.lobbyradar_item').click(function(){
39 | var data = {url: detail_url_extern+$('a',this).attr('data-uid')};
40 | self.port.emit('openTab',data);
41 | });
42 |
43 | } else {
44 | $('#nohits').show();
45 | }
46 | }
47 | }
48 | });
49 |
50 | $(function(){
51 | $('#btn_settings').click(function(){
52 | self.port.emit('openPrefs');
53 | });
54 | $('#btn_enable_for_site').click(function(){
55 | self.port.emit('addWhitelist',current_Taburl);
56 | $('.dynamic').hide();
57 | $('#reloadhint').show();
58 | });
59 | $('#btn_disable_for_site').click(function(){
60 | self.port.emit('removeWhitelist',current_Taburl);
61 | $('.dynamic').hide();
62 | $('#reloadhint').show();
63 | });
64 | })
65 |
--------------------------------------------------------------------------------
/lib/local_settings.json.example:
--------------------------------------------------------------------------------
1 | /*
2 | * Local settings
3 | * This contains settings that are specific to an installation,
4 | * Rename this file to 'local_settings.json' before use
5 | * 'localsettings.json' is in .gitignore because it should never go in version control
6 | */
7 | {
8 |
9 | // set this to release to addons.mozilla.org:
10 | amo_login_info: {
11 | username: 'user@example.org',
12 | password: 'password123' // optional - defaults to the environment variable 'AMO_PASSWORD'
13 | },
14 |
15 | // set this to release to the Chrome store:
16 | chrome_login_info: {
17 |
18 | username: 'user@example.org',
19 | password: 'password123', // optional - defaults to the environment variable 'CHROME_PASSWORD'
20 |
21 | // "ID" string in chrome://extensions/:
22 | id: "abcdefghijklmnopqrstuvwxyz012345",
23 |
24 | /*
25 | * Keys for the Chrome WebStore API.
26 | * Follow the instructions here: https://developer.chrome.com/webstore/using_webstore_api
27 | *
28 | * Make sure to get an access token (code) manually once, to make sure it works.
29 | * If you get a 401 error when you try to retrieve the token, go to APIs & auth > Consent screen
30 | * in the Google Developers Console and fill in your email address and product name.
31 | *
32 | * Also make sure to enable the Web Store API by going to APIs & auth > APIs,
33 | * browsing for "Chrome Web Store API" and changing the status to "ON"
34 | */
35 | "client_id" : 'abcdefghijkl-mnopqrstuvwxyz0123456789ABCDEFGH.apps.googleusercontent.com',
36 | "client_secret": "abcdefghijklm-nopqrstuvw",
37 |
38 | },
39 |
40 | // set this to release to the Opera extensions site:
41 | opera_login_info: {
42 | username: 'user@example.org',
43 | password: 'password123', // optional - defaults to the environment variable 'OPERA_PASSWORD'
44 | tested_on: 'Opera 25 Developer Linux' // List of versions you've tested on (see opera://about for your version)
45 | },
46 |
47 | // Command to get the changelog for your latest version.
48 | // At the time of writing, this was required by Opera and hadn't yet been implemented for other browsers:
49 | changelog_command: [ 'git', 'log', '--pretty=* %s', '@{u}..HEAD', '--reverse', '--first-parent' ],
50 |
51 | }
--------------------------------------------------------------------------------
/Chrome/popup/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Lobbyradar Popup
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
');
66 | });
67 | $('.lobbyradar_item').click(function(){
68 |
69 | chrome.tabs.create({url: $('a',this).attr('href')});
70 | });
71 |
72 | } else {
73 | $('#nohits').show();
74 | }
75 | }
76 | }
77 | });
78 | }
79 |
80 | $(function(){
81 | wire_components();
82 | update_content();
83 | });
84 |
--------------------------------------------------------------------------------
/Safari.safariextension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Author
6 | Medieninnovationszentrum Babelsberg MIZ
7 | Builder Version
8 | 10600.5.17
9 | CFBundleDisplayName
10 | Lobbyradar
11 | CFBundleIdentifier
12 | de.miz-babelsberg.lobbyradar
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleShortVersionString
16 | 1.3.4
17 | CFBundleVersion
18 | 1.3.4
19 | Chrome
20 |
21 | Database Quota
22 | 10485760
23 | Global Page
24 | background.html
25 | Popovers
26 |
27 |
28 | Filename
29 | popup/popup.html
30 | Height
31 | 640
32 | Identifier
33 | lobbyradarPopover
34 | Width
35 | 361
36 |
37 |
38 | Toolbar Items
39 |
40 |
41 | Identifier
42 | lobbyradarBtn
43 | Image
44 | lobbyradar-16-mono.png
45 | Label
46 | Lobbyradar
47 | Popover
48 | lobbyradarPopover
49 |
50 |
51 |
52 | Content
53 |
54 | Scripts
55 |
56 | End
57 |
58 | jquery.js
59 | jquery_highlight.js
60 | jquery.tooltipster.js
61 | fg_page.js
62 | moment.js
63 | underscore.js
64 | shariff.min.js
65 |
66 | Start
67 |
68 | BabelExt.js
69 |
70 |
71 | Stylesheets
72 |
73 | style.css
74 | tooltipster.css
75 | shariff.min.css
76 | share-icons.css
77 |
78 |
79 | Description
80 | Discover Lobby Networks
81 | DeveloperIdentifier
82 | 3HQU4WS555
83 | ExtensionInfoDictionaryVersion
84 | 1.0
85 | Permissions
86 |
87 | Website Access
88 |
89 | Allowed Domains
90 |
91 | *
92 |
93 | Include Secure Pages
94 |
95 | Level
96 | Some
97 |
98 |
99 | Website
100 | http://www.lobbyradar.zdf.de
101 |
102 |
103 |
--------------------------------------------------------------------------------
/Chrome/options.js:
--------------------------------------------------------------------------------
1 | // based on https://developer.chrome.com/extensions/options
2 |
3 | function get_preferences() {
4 | var preferences = {};
5 | [].slice.call(document.querySelectorAll('.form-control')).forEach(function(element) {
6 | switch ( element.nodeName ) {
7 | case 'INPUT':
8 | switch ( element.type ) {
9 | case 'checkbox':
10 | if ( element.checked ) {
11 | preferences[element.id] =
12 | element.hasAttribute('data-on') ? parseInt(element.getAttribute('data-on'),10) : true;
13 | } else {
14 | preferences[element.id] =
15 | element.hasAttribute('data-off') ? parseInt(element.getAttribute('data-off'),10) : false;
16 | }
17 | break;
18 | case 'radio' : if ( element.checked ) preferences[element.name] = element.value; break;
19 | case 'number': preferences[element.id] = parseInt(element.value,10); break;
20 | case 'text' : preferences[element.id] = element.value; break;
21 | }
22 | break;
23 | case 'SELECT': preferences[element.id] = element.value; break;
24 | case 'TEXTAREA': preferences[element.id] = element.value.split("\n").join(","); break;
25 | }
26 | });
27 | return preferences;
28 | }
29 |
30 | document.addEventListener('DOMContentLoaded', function() {
31 | chrome.storage.local.get(get_preferences(), function(preferences) {
32 | [].slice.call(document.querySelectorAll('.form-control')).forEach(function(element) {
33 | switch ( element.nodeName ) {
34 | case 'INPUT':
35 | switch ( element.type ) {
36 | case 'checkbox':
37 | element.checked =
38 | preferences[element.id] == ( element.hasAttribute('data-on') ? element.getAttribute('data-on') : true );
39 | break;
40 | case 'radio' : element.checked = preferences[element.name] == element.value; break;
41 | case 'number': element.value = preferences[element.id]; break;
42 | case 'text' : element.value = preferences[element.id]; break;
43 | }
44 | break;
45 | case 'SELECT': element.value = preferences[element.id]; break;
46 | case 'TEXTAREA': element.value = preferences[element.id].split(',').join("\n"); break;
47 | }
48 | });
49 | });
50 | });
51 |
52 | function storePreferences() {
53 | chrome.storage.local.set(get_preferences(), function() {
54 | chrome.runtime.sendMessage({requestType:'optionsChanged'});
55 | });
56 | }
57 | document.addEventListener('click', storePreferences);
58 | document.addEventListener('input', storePreferences);
59 |
60 | $(function(){
61 | moment.locale('de');
62 | chrome.storage.local.get('last_update',function(last_update){
63 | var string_last_update = "noch nie.";
64 | if(last_update.last_update){
65 | string_last_update = moment(last_update.last_update).calendar();
66 | }
67 | $('#updateinterval_help').append(' Letzte Aktualisierung: '+string_last_update);
68 | });
69 | });
70 |
--------------------------------------------------------------------------------
/lib/share-icons.css:
--------------------------------------------------------------------------------
1 | .tooltipster-lobbyradar .shariff .fa-envelope::before,
2 | .tooltipster-lobbyradar .shariff .fa-twitter::before,
3 | .tooltipster-lobbyradar .shariff .fa-facebook::before {
4 | content:'' !important;
5 | }
6 | .tooltipster-lobbyradar .shariff .fa-facebook {
7 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSMnXOqMswAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABU0lEQVRYw+2XMU7DQBBF/99YUFEgeiLgClDsiga4BAdAcBUkLgBHiOAKEQ2xC2joiRAnMDQUIdmhQCIQ7MRLHLNC8xtLY6337czsH5k3aQ8xK6nzY9baNoWHpGxAuPn1nVCeCTx44CLLsqdGAa21KwY4A3gCAgDx8RyLnwHpAmgO0FrbNmAXwNZiSuwmzxom43kFVofjiBKyZ7Jrfg/n39wRiO3QdSF7mnmyR+I42lvsX936jOzlEOlAkH+LDtlvxmaSqX2XyxD7Zjm7j8oHx6YnnTrg5u7BcsCJskYHWKMUsJFL4gdur+BoO+UGidXCNQDMUnod5LUwvZljR0bO15SQnK10Ld4SC+4i70HJ4wYU9KMGFPDx32Wwks3ICAdFNkPitGQWn4vn5Y/4C24XAljkXX7ggFb5LA71Ox11CqiACqiACqiACqiAf6JKv52awSl6B2n9WoEGthpcAAAAAElFTkSuQmCC") !important;
8 | }
9 | .tooltipster-lobbyradar .shariff .fa-twitter {
10 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSQV23xL9AAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACoElEQVRYw+2Yz0obURTGf+eaKEigTcCttOQBpKAL7y620gcQpA9gg/QBtKXrEu0DiIgPYEUfoIi4qePCtKUPEGjdhnZqEcFJvKeL2hRinMxM/mAld5mZzPw49/vO+e7IB++Q27wMt3wNAO88YAqL3GZAwRzKYIvvtgZ7vFzVZrjPM0EfAijyiRrHZtQ76ViD7tyOR31Qy//X7ZIIy0D22kXVbfVlwYx5ZwCuZhdEKKrPzN/fQgFd1WYkxzd1LJu0txkXTuvTa4gstrmtgupHROb/vFRLkj56HU2D95gCsmLYcDW7EKtyNTsXAQ4g34BTXdefUnI1OxcN0DDVKLNhQ2vTb1zVZiLpxrCSoOPlJcevZjlEd7GRV5LjswtsIbR6F3YCyCfoyLM4LTXL6WZAx3GrLZEh9rU+vXYF0upFuSSGUkexWX9tXayX9ntLBzZuoKywwyXvzYj3BcAFtiBD7MejY09S3tPYfVCVVZEQPQmTApOkWNFLC0q5b43aBbZAwBbD+iCiI0GY7N+oE/IywldEZns+z1TL8QGVSqNX9ZpP5DQ2oBn2DnqhqZYrYCtRmlHHch/wKmHzPhTQDHsH6igCfg/1t9dRHjRpb1PrzKC63gtQDWSlozzozu24pNgByYU27WTVWzejRyedVXDUO7nahmyXi+e3q17ksKC+LHXb0aqsRgnDkQDNmHemfkOH3aDbNinvbU+OnS6wBRF9gshsotGmlJtjfXdPdadXMawPcLFOde7CTojReQyLINkkjlVfluLA3QjoanZOhGJTSsmS7CtJRR0vTfpot2tpxqS9XQ14DlpBmE3YYnyclvQHj0za203qp7YmcVWbIcsLgcf/KhkCpfpOVfY7gerMxRd24tq5ox4+8AdftwaA/zPgb0V8C7UUveH2AAAAAElFTkSuQmCC") !important;
11 | }
12 | .tooltipster-lobbyradar .shariff .fa-envelope {
13 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSYHGvNYPgAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACaElEQVRYw+2X0UoUURzGv//Zo4JsFyvsbQU+wLYhwR69cUR6AEt6AIvwAULpWgRfQBEfIDIfwMr1Js9CCeF9EHkrOQRbMM7M+bpwZ1tpzVGnZcE5MDfnZn7M+Z3v+498sHvo1zVhxqFhIOjfRT2h+hjPAf2MByAHvAGAuuvVCWtLEBnr6XU9wVM1bA/TAUK+imCxd3TYx08cpz5iNWA36PAYgN8DuHf04amybV4I6H6Z2y4wlRbkFiN4IPb/X85xWbR9qMq26Y5M0Z2YyS6Ie5I8dHxLknRuNdlz33mLzq0y23XsYj5qvyPkPZJfSLJz//xbLPKckfnojkxRlW1TdGOexEJWvjGCpwbsFgC40MyJRh3AKAAIeD9dzAjGZATf2keu7QpjTF3LS/I1fXhqyB4kaSEK6wBKV83BkmjUXWjmAEAN2l0GqF7JS8dl0Y0niW+MzDaULGYR1CVRWGdYWwIANWwP6cMDuZYSzWeMKRlovAQAF5iKlFCHYDrbJlGyyMhsn/HS4dmFvgWoqkG72/JtRjTqEKQugctVnWBaRvC5I4o2GKHa1UtyjT68pB1avm3+y7esuni05eUMAKghe8Bj3On0ksSC6Mb8H99qr9L4luWwUBKFzbaXZdsUbR8wxhQD3FXariTBf+qbzGY6LFzOy9oofZlTZdtMXAMAd2ImpYA3lz3S7MctkVkpoZ7UlDsyRYa1JSlg57pw1/+CnaFewA5j097IJ+ocMAfMAfsUkJT35wIyxoue/CidT7fW2Uanidqa/c/MloGpQDDSU7gf+PTXn50bZ9cmSUby3MEcMAfMAW8A4G85E2704V7LBQAAAABJRU5ErkJggg==") !important;
14 | }
15 |
--------------------------------------------------------------------------------
/Chrome/share-icons.css:
--------------------------------------------------------------------------------
1 | .tooltipster-lobbyradar .shariff .fa-envelope::before,
2 | .tooltipster-lobbyradar .shariff .fa-twitter::before,
3 | .tooltipster-lobbyradar .shariff .fa-facebook::before {
4 | content:'' !important;
5 | }
6 | .tooltipster-lobbyradar .shariff .fa-facebook {
7 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSMnXOqMswAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABU0lEQVRYw+2XMU7DQBBF/99YUFEgeiLgClDsiga4BAdAcBUkLgBHiOAKEQ2xC2joiRAnMDQUIdmhQCIQ7MRLHLNC8xtLY6337czsH5k3aQ8xK6nzY9baNoWHpGxAuPn1nVCeCTx44CLLsqdGAa21KwY4A3gCAgDx8RyLnwHpAmgO0FrbNmAXwNZiSuwmzxom43kFVofjiBKyZ7Jrfg/n39wRiO3QdSF7mnmyR+I42lvsX936jOzlEOlAkH+LDtlvxmaSqX2XyxD7Zjm7j8oHx6YnnTrg5u7BcsCJskYHWKMUsJFL4gdur+BoO+UGidXCNQDMUnod5LUwvZljR0bO15SQnK10Ld4SC+4i70HJ4wYU9KMGFPDx32Wwks3ICAdFNkPitGQWn4vn5Y/4C24XAljkXX7ggFb5LA71Ox11CqiACqiACqiACqiAf6JKv52awSl6B2n9WoEGthpcAAAAAElFTkSuQmCC") !important;
8 | }
9 | .tooltipster-lobbyradar .shariff .fa-twitter {
10 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSQV23xL9AAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACoElEQVRYw+2Yz0obURTGf+eaKEigTcCttOQBpKAL7y620gcQpA9gg/QBtKXrEu0DiIgPYEUfoIi4qePCtKUPEGjdhnZqEcFJvKeL2hRinMxM/mAld5mZzPw49/vO+e7IB++Q27wMt3wNAO88YAqL3GZAwRzKYIvvtgZ7vFzVZrjPM0EfAijyiRrHZtQ76ViD7tyOR31Qy//X7ZIIy0D22kXVbfVlwYx5ZwCuZhdEKKrPzN/fQgFd1WYkxzd1LJu0txkXTuvTa4gstrmtgupHROb/vFRLkj56HU2D95gCsmLYcDW7EKtyNTsXAQ4g34BTXdefUnI1OxcN0DDVKLNhQ2vTb1zVZiLpxrCSoOPlJcevZjlEd7GRV5LjswtsIbR6F3YCyCfoyLM4LTXL6WZAx3GrLZEh9rU+vXYF0upFuSSGUkexWX9tXayX9ntLBzZuoKywwyXvzYj3BcAFtiBD7MejY09S3tPYfVCVVZEQPQmTApOkWNFLC0q5b43aBbZAwBbD+iCiI0GY7N+oE/IywldEZns+z1TL8QGVSqNX9ZpP5DQ2oBn2DnqhqZYrYCtRmlHHch/wKmHzPhTQDHsH6igCfg/1t9dRHjRpb1PrzKC63gtQDWSlozzozu24pNgByYU27WTVWzejRyedVXDUO7nahmyXi+e3q17ksKC+LHXb0aqsRgnDkQDNmHemfkOH3aDbNinvbU+OnS6wBRF9gshsotGmlJtjfXdPdadXMawPcLFOde7CTojReQyLINkkjlVfluLA3QjoanZOhGJTSsmS7CtJRR0vTfpot2tpxqS9XQ14DlpBmE3YYnyclvQHj0za203qp7YmcVWbIcsLgcf/KhkCpfpOVfY7gerMxRd24tq5ox4+8AdftwaA/zPgb0V8C7UUveH2AAAAAElFTkSuQmCC") !important;
11 | }
12 | .tooltipster-lobbyradar .shariff .fa-envelope {
13 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSYHGvNYPgAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACaElEQVRYw+2X0UoUURzGv//Zo4JsFyvsbQU+wLYhwR69cUR6AEt6AIvwAULpWgRfQBEfIDIfwMr1Js9CCeF9EHkrOQRbMM7M+bpwZ1tpzVGnZcE5MDfnZn7M+Z3v+498sHvo1zVhxqFhIOjfRT2h+hjPAf2MByAHvAGAuuvVCWtLEBnr6XU9wVM1bA/TAUK+imCxd3TYx08cpz5iNWA36PAYgN8DuHf04amybV4I6H6Z2y4wlRbkFiN4IPb/X85xWbR9qMq26Y5M0Z2YyS6Ie5I8dHxLknRuNdlz33mLzq0y23XsYj5qvyPkPZJfSLJz//xbLPKckfnojkxRlW1TdGOexEJWvjGCpwbsFgC40MyJRh3AKAAIeD9dzAjGZATf2keu7QpjTF3LS/I1fXhqyB4kaSEK6wBKV83BkmjUXWjmAEAN2l0GqF7JS8dl0Y0niW+MzDaULGYR1CVRWGdYWwIANWwP6cMDuZYSzWeMKRlovAQAF5iKlFCHYDrbJlGyyMhsn/HS4dmFvgWoqkG72/JtRjTqEKQugctVnWBaRvC5I4o2GKHa1UtyjT68pB1avm3+y7esuni05eUMAKghe8Bj3On0ksSC6Mb8H99qr9L4luWwUBKFzbaXZdsUbR8wxhQD3FXariTBf+qbzGY6LFzOy9oofZlTZdtMXAMAd2ImpYA3lz3S7MctkVkpoZ7UlDsyRYa1JSlg57pw1/+CnaFewA5j097IJ+ocMAfMAfsUkJT35wIyxoue/CidT7fW2Uanidqa/c/MloGpQDDSU7gf+PTXn50bZ9cmSUby3MEcMAfMAW8A4G85E2704V7LBQAAAABJRU5ErkJggg==") !important;
14 | }
15 |
--------------------------------------------------------------------------------
/Firefox/data/share-icons.css:
--------------------------------------------------------------------------------
1 | .tooltipster-lobbyradar .shariff .fa-envelope::before,
2 | .tooltipster-lobbyradar .shariff .fa-twitter::before,
3 | .tooltipster-lobbyradar .shariff .fa-facebook::before {
4 | content:'' !important;
5 | }
6 | .tooltipster-lobbyradar .shariff .fa-facebook {
7 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSMnXOqMswAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABU0lEQVRYw+2XMU7DQBBF/99YUFEgeiLgClDsiga4BAdAcBUkLgBHiOAKEQ2xC2joiRAnMDQUIdmhQCIQ7MRLHLNC8xtLY6337czsH5k3aQ8xK6nzY9baNoWHpGxAuPn1nVCeCTx44CLLsqdGAa21KwY4A3gCAgDx8RyLnwHpAmgO0FrbNmAXwNZiSuwmzxom43kFVofjiBKyZ7Jrfg/n39wRiO3QdSF7mnmyR+I42lvsX936jOzlEOlAkH+LDtlvxmaSqX2XyxD7Zjm7j8oHx6YnnTrg5u7BcsCJskYHWKMUsJFL4gdur+BoO+UGidXCNQDMUnod5LUwvZljR0bO15SQnK10Ld4SC+4i70HJ4wYU9KMGFPDx32Wwks3ICAdFNkPitGQWn4vn5Y/4C24XAljkXX7ggFb5LA71Ox11CqiACqiACqiACqiAf6JKv52awSl6B2n9WoEGthpcAAAAAElFTkSuQmCC") !important;
8 | }
9 | .tooltipster-lobbyradar .shariff .fa-twitter {
10 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSQV23xL9AAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACoElEQVRYw+2Yz0obURTGf+eaKEigTcCttOQBpKAL7y620gcQpA9gg/QBtKXrEu0DiIgPYEUfoIi4qePCtKUPEGjdhnZqEcFJvKeL2hRinMxM/mAld5mZzPw49/vO+e7IB++Q27wMt3wNAO88YAqL3GZAwRzKYIvvtgZ7vFzVZrjPM0EfAijyiRrHZtQ76ViD7tyOR31Qy//X7ZIIy0D22kXVbfVlwYx5ZwCuZhdEKKrPzN/fQgFd1WYkxzd1LJu0txkXTuvTa4gstrmtgupHROb/vFRLkj56HU2D95gCsmLYcDW7EKtyNTsXAQ4g34BTXdefUnI1OxcN0DDVKLNhQ2vTb1zVZiLpxrCSoOPlJcevZjlEd7GRV5LjswtsIbR6F3YCyCfoyLM4LTXL6WZAx3GrLZEh9rU+vXYF0upFuSSGUkexWX9tXayX9ntLBzZuoKywwyXvzYj3BcAFtiBD7MejY09S3tPYfVCVVZEQPQmTApOkWNFLC0q5b43aBbZAwBbD+iCiI0GY7N+oE/IywldEZns+z1TL8QGVSqNX9ZpP5DQ2oBn2DnqhqZYrYCtRmlHHch/wKmHzPhTQDHsH6igCfg/1t9dRHjRpb1PrzKC63gtQDWSlozzozu24pNgByYU27WTVWzejRyedVXDUO7nahmyXi+e3q17ksKC+LHXb0aqsRgnDkQDNmHemfkOH3aDbNinvbU+OnS6wBRF9gshsotGmlJtjfXdPdadXMawPcLFOde7CTojReQyLINkkjlVfluLA3QjoanZOhGJTSsmS7CtJRR0vTfpot2tpxqS9XQ14DlpBmE3YYnyclvQHj0za203qp7YmcVWbIcsLgcf/KhkCpfpOVfY7gerMxRd24tq5ox4+8AdftwaA/zPgb0V8C7UUveH2AAAAAElFTkSuQmCC") !important;
11 | }
12 | .tooltipster-lobbyradar .shariff .fa-envelope {
13 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSYHGvNYPgAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACaElEQVRYw+2X0UoUURzGv//Zo4JsFyvsbQU+wLYhwR69cUR6AEt6AIvwAULpWgRfQBEfIDIfwMr1Js9CCeF9EHkrOQRbMM7M+bpwZ1tpzVGnZcE5MDfnZn7M+Z3v+498sHvo1zVhxqFhIOjfRT2h+hjPAf2MByAHvAGAuuvVCWtLEBnr6XU9wVM1bA/TAUK+imCxd3TYx08cpz5iNWA36PAYgN8DuHf04amybV4I6H6Z2y4wlRbkFiN4IPb/X85xWbR9qMq26Y5M0Z2YyS6Ie5I8dHxLknRuNdlz33mLzq0y23XsYj5qvyPkPZJfSLJz//xbLPKckfnojkxRlW1TdGOexEJWvjGCpwbsFgC40MyJRh3AKAAIeD9dzAjGZATf2keu7QpjTF3LS/I1fXhqyB4kaSEK6wBKV83BkmjUXWjmAEAN2l0GqF7JS8dl0Y0niW+MzDaULGYR1CVRWGdYWwIANWwP6cMDuZYSzWeMKRlovAQAF5iKlFCHYDrbJlGyyMhsn/HS4dmFvgWoqkG72/JtRjTqEKQugctVnWBaRvC5I4o2GKHa1UtyjT68pB1avm3+y7esuni05eUMAKghe8Bj3On0ksSC6Mb8H99qr9L4luWwUBKFzbaXZdsUbR8wxhQD3FXariTBf+qbzGY6LFzOy9oofZlTZdtMXAMAd2ImpYA3lz3S7MctkVkpoZ7UlDsyRYa1JSlg57pw1/+CnaFewA5j097IJ+ocMAfMAfsUkJT35wIyxoue/CidT7fW2Uanidqa/c/MloGpQDDSU7gf+PTXn50bZ9cmSUby3MEcMAfMAW8A4G85E2704V7LBQAAAABJRU5ErkJggg==") !important;
14 | }
15 |
--------------------------------------------------------------------------------
/Safari.safariextension/share-icons.css:
--------------------------------------------------------------------------------
1 | .tooltipster-lobbyradar .shariff .fa-envelope::before,
2 | .tooltipster-lobbyradar .shariff .fa-twitter::before,
3 | .tooltipster-lobbyradar .shariff .fa-facebook::before {
4 | content:'' !important;
5 | }
6 | .tooltipster-lobbyradar .shariff .fa-facebook {
7 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSMnXOqMswAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABU0lEQVRYw+2XMU7DQBBF/99YUFEgeiLgClDsiga4BAdAcBUkLgBHiOAKEQ2xC2joiRAnMDQUIdmhQCIQ7MRLHLNC8xtLY6337czsH5k3aQ8xK6nzY9baNoWHpGxAuPn1nVCeCTx44CLLsqdGAa21KwY4A3gCAgDx8RyLnwHpAmgO0FrbNmAXwNZiSuwmzxom43kFVofjiBKyZ7Jrfg/n39wRiO3QdSF7mnmyR+I42lvsX936jOzlEOlAkH+LDtlvxmaSqX2XyxD7Zjm7j8oHx6YnnTrg5u7BcsCJskYHWKMUsJFL4gdur+BoO+UGidXCNQDMUnod5LUwvZljR0bO15SQnK10Ld4SC+4i70HJ4wYU9KMGFPDx32Wwks3ICAdFNkPitGQWn4vn5Y/4C24XAljkXX7ggFb5LA71Ox11CqiACqiACqiACqiAf6JKv52awSl6B2n9WoEGthpcAAAAAElFTkSuQmCC") !important;
8 | }
9 | .tooltipster-lobbyradar .shariff .fa-twitter {
10 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSQV23xL9AAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACoElEQVRYw+2Yz0obURTGf+eaKEigTcCttOQBpKAL7y620gcQpA9gg/QBtKXrEu0DiIgPYEUfoIi4qePCtKUPEGjdhnZqEcFJvKeL2hRinMxM/mAld5mZzPw49/vO+e7IB++Q27wMt3wNAO88YAqL3GZAwRzKYIvvtgZ7vFzVZrjPM0EfAijyiRrHZtQ76ViD7tyOR31Qy//X7ZIIy0D22kXVbfVlwYx5ZwCuZhdEKKrPzN/fQgFd1WYkxzd1LJu0txkXTuvTa4gstrmtgupHROb/vFRLkj56HU2D95gCsmLYcDW7EKtyNTsXAQ4g34BTXdefUnI1OxcN0DDVKLNhQ2vTb1zVZiLpxrCSoOPlJcevZjlEd7GRV5LjswtsIbR6F3YCyCfoyLM4LTXL6WZAx3GrLZEh9rU+vXYF0upFuSSGUkexWX9tXayX9ntLBzZuoKywwyXvzYj3BcAFtiBD7MejY09S3tPYfVCVVZEQPQmTApOkWNFLC0q5b43aBbZAwBbD+iCiI0GY7N+oE/IywldEZns+z1TL8QGVSqNX9ZpP5DQ2oBn2DnqhqZYrYCtRmlHHch/wKmHzPhTQDHsH6igCfg/1t9dRHjRpb1PrzKC63gtQDWSlozzozu24pNgByYU27WTVWzejRyedVXDUO7nahmyXi+e3q17ksKC+LHXb0aqsRgnDkQDNmHemfkOH3aDbNinvbU+OnS6wBRF9gshsotGmlJtjfXdPdadXMawPcLFOde7CTojReQyLINkkjlVfluLA3QjoanZOhGJTSsmS7CtJRR0vTfpot2tpxqS9XQ14DlpBmE3YYnyclvQHj0za203qp7YmcVWbIcsLgcf/KhkCpfpOVfY7gerMxRd24tq5ox4+8AdftwaA/zPgb0V8C7UUveH2AAAAAElFTkSuQmCC") !important;
11 | }
12 | .tooltipster-lobbyradar .shariff .fa-envelope {
13 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3wQYDSYHGvNYPgAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACaElEQVRYw+2X0UoUURzGv//Zo4JsFyvsbQU+wLYhwR69cUR6AEt6AIvwAULpWgRfQBEfIDIfwMr1Js9CCeF9EHkrOQRbMM7M+bpwZ1tpzVGnZcE5MDfnZn7M+Z3v+498sHvo1zVhxqFhIOjfRT2h+hjPAf2MByAHvAGAuuvVCWtLEBnr6XU9wVM1bA/TAUK+imCxd3TYx08cpz5iNWA36PAYgN8DuHf04amybV4I6H6Z2y4wlRbkFiN4IPb/X85xWbR9qMq26Y5M0Z2YyS6Ie5I8dHxLknRuNdlz33mLzq0y23XsYj5qvyPkPZJfSLJz//xbLPKckfnojkxRlW1TdGOexEJWvjGCpwbsFgC40MyJRh3AKAAIeD9dzAjGZATf2keu7QpjTF3LS/I1fXhqyB4kaSEK6wBKV83BkmjUXWjmAEAN2l0GqF7JS8dl0Y0niW+MzDaULGYR1CVRWGdYWwIANWwP6cMDuZYSzWeMKRlovAQAF5iKlFCHYDrbJlGyyMhsn/HS4dmFvgWoqkG72/JtRjTqEKQugctVnWBaRvC5I4o2GKHa1UtyjT68pB1avm3+y7esuni05eUMAKghe8Bj3On0ksSC6Mb8H99qr9L4luWwUBKFzbaXZdsUbR8wxhQD3FXariTBf+qbzGY6LFzOy9oofZlTZdtMXAMAd2ImpYA3lz3S7MctkVkpoZ7UlDsyRYa1JSlg57pw1/+CnaFewA5j097IJ+ocMAfMAfsUkJT35wIyxoue/CidT7fW2Uanidqa/c/MloGpQDDSU7gf+PTXn50bZ9cmSUby3MEcMAfMAW8A4G85E2704V7LBQAAAABJRU5ErkJggg==") !important;
14 | }
15 |
--------------------------------------------------------------------------------
/lib/bg_common.js:
--------------------------------------------------------------------------------
1 |
2 | // True in Safari, false in Chrome.
3 | SAFARI = (function() {
4 | if (typeof safari === "undefined" && typeof chrome === "undefined") {
5 | // Safari bug: window.safari undefined in iframes with JS src in them.
6 | // Must get it from an ancestor.
7 | var w = window;
8 | while (w.safari === undefined && w !== window.top) {
9 | w = w.parent;
10 | }
11 | window.safari = w.safari;
12 | }
13 | return (typeof safari !== "undefined");
14 | })();
15 |
16 | var parseURL = function(url) {
17 | var parser = document.createElement('a'),
18 | searchObject = {},
19 | queries, split, i;
20 | // Let the browser do the work
21 | parser.href = url;
22 |
23 | return {
24 | protocol: parser.protocol,
25 | host: parser.host,
26 | hostname: parser.hostname,
27 | port: parser.port,
28 | pathname: parser.pathname,
29 | search: parser.search,
30 | hash: parser.hash
31 | };
32 | }
33 |
34 | var getCurrentTabInfo = function(callback, secondTime) {
35 | if (!SAFARI) {
36 | console.log('getCurrentTabInfo');
37 | chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
38 | if (tabs.length === 0) {
39 | console.log('no tabs open?');
40 | return; // For example: only the background devtools or a popup are opened
41 | }
42 |
43 | var tab = tabs[0];
44 |
45 | if (tab && !tab.url) {
46 | // Issue 6877: tab URL is not set directly after you opened a window
47 | // using window.open()
48 | if (!secondTime)
49 | window.setTimeout(function() {
50 | getCurrentTabInfo(callback, true);
51 | }, 250);
52 | return;
53 | }
54 |
55 |
56 | var result = {
57 | tab: tab,
58 | value: tabData.get(tab.id)
59 | };
60 | if(!result.value) {
61 | result.value={state:'search'}
62 | }
63 |
64 | callback(result);
65 | });
66 | } else {
67 | var browserWindow = safari.application.activeBrowserWindow;
68 | var tab = browserWindow.activeTab;
69 | tab.id=_.indexOf(safari.application.activeBrowserWindow.tabs,tab);
70 |
71 | var result = {
72 | tab: tab,
73 | value: tabData.get(tab.id)
74 | };
75 |
76 | callback(result);
77 | }
78 | }
79 |
80 | function get_extension_setting(key,callback){
81 | if(!callback) callback = function(){};
82 | if( SAFARI ) {
83 | return callback(safari.extension.settings[key]);
84 | } else {
85 | chrome.storage.local.get(key, function(result){
86 | callback(result[key]);
87 | });
88 | }
89 | }
90 | function set_extension_setting(key,value,callback){
91 | if(!callback) callback = function(){};
92 | if( SAFARI ) {
93 | safari.extension.settings[key] = value;
94 | return callback(value);
95 | } else {
96 | var json = {};
97 | json[key]=value;
98 | chrome.storage.local.set(json, callback);
99 | }
100 | }
101 |
102 | function get_localstorage(key,callback) {
103 | if(!callback) callback = function(){};
104 | if( SAFARI ) {
105 | return callback(localStorage.getItem(key));
106 | } else {
107 | chrome.storage.local.get(key, function(result){
108 | callback(result[key]);
109 | });
110 | }
111 | }
112 | function set_localstorage(key,value,callback){
113 | if(!callback) callback = function(){};
114 | if( SAFARI ) {
115 | localStorage.setItem(key,value);
116 | return callback(value);
117 | } else {
118 | var json = {};
119 | json[key]=value;
120 | chrome.storage.local.set(json, callback);
121 | }
122 | }
123 |
124 | function replaceUmlauts(string)
125 | {
126 | return string.replace(/\u00e4|\u00c4/g, 'a')
127 | .replace(/\u00f6|\u00d6/g, 'o')
128 | .replace(/\u00fc|\u00dc/g, 'u');
129 | }
130 |
--------------------------------------------------------------------------------
/Chrome/bg_common.js:
--------------------------------------------------------------------------------
1 |
2 | // True in Safari, false in Chrome.
3 | SAFARI = (function() {
4 | if (typeof safari === "undefined" && typeof chrome === "undefined") {
5 | // Safari bug: window.safari undefined in iframes with JS src in them.
6 | // Must get it from an ancestor.
7 | var w = window;
8 | while (w.safari === undefined && w !== window.top) {
9 | w = w.parent;
10 | }
11 | window.safari = w.safari;
12 | }
13 | return (typeof safari !== "undefined");
14 | })();
15 |
16 | var parseURL = function(url) {
17 | var parser = document.createElement('a'),
18 | searchObject = {},
19 | queries, split, i;
20 | // Let the browser do the work
21 | parser.href = url;
22 |
23 | return {
24 | protocol: parser.protocol,
25 | host: parser.host,
26 | hostname: parser.hostname,
27 | port: parser.port,
28 | pathname: parser.pathname,
29 | search: parser.search,
30 | hash: parser.hash
31 | };
32 | }
33 |
34 | var getCurrentTabInfo = function(callback, secondTime) {
35 | if (!SAFARI) {
36 | console.log('getCurrentTabInfo');
37 | chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
38 | if (tabs.length === 0) {
39 | console.log('no tabs open?');
40 | return; // For example: only the background devtools or a popup are opened
41 | }
42 |
43 | var tab = tabs[0];
44 |
45 | if (tab && !tab.url) {
46 | // Issue 6877: tab URL is not set directly after you opened a window
47 | // using window.open()
48 | if (!secondTime)
49 | window.setTimeout(function() {
50 | getCurrentTabInfo(callback, true);
51 | }, 250);
52 | return;
53 | }
54 |
55 |
56 | var result = {
57 | tab: tab,
58 | value: tabData.get(tab.id)
59 | };
60 | if(!result.value) {
61 | result.value={state:'search'}
62 | }
63 |
64 | callback(result);
65 | });
66 | } else {
67 | var browserWindow = safari.application.activeBrowserWindow;
68 | var tab = browserWindow.activeTab;
69 | tab.id=_.indexOf(safari.application.activeBrowserWindow.tabs,tab);
70 |
71 | var result = {
72 | tab: tab,
73 | value: tabData.get(tab.id)
74 | };
75 |
76 | callback(result);
77 | }
78 | }
79 |
80 | function get_extension_setting(key,callback){
81 | if(!callback) callback = function(){};
82 | if( SAFARI ) {
83 | return callback(safari.extension.settings[key]);
84 | } else {
85 | chrome.storage.local.get(key, function(result){
86 | callback(result[key]);
87 | });
88 | }
89 | }
90 | function set_extension_setting(key,value,callback){
91 | if(!callback) callback = function(){};
92 | if( SAFARI ) {
93 | safari.extension.settings[key] = value;
94 | return callback(value);
95 | } else {
96 | var json = {};
97 | json[key]=value;
98 | chrome.storage.local.set(json, callback);
99 | }
100 | }
101 |
102 | function get_localstorage(key,callback) {
103 | if(!callback) callback = function(){};
104 | if( SAFARI ) {
105 | return callback(localStorage.getItem(key));
106 | } else {
107 | chrome.storage.local.get(key, function(result){
108 | callback(result[key]);
109 | });
110 | }
111 | }
112 | function set_localstorage(key,value,callback){
113 | if(!callback) callback = function(){};
114 | if( SAFARI ) {
115 | localStorage.setItem(key,value);
116 | return callback(value);
117 | } else {
118 | var json = {};
119 | json[key]=value;
120 | chrome.storage.local.set(json, callback);
121 | }
122 | }
123 |
124 | function replaceUmlauts(string)
125 | {
126 | return string.replace(/\u00e4|\u00c4/g, 'a')
127 | .replace(/\u00f6|\u00d6/g, 'o')
128 | .replace(/\u00fc|\u00dc/g, 'u');
129 | }
130 |
--------------------------------------------------------------------------------
/Safari.safariextension/bg_common.js:
--------------------------------------------------------------------------------
1 |
2 | // True in Safari, false in Chrome.
3 | SAFARI = (function() {
4 | if (typeof safari === "undefined" && typeof chrome === "undefined") {
5 | // Safari bug: window.safari undefined in iframes with JS src in them.
6 | // Must get it from an ancestor.
7 | var w = window;
8 | while (w.safari === undefined && w !== window.top) {
9 | w = w.parent;
10 | }
11 | window.safari = w.safari;
12 | }
13 | return (typeof safari !== "undefined");
14 | })();
15 |
16 | var parseURL = function(url) {
17 | var parser = document.createElement('a'),
18 | searchObject = {},
19 | queries, split, i;
20 | // Let the browser do the work
21 | parser.href = url;
22 |
23 | return {
24 | protocol: parser.protocol,
25 | host: parser.host,
26 | hostname: parser.hostname,
27 | port: parser.port,
28 | pathname: parser.pathname,
29 | search: parser.search,
30 | hash: parser.hash
31 | };
32 | }
33 |
34 | var getCurrentTabInfo = function(callback, secondTime) {
35 | if (!SAFARI) {
36 | console.log('getCurrentTabInfo');
37 | chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
38 | if (tabs.length === 0) {
39 | console.log('no tabs open?');
40 | return; // For example: only the background devtools or a popup are opened
41 | }
42 |
43 | var tab = tabs[0];
44 |
45 | if (tab && !tab.url) {
46 | // Issue 6877: tab URL is not set directly after you opened a window
47 | // using window.open()
48 | if (!secondTime)
49 | window.setTimeout(function() {
50 | getCurrentTabInfo(callback, true);
51 | }, 250);
52 | return;
53 | }
54 |
55 |
56 | var result = {
57 | tab: tab,
58 | value: tabData.get(tab.id)
59 | };
60 | if(!result.value) {
61 | result.value={state:'search'}
62 | }
63 |
64 | callback(result);
65 | });
66 | } else {
67 | var browserWindow = safari.application.activeBrowserWindow;
68 | var tab = browserWindow.activeTab;
69 | tab.id=_.indexOf(safari.application.activeBrowserWindow.tabs,tab);
70 |
71 | var result = {
72 | tab: tab,
73 | value: tabData.get(tab.id)
74 | };
75 |
76 | callback(result);
77 | }
78 | }
79 |
80 | function get_extension_setting(key,callback){
81 | if(!callback) callback = function(){};
82 | if( SAFARI ) {
83 | return callback(safari.extension.settings[key]);
84 | } else {
85 | chrome.storage.local.get(key, function(result){
86 | callback(result[key]);
87 | });
88 | }
89 | }
90 | function set_extension_setting(key,value,callback){
91 | if(!callback) callback = function(){};
92 | if( SAFARI ) {
93 | safari.extension.settings[key] = value;
94 | return callback(value);
95 | } else {
96 | var json = {};
97 | json[key]=value;
98 | chrome.storage.local.set(json, callback);
99 | }
100 | }
101 |
102 | function get_localstorage(key,callback) {
103 | if(!callback) callback = function(){};
104 | if( SAFARI ) {
105 | return callback(localStorage.getItem(key));
106 | } else {
107 | chrome.storage.local.get(key, function(result){
108 | callback(result[key]);
109 | });
110 | }
111 | }
112 | function set_localstorage(key,value,callback){
113 | if(!callback) callback = function(){};
114 | if( SAFARI ) {
115 | localStorage.setItem(key,value);
116 | return callback(value);
117 | } else {
118 | var json = {};
119 | json[key]=value;
120 | chrome.storage.local.set(json, callback);
121 | }
122 | }
123 |
124 | function replaceUmlauts(string)
125 | {
126 | return string.replace(/\u00e4|\u00c4/g, 'a')
127 | .replace(/\u00f6|\u00d6/g, 'o')
128 | .replace(/\u00fc|\u00dc/g, 'u');
129 | }
130 |
--------------------------------------------------------------------------------
/Firefox/lib/bg_browserbutton.js:
--------------------------------------------------------------------------------
1 | var { on, once, off, emit } = require('sdk/event/core');
2 | var panels = require("sdk/panel");
3 | var self = require("sdk/self");
4 | var { ToggleButton } = require("sdk/ui/button/toggle");
5 | var settings = require("./settings.js");
6 | var tabs = require('sdk/tabs');
7 | var { setTimeout } = require("sdk/timers");
8 | var lobbyradar_tools = require('bg_common').lobbyradar_tools;
9 |
10 | var ToolbarButton = false;
11 | var tabData = false;
12 | var activeTab = false;
13 | var panelsizes = { small:{w:361,h:250},
14 | big:{w:361,h:640}
15 | };
16 | exports.buttonfunctions = {
17 | initialize: function(global_tabData){
18 | ToolbarButton = ToggleButton({
19 | id: "lobbyradarBtn",
20 | label: "Lobbyradar",
21 | icon: {
22 | "16": './'+settings.icons[16],
23 | "32": './'+settings.icons[32]
24 | },
25 | onChange: function(state) { if (state.checked) {
26 | var activeSize = panelsizes.small;
27 | if(state.badge && state.badge != '0' && state.badge != '+++' && state.badge != '...') activeSize = panelsizes.big;
28 | panel.show({ position: ToolbarButton ,
29 | height: activeSize.h,
30 | width : activeSize.w
31 | });
32 | }
33 | },
34 | badgeColor:'#143B52'
35 | });
36 | tabData = global_tabData;
37 | },
38 | updateBrowserButton: function( tab ) {
39 | var storedTabdata = tabData.get(tab.id);
40 | storedTabdata.stage='done';
41 | tabData.set(tab.id,storedTabdata);
42 | if(storedTabdata && storedTabdata.hits) {
43 | ToolbarButton.state(tab,{ badge:storedTabdata.hits.length.toString() } );
44 | panel.resize( panelsizes.big.w,panelsizes.big.h);
45 | } else {
46 | if( storedTabdata && !storedTabdata.disabled ) {
47 | ToolbarButton.state(tab,{ badge:'0' } );
48 | } else {
49 | ToolbarButton.state(tab,{ badge:'' } );
50 | }
51 | }
52 | },
53 | setBrowserButton_searching: function( tab ) {
54 | var storedTabdata = tabData.get(tab.id);
55 | storedTabdata.stage='search';
56 | tabData.set(tab.id,storedTabdata);
57 | ToolbarButton.state(tab,{ badge:'...' } );
58 | panel.resize( panelsizes.small.w,panelsizes.small.h);
59 | },
60 | setBrowserButton_waiting: function( tab ) {
61 | var storedTabdata = tabData.get(tab.id);
62 | storedTabdata.stage='mark';
63 | tabData.set(tab.id,storedTabdata);
64 | ToolbarButton.state(tab,{ badge:'+++' } );
65 | panel.resize( panelsizes.small.w,panelsizes.small.h);
66 | }
67 | }
68 |
69 | var panel = panels.Panel({
70 | contentURL: self.data.url("popup/popup.html"),
71 | contentScriptFile: [self.data.url("jquery.js"),self.data.url("popup/popup_firefox.js")],
72 | onHide: function(){ToolbarButton.state('window', {checked: false});}
73 | });
74 |
75 | // das tabData-Objekt wird hier nur als Anker für die Events verwendet
76 | panel.port.on('addWhitelist',function(url){
77 | emit(tabData,'addWhitelist',lobbyradar_tools.parseURL(url).hostname);
78 | });
79 | panel.port.on('removeWhitelist',function(url){
80 | emit(tabData,'removeWhitelist',lobbyradar_tools.parseURL(url).hostname);
81 | });
82 | panel.port.on('openPrefs',function(){
83 | emit(tabData,'openPrefs');
84 | });
85 | panel.port.on('openTab',function(data){
86 | emit(tabData,'openTab',data);
87 | });
88 |
89 | function makeTabObject() {
90 | return {
91 | tab: { url: tabs.activeTab.url },
92 | value: tabData.get(tabs.activeTab.id)
93 | }
94 | }
95 |
96 | function sendTabdata() {
97 | var tabdata = makeTabObject();
98 | panel.port.emit('currentTabInfo',tabdata );
99 | if( !tabdata.value || !tabdata.value.stage || tabdata.value.stage == 'search' || tabdata.value.stage == 'mark' ) {
100 | setTimeout(sendTabdata,100);
101 | }
102 | }
103 |
104 | panel.on("show",sendTabdata);
105 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Lobbyradar ###
3 |
4 | Lobbyradar is a Browserextension which uses Data available on lobbyradar.opendatacloud.de
5 | Lobbyradar is meant to run on Chrome, Safari and Firefox.
6 | It is built using the BabelExt Project. BabelExt simplifies cross-browser development of
7 | Extensions. It abstracts Message passing between background- and foreground scripts.
8 | Background scripts are run in the Context of the Extension. They have access to the extension
9 | data, here: settings and lobbydata.
10 | Foreground scripts are injected into the current page and can modify the DOM and interact with
11 | the UI. BabelExt comes with an unusual Build-Script based on PhantomJS.
12 |
13 | I had to modify BabelExt for lobbyradar, so browser abstraction is somewhat lost.
14 |
15 | ### Directories ###
16 |
17 | lib/: Background and Foreground scripts, settings files (settings.json, local_settings.json)
18 | test/: Test-Page with many names and an iframe. Serve this directory with a web server to test your extension.
19 | build/: Installable Extensions generated by the build script.
20 |
21 | Chrome/: the Chrome-Extension. This Directory is modified by the build script.
22 | Safari.safariextension/: the Safari extension. Modified by build script and Safaris extensions builder (Info.plist)
23 | Firefox/: the Firefox extension. Modified by Build script and Firefox-SDK.
24 |
25 | Do not delete the Extension directories! The build script generates only part of the files.
26 |
27 | ### Files ###
28 | fg_page.js: Injected into the Page. The same for all Browsers
29 | bg_*.js: Background Scripts. One Version for Chrome/Safari, different for Firefox.
30 |
31 | Background-scripts for Chrome/Safari are modified in lib/.
32 | Background-scripts for Firefox are modified in Firefox/.
33 |
34 | I strongly recommend to understand the build script.
35 |
36 | ### Build process ###
37 |
38 | Download PhantomJS (http://phantomjs.org), which is used to build and deploy browser-extensions.
39 | You need to have the Chrome Browser installed to build the Chrome extension.
40 |
41 | In UNIX-based OSes, run `./bin/build.sh`
42 |
43 | The build system hasn't been tested under Windows yet - your best bet is probably to look at
44 | the scripts and write a Windows equivalent. If it's any good, please send in a patch!
45 |
46 | **IMPORTANT SAFARI NOTE:**
47 | If the extension directory does not end in ".safariextension", it will not be
48 | recognized by Safari. Symlinks inside the extension directory are not allowed.
49 |
50 |
51 | ## Instructions for loading/testing an extension in each browser ##
52 |
53 | - You need to build the package before you start - the initial build
54 | process configures some files that aren't stored in git
55 |
56 | ### Chrome / Opera ###
57 |
58 | - Go to about://extensions
59 |
60 | - Check "Developer Mode"
61 |
62 | - Click "load unpacked extension" and choose the Chrome directory
63 |
64 | - You're good to go! If you just want to try out the BabelExt kitchen sink demo, navigate to [http://babelext.com/demo/](http://babelext.com/demo/)
65 |
66 | - Further Chrome development information can be found at [http://code.google.com/chrome/extensions/index.html](http://code.google.com/chrome/extensions/index.html)
67 |
68 | ### Firefox ###
69 |
70 | - Install firefox developer edition
71 | - Install Auto-Installer Extension [https://addons.mozilla.org/addon/autoinstaller/](https://addons.mozilla.org/addon/autoinstaller/)
72 |
73 | - Further Firefox development information can be found at [https://addons.mozilla.org/en-US/developers/docs/sdk/latest/](https://addons.mozilla.org/en-US/developers/docs/sdk/latest/)
74 |
75 | ### Safari ###
76 |
77 | - Click the gear icon, and choose Settings -> Preferences -> Advanced
78 |
79 | - Check the box that reads "Show Develop menu in menu bar"
80 |
81 | - Click the menu button (left of the gear icon), and choose Develop -> Show Extension Builder
82 |
83 | - Click the + button at the bottom left, and choose "Add Extension"
84 |
85 | - Choose the Safari.safariextension folder from lobbyradar
86 |
87 | - Further Safari development information can be found at [https://developer.apple.com/library/safari/#documentation/Tools/Conceptual/SafariExtensionGuide/Introduction/Introduction.html](https://developer.apple.com/library/safari/#documentation/Tools/Conceptual/SafariExtensionGuide/Introduction/Introduction.html)
88 |
89 | ## Releasing packages ##
90 |
91 | You need to release your extension by hand in each Extension store.
92 |
93 | ### LICENSE ###
94 |
95 | MIT (X11) license. See LICENSE.txt
96 |
--------------------------------------------------------------------------------
/lib/settings.json:
--------------------------------------------------------------------------------
1 | /*
2 | * BROWSER-NEUTRAL CONFIGURATION FILE
3 | * (copied to browser-specific files during build)
4 | */
5 | {
6 | // In Linux, you can make a GUID by running `uuidgen` on the command line:
7 | "id": "DF6BD873-26A4-4A36-96DB-208B10ACC4D0",
8 | "bundleid": "de.miz-babelsberg.lobbyradar", // used by safari only
9 |
10 | // General config parameters
11 | "name": "lobbyradar",
12 | "title": "Lobbyradar",
13 | "description": "Discover Lobby Networks",
14 | "license": "MIT",
15 | "author": "Medieninnovationszentrum Babelsberg MIZ",
16 | "version": "1.3.4",
17 | "website": "http://www.lobbyradar.zdf.de",
18 | "icons": {
19 | "16": "lobbyradar-16.png",
20 | "32": "lobbyradar-32.png",
21 | "38": "lobbyradar-38.png",
22 | "48": "lobbyradar-48.png",
23 | "64": "lobbyradar-64.png",
24 | "128": "lobbyradar-128.png"
25 | },
26 |
27 | "long_description":
28 | "Lobbyradar markiert die Namen und Organisationen, die in unserer Datenbank hinterlegt sind, in den Texten, die Sie lesen. Fährt man dann mit der Maus über die Markierung, lädt Lobbyradar die wichtigsten Infos aus unserer Datenbank und zeigt sie an. So werden Nachrichten und Geschichten in einen neuen Kontext gesetzt und Sie erhalten nützliche Zusatzinformationen.",
29 |
30 | // userscript config parameters:
31 |
32 | /*
33 | * contentScriptWhen can be 'early', 'middle' or 'late'.
34 | * different browsers interpret this in different ways, but in general:
35 | * * 'early' runs at the earliest point supported by the browser (possibly before the DOM exists)
36 | * * 'middle' guarantees the DOM exists, but might run while the page is still loading
37 | * * 'late' guarantees the scripts are run aft the page finishes loading
38 | */
39 | "contentScriptWhen": "middle",
40 |
41 | "contentScriptFiles": [ "jquery.js","jquery_highlight.js","jquery.tooltipster.js","fg_page.js","moment.js","underscore.js", "shariff.min.js" ],
42 | // contentscriptfiles nur für Firefox
43 | "contentScriptFiles_ff": [ "worker_search.js" ],
44 | "contentCSSFiles": [ "style.css","tooltipster.css","shariff.min.css","share-icons.css" ],
45 | "contentCSSFiles_chrome":[ ],
46 | "contentCSSFiles_ff": [ ],
47 | "contentCSSFiles_safari":[ ],
48 | "backgroundScriptFiles": [ "underscore.js","bg_common.js", "bg_search.js","bg_browserbutton.js","jquery.js",],
49 | "extra_files": [ "css","lobbyradar.png" ],
50 |
51 | "match_domain": "*", // catchall
52 | // whether to match https://:
53 | "match_secure_domain": true,
54 |
55 | // plugin should not run on these urls
56 | "exclude_matches": [ "*://lobbyradar.opendatacloud.de/*","*://www.lobbyradar.de/*" ],
57 |
58 | // Popup if supported by target platform
59 | //
60 | // reference for this feature is the functionality on the Chrome Platform
61 | "popup": {
62 | "page": "popup/popup.html",
63 | "extra_files": [ "popup" ],
64 | "icon": "lobbyradar-16-mono.png", // safari only. Chrome uses best match from icons{} array
65 | "width": 361,
66 | "height": 640
67 | },
68 |
69 | "preferences": [
70 | /*
71 | * Preferences that users can set in the browser's preferences page.
72 | * The layout is based on Mozilla's "simple preferences" interface:
73 | * https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/simple-prefs
74 | * currently supported types: bool, boolint, integer, string, menulist, radio
75 | */
76 | {
77 | "name": "whitelist",
78 | "type": "text",
79 | "title": "Whitelist",
80 | "description": "Persönliche Liste von Domains auf denen Lobbyradar aktiv ist. Ein Eintrag pro Zeile.",
81 | "value": "",
82 | },
83 | {
84 | "name": "updateinterval",
85 | "type": "menulist",
86 | "title": "Update Interval",
87 | "value": 3600,
88 | "description": "Aktualisierungsinterval für Lobbydaten",
89 | "options": [
90 | {
91 | "value": "600",
92 | "label": "alle 10 Minuten"
93 | },
94 | {
95 | "value": "3600",
96 | "label": "stündlich"
97 | },
98 | {
99 | "value": "86400",
100 | "label": "täglich"
101 | },
102 | {
103 | "value": "604800",
104 | "label": "wöchentlich"
105 | }
106 | ]
107 | }
108 | ],
109 |
110 | "firefox_max_version": '38.*'
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/lib/jquery_highlight.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Highlight plugin
3 | *
4 | * Based on highlight v3 by Johann Burkard
5 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
6 | *
7 | * Code a little bit refactored and cleaned (in my humble opinion).
8 | * Most important changes:
9 | * - has an option to highlight only entire words (wordsOnly - false by default),
10 | * - has an option to be case sensitive (caseSensitive - false by default)
11 | * - highlight element tag and class names can be specified in options
12 | *
13 | * Usage:
14 | * // wrap every occurrance of text 'lorem' in content
15 | * // with (default options)
16 | * $('#content').highlight('lorem');
17 | *
18 | * // search for and highlight more terms at once
19 | * // so you can save some time on traversing DOM
20 | * $('#content').highlight(['lorem', 'ipsum']);
21 | * $('#content').highlight('lorem ipsum');
22 | *
23 | * // search only for entire word 'lorem'
24 | * $('#content').highlight('lorem', { wordsOnly: true });
25 | *
26 | * // don't ignore case during search of term 'lorem'
27 | * $('#content').highlight('lorem', { caseSensitive: true });
28 | *
29 | * // wrap every occurrance of term 'ipsum' in content
30 | * // with
31 | * $('#content').highlight('ipsum', { element: 'em', className: 'important' });
32 | *
33 | * // remove default highlight
34 | * $('#content').unhighlight();
35 | *
36 | * // remove custom highlight
37 | * $('#content').unhighlight({ element: 'em', className: 'important' });
38 | *
39 | *
40 | * Copyright (c) 2009 Bartek Szopka
41 | *
42 | * Licensed under MIT license.
43 | *
44 | */
45 |
46 | jQuery.extend({
47 | highlight: function (node, re, nodeName, className, wordsOnly, word, re_word,ret) {
48 | if (node.nodeType === 3) {
49 | ret.match = 0;
50 | var match = node.data.match(re);
51 | if (match) {
52 | if( ret.maxHits === 0 ) return ret;
53 | var highlight = document.createElement(nodeName || 'span');
54 | highlight.className = className || 'highlight';
55 | if(wordsOnly) {
56 | var index = match[0].search(re_word)+match.index;
57 | var wordNode = node.splitText(index);
58 | wordNode.splitText(word.length);
59 | } else {
60 | var wordNode = node.splitText(match.index);
61 | wordNode.splitText(word.length);
62 | }
63 | var wordClone = wordNode.cloneNode(true);
64 | highlight.appendChild(wordClone);
65 | wordNode.parentNode.replaceChild(highlight, wordNode);
66 | ret.match = 1;
67 | ret.maxHits--;
68 | return ret; //skip added node in parent
69 | }
70 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
71 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
72 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
73 | for (var i = 0; i < node.childNodes.length; i++) {
74 | ret = jQuery.highlight(node.childNodes[i], re, nodeName, className,wordsOnly,word,re_word,ret);
75 | i += ret.match;
76 | }
77 | }
78 | return ret;
79 | }
80 | });
81 |
82 | jQuery.fn.unhighlight = function (options) {
83 | var settings = { className: 'highlight', element: 'span' };
84 | jQuery.extend(settings, options);
85 |
86 | return this.find(settings.element + "." + settings.className).each(function () {
87 | var parent = this.parentNode;
88 | parent.replaceChild(this.firstChild, this);
89 | parent.normalize();
90 | }).end();
91 | };
92 |
93 | jQuery.fn.highlight = function (word, options) {
94 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false, maxHits:-1 };
95 | jQuery.extend(settings, options);
96 |
97 | var pattern = "(" + word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + ")";
98 | var pattern_word = word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
99 |
100 | var flag = settings.caseSensitive ? "" : "i";
101 | if (settings.wordsOnly) {
102 | // simple \b does not work with unicode text
103 | // see http://stackoverflow.com/questions/10590098/javascript-regexp-word-boundaries-unicode-characters
104 | pattern = "(^|\\s|[,.\\-\\(\\)\\[\\]])" + pattern + "($|\\s|[,.\\-\\(\\)\\[\\]])";
105 | }
106 | var re = new RegExp(pattern, flag);
107 | var document_results={match:0,maxHits:settings.maxHits};
108 |
109 | return this.each(function () {
110 | document_results = jQuery.highlight(this, re, settings.element, settings.className,settings.wordsOnly,word,new RegExp(pattern_word,'i'), document_results);
111 | });
112 | };
113 |
--------------------------------------------------------------------------------
/Chrome/jquery_highlight.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Highlight plugin
3 | *
4 | * Based on highlight v3 by Johann Burkard
5 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
6 | *
7 | * Code a little bit refactored and cleaned (in my humble opinion).
8 | * Most important changes:
9 | * - has an option to highlight only entire words (wordsOnly - false by default),
10 | * - has an option to be case sensitive (caseSensitive - false by default)
11 | * - highlight element tag and class names can be specified in options
12 | *
13 | * Usage:
14 | * // wrap every occurrance of text 'lorem' in content
15 | * // with (default options)
16 | * $('#content').highlight('lorem');
17 | *
18 | * // search for and highlight more terms at once
19 | * // so you can save some time on traversing DOM
20 | * $('#content').highlight(['lorem', 'ipsum']);
21 | * $('#content').highlight('lorem ipsum');
22 | *
23 | * // search only for entire word 'lorem'
24 | * $('#content').highlight('lorem', { wordsOnly: true });
25 | *
26 | * // don't ignore case during search of term 'lorem'
27 | * $('#content').highlight('lorem', { caseSensitive: true });
28 | *
29 | * // wrap every occurrance of term 'ipsum' in content
30 | * // with
31 | * $('#content').highlight('ipsum', { element: 'em', className: 'important' });
32 | *
33 | * // remove default highlight
34 | * $('#content').unhighlight();
35 | *
36 | * // remove custom highlight
37 | * $('#content').unhighlight({ element: 'em', className: 'important' });
38 | *
39 | *
40 | * Copyright (c) 2009 Bartek Szopka
41 | *
42 | * Licensed under MIT license.
43 | *
44 | */
45 |
46 | jQuery.extend({
47 | highlight: function (node, re, nodeName, className, wordsOnly, word, re_word,ret) {
48 | if (node.nodeType === 3) {
49 | ret.match = 0;
50 | var match = node.data.match(re);
51 | if (match) {
52 | if( ret.maxHits === 0 ) return ret;
53 | var highlight = document.createElement(nodeName || 'span');
54 | highlight.className = className || 'highlight';
55 | if(wordsOnly) {
56 | var index = match[0].search(re_word)+match.index;
57 | var wordNode = node.splitText(index);
58 | wordNode.splitText(word.length);
59 | } else {
60 | var wordNode = node.splitText(match.index);
61 | wordNode.splitText(word.length);
62 | }
63 | var wordClone = wordNode.cloneNode(true);
64 | highlight.appendChild(wordClone);
65 | wordNode.parentNode.replaceChild(highlight, wordNode);
66 | ret.match = 1;
67 | ret.maxHits--;
68 | return ret; //skip added node in parent
69 | }
70 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
71 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
72 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
73 | for (var i = 0; i < node.childNodes.length; i++) {
74 | ret = jQuery.highlight(node.childNodes[i], re, nodeName, className,wordsOnly,word,re_word,ret);
75 | i += ret.match;
76 | }
77 | }
78 | return ret;
79 | }
80 | });
81 |
82 | jQuery.fn.unhighlight = function (options) {
83 | var settings = { className: 'highlight', element: 'span' };
84 | jQuery.extend(settings, options);
85 |
86 | return this.find(settings.element + "." + settings.className).each(function () {
87 | var parent = this.parentNode;
88 | parent.replaceChild(this.firstChild, this);
89 | parent.normalize();
90 | }).end();
91 | };
92 |
93 | jQuery.fn.highlight = function (word, options) {
94 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false, maxHits:-1 };
95 | jQuery.extend(settings, options);
96 |
97 | var pattern = "(" + word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + ")";
98 | var pattern_word = word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
99 |
100 | var flag = settings.caseSensitive ? "" : "i";
101 | if (settings.wordsOnly) {
102 | // simple \b does not work with unicode text
103 | // see http://stackoverflow.com/questions/10590098/javascript-regexp-word-boundaries-unicode-characters
104 | pattern = "(^|\\s|[,.\\-\\(\\)\\[\\]])" + pattern + "($|\\s|[,.\\-\\(\\)\\[\\]])";
105 | }
106 | var re = new RegExp(pattern, flag);
107 | var document_results={match:0,maxHits:settings.maxHits};
108 |
109 | return this.each(function () {
110 | document_results = jQuery.highlight(this, re, settings.element, settings.className,settings.wordsOnly,word,new RegExp(pattern_word,'i'), document_results);
111 | });
112 | };
113 |
--------------------------------------------------------------------------------
/Safari.safariextension/background.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/Safari.safariextension/jquery_highlight.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Highlight plugin
3 | *
4 | * Based on highlight v3 by Johann Burkard
5 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
6 | *
7 | * Code a little bit refactored and cleaned (in my humble opinion).
8 | * Most important changes:
9 | * - has an option to highlight only entire words (wordsOnly - false by default),
10 | * - has an option to be case sensitive (caseSensitive - false by default)
11 | * - highlight element tag and class names can be specified in options
12 | *
13 | * Usage:
14 | * // wrap every occurrance of text 'lorem' in content
15 | * // with (default options)
16 | * $('#content').highlight('lorem');
17 | *
18 | * // search for and highlight more terms at once
19 | * // so you can save some time on traversing DOM
20 | * $('#content').highlight(['lorem', 'ipsum']);
21 | * $('#content').highlight('lorem ipsum');
22 | *
23 | * // search only for entire word 'lorem'
24 | * $('#content').highlight('lorem', { wordsOnly: true });
25 | *
26 | * // don't ignore case during search of term 'lorem'
27 | * $('#content').highlight('lorem', { caseSensitive: true });
28 | *
29 | * // wrap every occurrance of term 'ipsum' in content
30 | * // with
31 | * $('#content').highlight('ipsum', { element: 'em', className: 'important' });
32 | *
33 | * // remove default highlight
34 | * $('#content').unhighlight();
35 | *
36 | * // remove custom highlight
37 | * $('#content').unhighlight({ element: 'em', className: 'important' });
38 | *
39 | *
40 | * Copyright (c) 2009 Bartek Szopka
41 | *
42 | * Licensed under MIT license.
43 | *
44 | */
45 |
46 | jQuery.extend({
47 | highlight: function (node, re, nodeName, className, wordsOnly, word, re_word,ret) {
48 | if (node.nodeType === 3) {
49 | ret.match = 0;
50 | var match = node.data.match(re);
51 | if (match) {
52 | if( ret.maxHits === 0 ) return ret;
53 | var highlight = document.createElement(nodeName || 'span');
54 | highlight.className = className || 'highlight';
55 | if(wordsOnly) {
56 | var index = match[0].search(re_word)+match.index;
57 | var wordNode = node.splitText(index);
58 | wordNode.splitText(word.length);
59 | } else {
60 | var wordNode = node.splitText(match.index);
61 | wordNode.splitText(word.length);
62 | }
63 | var wordClone = wordNode.cloneNode(true);
64 | highlight.appendChild(wordClone);
65 | wordNode.parentNode.replaceChild(highlight, wordNode);
66 | ret.match = 1;
67 | ret.maxHits--;
68 | return ret; //skip added node in parent
69 | }
70 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
71 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
72 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
73 | for (var i = 0; i < node.childNodes.length; i++) {
74 | ret = jQuery.highlight(node.childNodes[i], re, nodeName, className,wordsOnly,word,re_word,ret);
75 | i += ret.match;
76 | }
77 | }
78 | return ret;
79 | }
80 | });
81 |
82 | jQuery.fn.unhighlight = function (options) {
83 | var settings = { className: 'highlight', element: 'span' };
84 | jQuery.extend(settings, options);
85 |
86 | return this.find(settings.element + "." + settings.className).each(function () {
87 | var parent = this.parentNode;
88 | parent.replaceChild(this.firstChild, this);
89 | parent.normalize();
90 | }).end();
91 | };
92 |
93 | jQuery.fn.highlight = function (word, options) {
94 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false, maxHits:-1 };
95 | jQuery.extend(settings, options);
96 |
97 | var pattern = "(" + word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + ")";
98 | var pattern_word = word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
99 |
100 | var flag = settings.caseSensitive ? "" : "i";
101 | if (settings.wordsOnly) {
102 | // simple \b does not work with unicode text
103 | // see http://stackoverflow.com/questions/10590098/javascript-regexp-word-boundaries-unicode-characters
104 | pattern = "(^|\\s|[,.\\-\\(\\)\\[\\]])" + pattern + "($|\\s|[,.\\-\\(\\)\\[\\]])";
105 | }
106 | var re = new RegExp(pattern, flag);
107 | var document_results={match:0,maxHits:settings.maxHits};
108 |
109 | return this.each(function () {
110 | document_results = jQuery.highlight(this, re, settings.element, settings.className,settings.wordsOnly,word,new RegExp(pattern_word,'i'), document_results);
111 | });
112 | };
113 |
--------------------------------------------------------------------------------
/lib/bg_browserbutton.js:
--------------------------------------------------------------------------------
1 | if(SAFARI) {
2 | var ToolbarButton;
3 | safari.extension.toolbarItems.forEach(function(item) {
4 | if (item.identifier == 'lobbyradarBtn') {
5 | ToolbarButton = item;
6 | }
7 | });
8 | var updateBrowserButton = function( tabId ) {
9 | var storedTabdata = tabData.get(tabId);
10 | storedTabdata.stage='done';
11 | tabData.set(tabId,storedTabdata);
12 | if(storedTabdata && storedTabdata.hits && storedTabdata.hits.length) {
13 | ToolbarButton.badge = storedTabdata.hits.length.toString();
14 | } else {
15 | ToolbarButton.badge = '0';
16 | }
17 | }
18 |
19 | var setBrowserButton_searching = function( tabId ) {
20 | var storedTabdata = tabData.get(tabId);
21 | storedTabdata.stage='search';
22 | tabData.set(tabId,storedTabdata);
23 | ToolbarButton.badge = '...'; // safari is not displaying this. unfortunately
24 | }
25 | var setBrowserButton_waiting = function( tabId ) {
26 | var storedTabdata = tabData.get(tabId);
27 | storedTabdata.stage='mark';
28 | tabData.set(tabId,storedTabdata);
29 | ToolbarButton.badge = '+++'; // safari is not displaying this. unfortunately
30 | }
31 | } else {
32 | var updateBrowserButton = function( tabId ) {
33 | chrome.browserAction.setTitle({title:'Lobbyradar',tabId:tabId});
34 | chrome.browserAction.setBadgeText({text:'',tabId:tabId});
35 | chrome.browserAction.setBadgeBackgroundColor({ color: "#555",tabId:tabId });
36 | var storedTabdata = tabData.get(tabId);
37 | storedTabdata.stage='done';
38 | tabData.set(tabId,storedTabdata);
39 | if(storedTabdata.hits) {
40 | chrome.browserAction.setBadgeText({text:storedTabdata.hits.length.toString(),tabId:tabId});
41 | } else {
42 | chrome.browserAction.setBadgeText({text:"0",tabId:tabId});
43 | }
44 | }
45 |
46 | var setBrowserButton_searching = function( tabId ) {
47 | var storedTabdata = tabData.get(tabId);
48 | storedTabdata.stage='search';
49 | tabData.set(tabId,storedTabdata);
50 | chrome.browserAction.setTitle({title:'Lobbyradar sucht...',tabId:tabId});
51 | chrome.browserAction.setBadgeText({text:'...',tabId:tabId});
52 | chrome.browserAction.setBadgeBackgroundColor({ color: "#a00",tabId:tabId });
53 | }
54 | var setBrowserButton_waiting = function( tabId ) {
55 | var storedTabdata = tabData.get(tabId);
56 | storedTabdata.stage='mark';
57 | tabData.set(tabId,storedTabdata);
58 | chrome.browserAction.setTitle({title:'Lobbyradar arbeitet...',tabId:tabId});
59 | chrome.browserAction.setBadgeText({text:'+++',tabId:tabId});
60 | chrome.browserAction.setBadgeBackgroundColor({ color: "#a00",tabId:tabId });
61 | }
62 | }
63 |
64 | // keep track of names found in each Browsertab
65 | tabData = {
66 | // get data stored for a tab
67 | get: function(tabId) {
68 | return tabData[tabId] ? tabData[tabId] : {};
69 | },
70 |
71 | // store value for tab
72 | set: function(tabId, value) {
73 | tabData[tabId] = value;
74 | },
75 |
76 | // When a tab is closed, delete all its data
77 | onTabClosed: function(tabId) {
78 | delete tabData[tabId];
79 | }
80 | };
81 |
82 | function respondToLobbyradarBadgeMessage (request, sender, sendResponse) {
83 | switch(request.requestType) {
84 | case 'updateBrowserButton': updateBrowserButton( sender.tab.id );break;
85 | case 'setBrowserButton_waiting': setBrowserButton_waiting( sender.tab.id );break;
86 | case 'setBrowserButton_searching': setBrowserButton_searching( sender.tab.id );break;
87 | }
88 | return true;
89 | };
90 |
91 | if(SAFARI) {
92 | safari.application.addEventListener("validate",function(msgEvent){
93 | var sender = {tab:msgEvent.target.browserWindow.activeTab};
94 | sender.tab.id=_.indexOf(safari.application.activeBrowserWindow.tabs,sender.tab);
95 | updateBrowserButton( sender.tab.id );
96 | });
97 | safari.application.addEventListener("popover", function(msgEvent) {
98 | safari.extension.popovers[0].contentWindow.update_content();
99 | }, true);
100 |
101 | safari.application.addEventListener("message",function(msgEvent){
102 | var sender = {tab:msgEvent.target};
103 | sender.tab.id=_.indexOf(safari.application.activeBrowserWindow.tabs,sender.tab);
104 |
105 | var sendResponse=function(data) {
106 | var callbackID = msgEvent.message.callbackID;
107 | msgEvent.target.page.dispatchMessage( msgEvent.name, { value:data,
108 | callbackID:callbackID
109 | });
110 | }
111 | respondToLobbyradarBadgeMessage( msgEvent.message, sender, sendResponse );
112 | },false);
113 |
114 | } else {
115 | chrome.runtime.onMessage.addListener(respondToLobbyradarBadgeMessage);
116 | chrome.tabs.onRemoved.addListener(tabData.onTabClosed);
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/Chrome/bg_browserbutton.js:
--------------------------------------------------------------------------------
1 | if(SAFARI) {
2 | var ToolbarButton;
3 | safari.extension.toolbarItems.forEach(function(item) {
4 | if (item.identifier == 'lobbyradarBtn') {
5 | ToolbarButton = item;
6 | }
7 | });
8 | var updateBrowserButton = function( tabId ) {
9 | var storedTabdata = tabData.get(tabId);
10 | storedTabdata.stage='done';
11 | tabData.set(tabId,storedTabdata);
12 | if(storedTabdata && storedTabdata.hits && storedTabdata.hits.length) {
13 | ToolbarButton.badge = storedTabdata.hits.length.toString();
14 | } else {
15 | ToolbarButton.badge = '0';
16 | }
17 | }
18 |
19 | var setBrowserButton_searching = function( tabId ) {
20 | var storedTabdata = tabData.get(tabId);
21 | storedTabdata.stage='search';
22 | tabData.set(tabId,storedTabdata);
23 | ToolbarButton.badge = '...'; // safari is not displaying this. unfortunately
24 | }
25 | var setBrowserButton_waiting = function( tabId ) {
26 | var storedTabdata = tabData.get(tabId);
27 | storedTabdata.stage='mark';
28 | tabData.set(tabId,storedTabdata);
29 | ToolbarButton.badge = '+++'; // safari is not displaying this. unfortunately
30 | }
31 | } else {
32 | var updateBrowserButton = function( tabId ) {
33 | chrome.browserAction.setTitle({title:'Lobbyradar',tabId:tabId});
34 | chrome.browserAction.setBadgeText({text:'',tabId:tabId});
35 | chrome.browserAction.setBadgeBackgroundColor({ color: "#555",tabId:tabId });
36 | var storedTabdata = tabData.get(tabId);
37 | storedTabdata.stage='done';
38 | tabData.set(tabId,storedTabdata);
39 | if(storedTabdata.hits) {
40 | chrome.browserAction.setBadgeText({text:storedTabdata.hits.length.toString(),tabId:tabId});
41 | } else {
42 | chrome.browserAction.setBadgeText({text:"0",tabId:tabId});
43 | }
44 | }
45 |
46 | var setBrowserButton_searching = function( tabId ) {
47 | var storedTabdata = tabData.get(tabId);
48 | storedTabdata.stage='search';
49 | tabData.set(tabId,storedTabdata);
50 | chrome.browserAction.setTitle({title:'Lobbyradar sucht...',tabId:tabId});
51 | chrome.browserAction.setBadgeText({text:'...',tabId:tabId});
52 | chrome.browserAction.setBadgeBackgroundColor({ color: "#a00",tabId:tabId });
53 | }
54 | var setBrowserButton_waiting = function( tabId ) {
55 | var storedTabdata = tabData.get(tabId);
56 | storedTabdata.stage='mark';
57 | tabData.set(tabId,storedTabdata);
58 | chrome.browserAction.setTitle({title:'Lobbyradar arbeitet...',tabId:tabId});
59 | chrome.browserAction.setBadgeText({text:'+++',tabId:tabId});
60 | chrome.browserAction.setBadgeBackgroundColor({ color: "#a00",tabId:tabId });
61 | }
62 | }
63 |
64 | // keep track of names found in each Browsertab
65 | tabData = {
66 | // get data stored for a tab
67 | get: function(tabId) {
68 | return tabData[tabId] ? tabData[tabId] : {};
69 | },
70 |
71 | // store value for tab
72 | set: function(tabId, value) {
73 | tabData[tabId] = value;
74 | },
75 |
76 | // When a tab is closed, delete all its data
77 | onTabClosed: function(tabId) {
78 | delete tabData[tabId];
79 | }
80 | };
81 |
82 | function respondToLobbyradarBadgeMessage (request, sender, sendResponse) {
83 | switch(request.requestType) {
84 | case 'updateBrowserButton': updateBrowserButton( sender.tab.id );break;
85 | case 'setBrowserButton_waiting': setBrowserButton_waiting( sender.tab.id );break;
86 | case 'setBrowserButton_searching': setBrowserButton_searching( sender.tab.id );break;
87 | }
88 | return true;
89 | };
90 |
91 | if(SAFARI) {
92 | safari.application.addEventListener("validate",function(msgEvent){
93 | var sender = {tab:msgEvent.target.browserWindow.activeTab};
94 | sender.tab.id=_.indexOf(safari.application.activeBrowserWindow.tabs,sender.tab);
95 | updateBrowserButton( sender.tab.id );
96 | });
97 | safari.application.addEventListener("popover", function(msgEvent) {
98 | safari.extension.popovers[0].contentWindow.update_content();
99 | }, true);
100 |
101 | safari.application.addEventListener("message",function(msgEvent){
102 | var sender = {tab:msgEvent.target};
103 | sender.tab.id=_.indexOf(safari.application.activeBrowserWindow.tabs,sender.tab);
104 |
105 | var sendResponse=function(data) {
106 | var callbackID = msgEvent.message.callbackID;
107 | msgEvent.target.page.dispatchMessage( msgEvent.name, { value:data,
108 | callbackID:callbackID
109 | });
110 | }
111 | respondToLobbyradarBadgeMessage( msgEvent.message, sender, sendResponse );
112 | },false);
113 |
114 | } else {
115 | chrome.runtime.onMessage.addListener(respondToLobbyradarBadgeMessage);
116 | chrome.tabs.onRemoved.addListener(tabData.onTabClosed);
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/Safari.safariextension/bg_browserbutton.js:
--------------------------------------------------------------------------------
1 | if(SAFARI) {
2 | var ToolbarButton;
3 | safari.extension.toolbarItems.forEach(function(item) {
4 | if (item.identifier == 'lobbyradarBtn') {
5 | ToolbarButton = item;
6 | }
7 | });
8 | var updateBrowserButton = function( tabId ) {
9 | var storedTabdata = tabData.get(tabId);
10 | storedTabdata.stage='done';
11 | tabData.set(tabId,storedTabdata);
12 | if(storedTabdata && storedTabdata.hits && storedTabdata.hits.length) {
13 | ToolbarButton.badge = storedTabdata.hits.length.toString();
14 | } else {
15 | ToolbarButton.badge = '0';
16 | }
17 | }
18 |
19 | var setBrowserButton_searching = function( tabId ) {
20 | var storedTabdata = tabData.get(tabId);
21 | storedTabdata.stage='search';
22 | tabData.set(tabId,storedTabdata);
23 | ToolbarButton.badge = '...'; // safari is not displaying this. unfortunately
24 | }
25 | var setBrowserButton_waiting = function( tabId ) {
26 | var storedTabdata = tabData.get(tabId);
27 | storedTabdata.stage='mark';
28 | tabData.set(tabId,storedTabdata);
29 | ToolbarButton.badge = '+++'; // safari is not displaying this. unfortunately
30 | }
31 | } else {
32 | var updateBrowserButton = function( tabId ) {
33 | chrome.browserAction.setTitle({title:'Lobbyradar',tabId:tabId});
34 | chrome.browserAction.setBadgeText({text:'',tabId:tabId});
35 | chrome.browserAction.setBadgeBackgroundColor({ color: "#555",tabId:tabId });
36 | var storedTabdata = tabData.get(tabId);
37 | storedTabdata.stage='done';
38 | tabData.set(tabId,storedTabdata);
39 | if(storedTabdata.hits) {
40 | chrome.browserAction.setBadgeText({text:storedTabdata.hits.length.toString(),tabId:tabId});
41 | } else {
42 | chrome.browserAction.setBadgeText({text:"0",tabId:tabId});
43 | }
44 | }
45 |
46 | var setBrowserButton_searching = function( tabId ) {
47 | var storedTabdata = tabData.get(tabId);
48 | storedTabdata.stage='search';
49 | tabData.set(tabId,storedTabdata);
50 | chrome.browserAction.setTitle({title:'Lobbyradar sucht...',tabId:tabId});
51 | chrome.browserAction.setBadgeText({text:'...',tabId:tabId});
52 | chrome.browserAction.setBadgeBackgroundColor({ color: "#a00",tabId:tabId });
53 | }
54 | var setBrowserButton_waiting = function( tabId ) {
55 | var storedTabdata = tabData.get(tabId);
56 | storedTabdata.stage='mark';
57 | tabData.set(tabId,storedTabdata);
58 | chrome.browserAction.setTitle({title:'Lobbyradar arbeitet...',tabId:tabId});
59 | chrome.browserAction.setBadgeText({text:'+++',tabId:tabId});
60 | chrome.browserAction.setBadgeBackgroundColor({ color: "#a00",tabId:tabId });
61 | }
62 | }
63 |
64 | // keep track of names found in each Browsertab
65 | tabData = {
66 | // get data stored for a tab
67 | get: function(tabId) {
68 | return tabData[tabId] ? tabData[tabId] : {};
69 | },
70 |
71 | // store value for tab
72 | set: function(tabId, value) {
73 | tabData[tabId] = value;
74 | },
75 |
76 | // When a tab is closed, delete all its data
77 | onTabClosed: function(tabId) {
78 | delete tabData[tabId];
79 | }
80 | };
81 |
82 | function respondToLobbyradarBadgeMessage (request, sender, sendResponse) {
83 | switch(request.requestType) {
84 | case 'updateBrowserButton': updateBrowserButton( sender.tab.id );break;
85 | case 'setBrowserButton_waiting': setBrowserButton_waiting( sender.tab.id );break;
86 | case 'setBrowserButton_searching': setBrowserButton_searching( sender.tab.id );break;
87 | }
88 | return true;
89 | };
90 |
91 | if(SAFARI) {
92 | safari.application.addEventListener("validate",function(msgEvent){
93 | var sender = {tab:msgEvent.target.browserWindow.activeTab};
94 | sender.tab.id=_.indexOf(safari.application.activeBrowserWindow.tabs,sender.tab);
95 | updateBrowserButton( sender.tab.id );
96 | });
97 | safari.application.addEventListener("popover", function(msgEvent) {
98 | safari.extension.popovers[0].contentWindow.update_content();
99 | }, true);
100 |
101 | safari.application.addEventListener("message",function(msgEvent){
102 | var sender = {tab:msgEvent.target};
103 | sender.tab.id=_.indexOf(safari.application.activeBrowserWindow.tabs,sender.tab);
104 |
105 | var sendResponse=function(data) {
106 | var callbackID = msgEvent.message.callbackID;
107 | msgEvent.target.page.dispatchMessage( msgEvent.name, { value:data,
108 | callbackID:callbackID
109 | });
110 | }
111 | respondToLobbyradarBadgeMessage( msgEvent.message, sender, sendResponse );
112 | },false);
113 |
114 | } else {
115 | chrome.runtime.onMessage.addListener(respondToLobbyradarBadgeMessage);
116 | chrome.tabs.onRemoved.addListener(tabData.onTabClosed);
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/styling/tooltip/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Testpage
4 |
5 |
6 |
7 |
8 |
9 |
Tooltip Styling
10 |
11 | Diese Seite existiert nur, um beim Styling des Tooltips zu helfen. Phasellus gravida semper nisi. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Curabitur suscipit suscipit tellus. Praesent ut ligula non mi varius sagittis. Quisque id mi.
12 |
13 | Curabitur suscipit suscipit tellus. Nullam accumsan lorem in dui. Maecenas nec odio et ante tincidunt tempus. Aliquam lobortis. Vivamus elementum semper nisi.
14 |
15 | Praesent porttitor, nulla vitae posuere iaculis, arcu nisl dignissim dolor, a pretium mi sem ut ipsum. Vestibulum suscipit nulla quis orci. Cras id dui. Praesent egestas tristique nibh. Aliquam eu nunc.
16 |
17 | Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Duis leo. Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Pellentesque egestas, neque sit amet convallis pulvinar, justo nulla eleifend augue, ac auctor orci leo non est.
18 |
19 | Vestibulum rutrum, mi nec elementum vehicula, eros quam gravida nisl, id fringilla neque ante vel mi. Sed fringilla mauris sit amet nibh. Sed in libero ut nibh placerat accumsan. Ut non enim eleifend felis pretium feugiat. Fusce fermentum.
20 |
some Persons
21 |
22 |
Thomas
23 |
Entwicklung der Braunschen Röhre durch Karl Ferdinand Braun.
24 |
georg
25 |
Karl-August Siepelmeyer
26 |
Hans-Joachim Ahnert
27 |
Hans-Joachim Wolff, Hans Joachim Wolff, Hans-Joachim Wolff
28 |
Karin Schüler
29 |
Klaus-Dieter Rennert
30 |
Reiner Assmann
31 |
Siepelmeyer
32 |
Peter Spary
33 |
34 |
35 |
some Orgs
36 |
37 |
Arbeitgebervereinigung Nahrung und Genuß e.V.
38 |
Apotheker in Wissenschaft, Industrie und Verwaltungen (Fachgruppe WIV-Apotheker)
39 |
Arbeitsgemeinschaft Kino - Gilde deutscher Filmkunsttheater e.V AG Kino-Gilde