您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Better readability, forever transactions retention and a chart display
// ==UserScript== // @name HSBC - Better Account History // @description Better readability, forever transactions retention and a chart display // @namespace http://github.com/jobwat/ // @author Joseph Boiteau // @version 2014.11.15 // @homepage https://github.com/jobwat/hsbc-account-history-rerender.user.js // @include https://*.hsbc.com/* // @include https://*.hsbc.com.au/* // @include https://*.hsbc.co.uk/* // @grant none // @require https://code.jquery.com/jquery-1.11.1.min.js // @require http://cdnjs.cloudflare.com/ajax/libs/flot/0.8.2/jquery.flot.min.js // @require http://cdnjs.cloudflare.com/ajax/libs/flot/0.8.2/jquery.flot.time.min.js // ==/UserScript== // this script is only for the "Account History" page if(document.getElementsByTagName('title')[0].text.match("Account History")){ // centering function used in final display // Thx Tony L. - http://stackoverflow.com/questions/210717/what-is-the-best-way-to-center-a-div-on-the-screen-using-jquery $.fn.center = function () { this.css("position","absolute"); this.css("top", ( $(window).height() - this.height() ) / 2+$(window).scrollTop() + "px"); this.css("left", ( $(window).width() - this.width() ) / 2+$(window).scrollLeft() + "px"); return this; }; // set some style (no need to have wide spaces around lines) $('<style type="text/css">table.hsbcTableStyle07 tr td{ padding:0px 5px 0px 5px; line-height: 1em; white-space: nowrap; } </style>').prependTo($('head')); var graphData = []; // array containing values for the graph var the_table = $("table.hsbcTableStyle07"); // the interesting table object of the page // We will first go through all lines of the table // Get their content, load our objects and rewrite all, but lighter clearTable = function(){ trs = $('tr', the_table); trs.each(function(index, tr){ if(index!==0 && index!=(trs.length-1)){ $(tr).addClass('to_del'); } }); $('tr.to_del', the_table).remove(); }; Line = function() { this.timestamp = undefined; }; Line.prototype.populate = function(line_data_array) { this.timestamp = line_data_array.timestamp; this.details = line_data_array.details; this.debit = line_data_array.debit; this.credit = line_data_array.credit; this.balance = line_data_array.balance; }; Line.prototype.setDate = function(dateString) { this.timestamp = new Date(dateString).getTime(); }; Line.prototype.hasDate = function() { return !(this.timestamp === undefined || isNaN(this.timestamp)); }; Line.prototype.getDate = function(){ // reformat the date column if(this.hasDate()){ date = new Date(this.timestamp); return '<span style="float:right">'+weekdayArray[date.getDay()]+', '+date.getDate()+' '+monthArray[date.getMonth()].slice(0,3)+' '+date.getFullYear()+'</span>'; } else{ return undefined; } }; Line.prototype.setDetails = function(detailsHTML) { // remove some non-useful data from details column and make it 1 line only tmp=detailsHTML.split('<br>'); this.details = this.cleanStrings(tmp[0] + ' - ' + tmp[2] + ' - ' + tmp[3] + ' ' + tmp[4]); }; Line.prototype.getDetails = function(){ return this.details; }; Line.prototype.setDebit = function(debit){ this.debit = this.cleanAmounts(debit); }; Line.prototype.getDebit = function(){ return this.displayDigits(this.emptyIfZero(this.debit)); }; Line.prototype.setCredit = function(credit){ this.credit = this.cleanAmounts(credit); }; Line.prototype.getCredit = function(){ return this.displayDigits(this.emptyIfZero(this.credit)); }; Line.prototype.setBalance = function(balance){ this.balance = this.cleanAmounts(balance); }; Line.prototype.getBalance = function(){ return this.displayDigits(this.balance); }; Line.prototype.cleanAmounts = function(value){ tmp = parseFloat(this.cleanStrings(value).replace(/[^0-9\.]/g,'')); if(isNaN(tmp)) return 0; else return tmp; }; Line.prototype.cleanStrings = function(value){ return value.replace(/[\t\n\r ]+/g,' '); }; Line.prototype.displayDigits = function(value){ return value.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,"); }; Line.prototype.emptyIfZero = function(value){ if(value===0) return ' '; else return value+' '; }; History = function(){ this.lines = []; }; History.prototype.add = function(line){ this.lines.push(line); }; History.prototype.toJSON = function(){ return JSON.stringify(this.lines); }; History.prototype.merge = function(anotherHistory){ var merged = $.merge(this.lines, anotherHistory.lines); merged.sort(function(a,b){ if(a.timestamp < b.timestamp) return 1; else if(a.timestamp > b.timestamp) return -1; else{ if(a.balance == b.balance + b.credit) return 1; if(a.balance == b.balance - b.debit) return 1; return -1; } }); var ind = 1; while(ind < merged.length){ if(merged[ind-1].timestamp == merged[ind].timestamp && merged[ind-1].details == merged[ind].details){ merged.splice(ind, 1); } else ind++; } this.lines = merged; }; History.prototype.testMerge = function(){ console.log('before merge: ' + this.lines.length + 'lines'); history.merge(this); console.log('after merge: ' + this.lines.length + 'lines'); }; History.prototype.displayAll = function(){ clearTable(); last_tr = $('tr', the_table).last(); // the greyed line with sorting arrows at the bottom $(this.lines).each(function(index, line_data_array){ var line = new Line(); line.populate(line_data_array); graphData.push([line.timestamp, line.balance]); /*jshint multistr: true */ tr = $('<tr class="hsbcTableRow0'+((index%2===0)?'3':'4')+'">\ <td class="hsbcTableColumn03" headers="header1">'+line.getDate()+'</td>\ <td class="" headers="header2">'+line.getDetails()+'</td>\ <td class="hsbcTableColumn03" headers="header3">'+line.getDebit()+'</td>\ <td class="hsbcTableColumn03" headers="header4">'+line.getCredit()+'</td>\ <td class="hsbcTableColumn03" headers="header5">'+line.getBalance()+'</td>\ <td class="hsbcTableColumn03" headers="header6"> </td>\ </tr>'); tr.insertBefore(last_tr); }); }; var previous_history = new History(); var account_history = new History(); // recover the account name var account_name = $('#LongSelection1 option[value="'+$('#LongSelection1').val()+'"]').text().replace(/[^a-zA-Z]/g, ''); console.log('account_name: ', account_name); // recover existing history previous_history_JSON = localStorage.getItem(account_name); if (previous_history_JSON){ previous_history.lines = JSON.parse(previous_history_JSON); console.log('previous history from localStorage: ', previous_history.lines.length); } else{ previous_history.lines = []; } // Drop the right panel containing mostly ads $('.containerRightTools').remove(); // loop through table lines var prev_line = new Line(); $.each($("tr", the_table), function(TRind, TRval) { // each tr line = new Line(); var mytd = $(this).children("td").each(function(index, td){ // each td if(td.headers=="header1"){ // the date line.setDate(td.innerHTML); if(line.hasDate()){ td.innerHTML=line.getDate(); } else { return false; } } else if(td.headers=="header2"){ // the details line.setDetails(td.innerHTML); if(line.getDetails() == prev_line.getDetails()){ line.details = prev_line.getDetails() + ' (2x)'; } td.innerHTML = line.getDetails(); } else if(td.headers=="header3"){ // debit line.setDebit(td.innerHTML); td.innerHTML = line.getDebit(); } else if(td.headers=="header4"){ // credit line.setCredit(td.innerHTML); td.innerHTML = line.getCredit(); } else if(td.headers=="header5"){ // balance line.setBalance(td.innerHTML); td.innerHTML = line.getBalance(); } else if(td.headers=="header6"){ // empty last column td.innerHTML = account_history.lines.length + 1; } }); if(line.getDate()!==undefined && line.getBalance()!==undefined){ // the first and last tr of the array are the sorting arrows account_history.add(line); } prev_line = line; }); console.log('lines parsed: ', account_history.lines.length); // merging previous history with actual one and save it locally //account_history.merge(previous_history); // saving new merged history to localStorage localStorage.setItem(account_name, JSON.stringify(account_history.lines)); console.log('lines saved after merge: ', account_history.lines.length); // rewrite the whole thing account_history.displayAll(); // 2e part: draw a chart // add a div somewhere in the DOM $('<div id="chartwrap" style="border: 1px solid #AAA; background-color:white; position: absolute;"></div>').appendTo("body"); $('<div id="placeholder" style="width:650px; height:300px;"></div>').appendTo("#chartwrap"); // draw the chart in its div // TODO: do way better ! watch here: http://people.iola.dk/olau/flot/examples/stacking.html $.plot("#placeholder", [graphData], { xaxis: { mode: "time" } }); toggleChartDisplay = function(show_or_hide){ if($("#chartwrap").is(':hidden')) $("#chartwrap").center(); $("#chartwrap").toggle(show_or_hide); }; // display a button to toggle chart visibility $('<a class="hsbcLinkStyle06">Display chart</a>') .prependTo($('td.hsbcTableColumn03')[0]) .css('cursor', 'pointer') .click(toggleChartDisplay); // click on the chart hides it $('#placeholder').click(toggleChartDisplay); // start with Chart hidden toggleChartDisplay(false); }