2020-09-16 12:39:29 +02:00
function log ( msg ) {
console . log ( "[Bahn Insight] " + msg ) ;
}
function getMediaURL ( path ) {
path = "media/" + path ;
return chrome . runtime . getURL ( path ) || browser . runtime . getURL ( path ) ;
}
2020-09-16 13:45:43 +02:00
2020-09-16 13:17:49 +02:00
/ * *
* Return train name in format "PRODUCT TRAIN_NUMER"
* i . e . "ICE 112" , "RE 12734"
* Sometimes train name is in format "PRODUCT LINE_NUMER (TRAIN_NUMER)"
* i . e . "STB 12 (62371)"
2020-09-16 13:45:43 +02:00
* Sometimes 'trains' are not trains or we can ' t find an unique id for them
* i . e . busses , ferrys , trams
* they will also be cleaned up and returned as undefined , because we can ' t link to them correctly
2020-09-16 13:17:49 +02:00
* /
function bahnParseTrainName ( dirty _train _name ) {
2020-09-16 14:16:47 +02:00
var name _list = dirty _train _name . trim ( ) . replace ( / +/g , ' ' ) . split ( " " ) ;
2020-09-16 12:39:29 +02:00
2020-09-16 13:17:49 +02:00
// Train name in format "STB 12 (23561)"
if ( name _list . length == 3 && name _list [ 2 ] . charAt ( 0 ) == '(' && name _list [ 2 ] . charAt ( name _list [ 2 ] . length - 1 ) == ')' ) {
return name _list [ 0 ] + " " + name _list [ 2 ] . substring ( 1 , name _list [ 2 ] . length - 1 ) ;
}
2020-09-16 13:45:43 +02:00
// Exclude linking to specific products
if ( [ "bus" , "fäh" , "str" ] . indexOf ( name _list [ 0 ] . toLowerCase ( ) ) !== - 1 ) {
return undefined ;
}
2020-09-16 13:17:49 +02:00
return dirty _train _name ;
}
2020-09-16 12:39:29 +02:00
2020-09-19 20:17:36 +02:00
/ * *
* Returns HTML a as DOM object
*
* @ param href URI as string
* /
2020-09-16 14:53:04 +02:00
function domCreateLink ( href ) {
var link = document . createElement ( "a" ) ;
link . setAttribute ( "href" , href ) ;
return link ;
}
2020-09-19 20:17:36 +02:00
/ * *
* Returns HTML img as DOM object
*
* @ param src Image URI as string
* /
2020-09-16 14:53:04 +02:00
function domCreateImage ( src ) {
var image = document . createElement ( "img" ) ;
image . setAttribute ( "src" , src ) ;
return image ;
}
2020-09-19 20:17:36 +02:00
/ * *
* Returns HTML br as DOM object
* /
2020-09-16 15:05:04 +02:00
function domCreateLinebreak ( ) {
var linebreak = document . createElement ( "br" ) ;
return linebreak ;
}
2020-09-19 21:42:11 +02:00
/ * *
* Returns HTML span as DOM object
* /
function domCreateSpan ( ) {
var span = document . createElement ( "span" ) ;
return span ;
}
2020-09-19 20:17:36 +02:00
/ * *
* Returns an 'image button' like construct as DOM object
*
* @ param href URI as string
* @ param image _src Image URI as string
* /
2020-09-16 14:53:04 +02:00
function domCreateButton ( href , image _src ) {
var link = domCreateLink ( href ) ;
2020-09-16 14:55:46 +02:00
link . setAttribute ( "target" , "_blank" ) ;
2020-09-16 14:53:04 +02:00
var image = domCreateImage ( image _src ) ;
2020-09-19 21:43:14 +02:00
image . setAttribute ( "style" , "height: 16px; vertical-align:middle;" ) ;
2020-09-16 14:53:04 +02:00
link . append ( image ) ;
return link ;
}
2020-09-19 20:17:36 +02:00
/ * *
* Returns an 'image buttom' to specifically link to marudor . de
*
* @ param path URL path part after https : //marudor.de
* /
2020-09-16 14:53:04 +02:00
function domCreateButtonMarudor ( path ) {
var button = domCreateButton ( "https://marudor.de" + path , getMediaURL ( "marudor.svg" ) ) ;
2020-09-19 21:43:42 +02:00
button . setAttribute ( "title" , "marudor.de" ) ;
return button ;
}
/ * *
* Returns an 'image buttom' to specifically link to dbf . finalrewind . org
*
* @ param path URL path part after https : //dbf.finalrewind.org
* /
function domCreateButtonDbf ( path ) {
var button = domCreateButton ( "https://dbf.finalrewind.org" + path , getMediaURL ( "dbf.png" ) ) ;
button . setAttribute ( "title" , "dbf.finalrewind.org" ) ;
2020-09-16 14:53:04 +02:00
return button ;
}
2020-09-19 21:42:11 +02:00
/ * *
* Returns a 'bahn-insight' element as DOM object
*
* Used to determine if this is an object set by this extension itself
* /
function domCreateBahnInsightField ( ) {
var span = domCreateSpan ( ) ;
span . setAttribute ( "class" , "bahn-insight" ) ;
return span ;
}
2020-09-16 14:19:31 +02:00
var connection _result _observer = new MutationObserver ( ( mutations ) => {
2020-09-19 21:38:23 +02:00
log ( "change detected" )
2020-09-16 14:22:10 +02:00
mutations . forEach ( ( mutation ) => {
if ( mutation . type === 'childList' ) {
var target = mutation . target ;
if ( target . tagName === 'TD' ) {
2020-09-19 21:38:23 +02:00
log ( "change is interesting" ) ;
2020-09-16 14:22:10 +02:00
var timetable = target . querySelector ( "td div.detailContainer table.result tbody" ) ;
2020-09-19 22:12:02 +02:00
// Just break if there are elements injected by us
if ( timetable . querySelectorAll ( ".bahn-insight" ) . length != 0 ) {
log ( "links already injected" )
return ;
}
2020-09-19 20:11:06 +02:00
/ *
* COLLECT DATA
* /
2020-09-19 20:09:43 +02:00
var data = [ ] ;
var relations = timetable . querySelectorAll ( "tr.first" ) ;
relations . forEach ( ( relation , i ) => {
var relationend = relation . nextElementSibling ;
data [ i ] = { } ;
data [ i ] [ "from" ] = { }
data [ i ] [ "to" ] = { }
2020-09-19 20:22:08 +02:00
// Depature station name
2020-09-19 20:09:43 +02:00
var relation _from = relation . querySelector ( "td.station" ) ;
data [ i ] [ "from" ] [ "station" ] = relation _from . innerText ;
2020-09-19 20:22:08 +02:00
// Arrival station name
2020-09-19 20:09:43 +02:00
var relation _to = relationend . querySelector ( "td.station" ) ;
data [ i ] [ "to" ] [ "station" ] = relation _to . innerText ;
2020-09-19 20:22:08 +02:00
// Departure time & current estimation
2020-09-19 20:09:43 +02:00
var relation _departure = relation . querySelector ( "td.time" ) ;
var relation _departure _list = relation _departure . firstChild . textContent . trim ( ) . split ( " " ) ;
data [ i ] [ "from" ] [ "time" ] = relation _departure _list [ 1 ] ;
data [ i ] [ "from" ] [ "time_current" ] = null ;
var relation _departure _current = relation _departure . querySelector ( "span.delay, span.delayOnTime" ) ;
2020-09-19 20:59:27 +02:00
if ( relation _departure _current != null ) {
2020-09-19 20:09:43 +02:00
data [ i ] [ "from" ] [ "time_current" ] = relation _departure _current . innerText . trim ( ) ;
}
2020-09-19 20:22:08 +02:00
// Arrival time & current estimation
2020-09-19 20:09:43 +02:00
var relation _arrival = relationend . querySelector ( "td.time" ) ;
var relation _arrival _list = relation _arrival . firstChild . textContent . trim ( ) . split ( " " ) ;
data [ i ] [ "to" ] [ "time" ] = relation _arrival _list [ 1 ] ;
data [ i ] [ "to" ] [ "time_current" ] = null ;
var relation _arrival _current = relation _arrival . querySelector ( "span.delay, span.delayOnTime" ) ;
2020-09-19 20:59:27 +02:00
if ( relation _arrival _current != null ) {
2020-09-19 20:09:43 +02:00
data [ i ] [ "to" ] [ "time_current" ] = relation _arrival _current . innerText . trim ( ) ;
}
2020-09-19 20:22:08 +02:00
// Departure platform
2020-09-19 20:09:43 +02:00
var relation _platform = relation . querySelector ( "td.platform" ) ;
data [ i ] [ "from" ] [ "platform" ] = relation _platform . innerText ;
2020-09-19 20:22:08 +02:00
// Arrival platform
2020-09-19 20:09:43 +02:00
var relation _to _platform = relationend . querySelector ( "td.platform" ) ;
data [ i ] [ "to" ] [ "platform" ] = relation _to _platform . innerText ;
2020-09-19 20:22:08 +02:00
// Travel products
2020-09-19 20:09:43 +02:00
var relation _products = relation . querySelector ( "td.products" ) ;
data [ i ] [ "products" ] = [ ] ;
2020-09-19 20:22:08 +02:00
// Fetch all products for this travel
2020-09-19 20:09:43 +02:00
var relation _trains = relation _products . querySelectorAll ( "span a" ) ;
relation _trains . forEach ( ( train , j ) => {
data [ i ] [ "products" ] [ j ] = { } ;
2020-09-19 20:22:08 +02:00
// Prodcut details
2020-09-19 20:09:43 +02:00
data [ i ] [ "products" ] [ j ] [ "product" ] = null ;
2020-09-19 23:06:19 +02:00
data [ i ] [ "products" ] [ j ] [ "train_id" ] = null ;
2020-09-19 20:09:43 +02:00
data [ i ] [ "products" ] [ j ] [ "train_number" ] = null ;
data [ i ] [ "products" ] [ j ] [ "line_name" ] = null ;
var name _list = train . innerText . trim ( ) . replace ( / +/g , ' ' ) . split ( " " ) ;
2020-09-19 20:22:08 +02:00
// Product name in format "STB 12 (23561)"
2020-09-19 20:09:43 +02:00
if ( name _list . length == 3 && name _list [ 2 ] . charAt ( 0 ) == '(' && name _list [ 2 ] . charAt ( name _list [ 2 ] . length - 1 ) == ')' ) {
data [ i ] [ "products" ] [ j ] [ "product" ] = name _list [ 0 ] ;
2020-09-19 23:06:19 +02:00
data [ i ] [ "products" ] [ j ] [ "train_id" ] = name _list [ 2 ] . substring ( 1 , name _list [ 2 ] . length - 1 )
2020-09-19 20:09:43 +02:00
data [ i ] [ "products" ] [ j ] [ "line_name" ] = name _list [ 0 ] + " " + name _list [ 1 ] ;
}
2020-09-19 20:22:08 +02:00
// Product name in format "ICE 234"
2020-09-19 20:09:43 +02:00
else {
data [ i ] [ "products" ] [ j ] [ "product" ] = name _list [ 0 ] ;
2020-09-19 23:06:19 +02:00
data [ i ] [ "products" ] [ j ] [ "train_id" ] = name _list [ 1 ] ;
2020-09-19 20:09:43 +02:00
}
2020-09-19 23:06:19 +02:00
data [ i ] [ "products" ] [ j ] [ "train_number" ] = data [ i ] [ "products" ] [ j ] [ "product" ] + " " + data [ i ] [ "products" ] [ j ] [ "train_id" ] ;
2020-09-19 20:09:43 +02:00
} ) ;
2020-09-19 20:22:08 +02:00
// Travel information
2020-09-19 20:09:43 +02:00
var relation _items = relation . querySelectorAll ( "td" ) ;
var relation _info = relation _items [ relation _items . length - 1 ] ;
data [ i ] [ "info" ] = relation _info . innerText ;
} ) ;
2020-09-19 21:38:23 +02:00
log ( "data collected" ) ;
2020-09-19 20:09:43 +02:00
console . log ( data ) ;
2020-09-19 20:11:06 +02:00
/ *
* INJECT CUSTOM UI
* /
2020-09-19 21:42:11 +02:00
var relations = timetable . querySelectorAll ( "tr.first" ) ;
relations . forEach ( ( relation , i ) => {
var relationend = relation . nextElementSibling ;
2020-09-19 20:11:06 +02:00
2020-09-19 21:42:11 +02:00
var products = relation . querySelectorAll ( "td.products span a" ) ;
products . forEach ( ( product , j ) => {
// Field for 'bahn-insight' stuff
var bahn _insight _field = domCreateBahnInsightField ( ) ;
product . after ( bahn _insight _field ) ;
2020-09-19 23:35:35 +02:00
var departure _time = new Date ( Date . parse ( connection _result _date + " " + data [ i ] [ "from" ] [ "time" ] ) ) ;
2020-09-19 21:42:11 +02:00
// Button linking to marudor.de
2020-09-19 23:35:35 +02:00
var marudor _button = domCreateButtonMarudor ( "/details/" + data [ i ] [ "products" ] [ j ] [ "train_number" ] + "/" + departure _time . getTime ( ) ) ;
2020-09-19 21:42:11 +02:00
bahn _insight _field . appendChild ( marudor _button ) ;
// Move linebreaks from link inner, after our 'bahn-insight' field
var linebreaks = product . querySelectorAll ( "br" ) ;
if ( linebreaks . length != 0 ) {
linebreaks . forEach ( ( linebreak ) => {
product . removeChild ( linebreak ) ;
} ) ;
bahn _insight _field . after ( domCreateLinebreak ( ) ) ;
2020-09-16 14:22:10 +02:00
}
2020-09-16 12:39:29 +02:00
} ) ;
2020-09-16 14:22:10 +02:00
2020-09-19 21:42:11 +02:00
var from = relation . querySelector ( "td.station" ) ;
var bahn _insight _field = domCreateBahnInsightField ( ) ;
from . appendChild ( bahn _insight _field ) ;
var marudor _button = domCreateButtonMarudor ( "/" + data [ i ] [ "from" ] [ "station" ] ) ;
bahn _insight _field . appendChild ( marudor _button ) ;
2020-09-19 21:43:42 +02:00
var dbf _button = domCreateButtonDbf ( "/" + data [ i ] [ "from" ] [ "station" ] ) ;
bahn _insight _field . appendChild ( dbf _button ) ;
2020-09-19 21:42:11 +02:00
var to = relationend . querySelector ( "td.station" ) ;
var bahn _insight _field = domCreateBahnInsightField ( ) ;
to . appendChild ( bahn _insight _field ) ;
var marudor _button = domCreateButtonMarudor ( "/" + data [ i ] [ "to" ] [ "station" ] ) ;
bahn _insight _field . appendChild ( marudor _button ) ;
2020-09-19 21:43:42 +02:00
var dbf _button = domCreateButtonDbf ( "/" + data [ i ] [ "to" ] [ "station" ] ) ;
bahn _insight _field . appendChild ( dbf _button ) ;
2020-09-16 14:22:10 +02:00
} ) ;
2020-09-16 12:39:29 +02:00
2020-09-19 21:38:23 +02:00
log ( "ui injected" ) ;
2020-09-16 12:39:29 +02:00
}
2020-09-16 14:22:10 +02:00
}
} ) ;
2020-09-16 12:39:29 +02:00
} ) ;
2020-09-16 13:03:05 +02:00
var target = document . getElementById ( 'resultsOverview' ) ;
if ( typeof target !== 'undefined' ) {
2020-09-19 23:02:42 +02:00
var connection _result _date = document . querySelector ( "html body div div div.resultContentHolder form div h2 span" ) . innerText . replace ( /(\d{2})\.(\d{2})\.(\d{2})/ , '20$3-$2-$1' ) ;
2020-09-16 14:19:31 +02:00
connection _result _observer . observe ( target , {
2020-09-16 13:03:05 +02:00
subtree : true ,
childList : true
} ) ;
2020-09-19 21:38:23 +02:00
log ( "observation started" )
2020-09-16 13:03:05 +02:00
}