2 GLib = imports.gi.GLib;
3 WebKit = imports.gi.WebKit;
4 Soup = imports.gi.Soup;
6 TabbedBrowser = imports.TabbedBrowser;
7 BrowserSettings = imports.BrowserSettings;
8 BrowserTab = imports.BrowserTab;
10 File = imports.File.File;
12 base64 = imports.base64.base64;
14 BrowserView = new GType({
15 parent: WebKit.WebView.type,
21 var sess = WebKit.get_default_session();
22 sess.proxy_uri = new Soup.URI.c_new('http://localhost:3128');
26 var browsePage = false;
32 var update_title = function (web_view, web_frame, title)
35 print("calling update title");
37 title = title.slice(0,25) + "...";
39 tab.get_tab_label().label = title;
46 var traversedom = function(doc, fn, sub ) {
47 print("TRAVERSE DOM?");
52 var cb = function(s) {
62 //Roo.select('body > div',true).each(function(el) {
63 traverseDOMTree(cb, doc.head, 1);
64 traverseDOMTree(cb, doc.body, 1);
66 File.write(cb.fn.replace(/\.html$/, '')+ (sub ? ('.' + sub ) : '') + '.html' , ret +'</HTML>');
72 var traverseDOMTree = function(cb, currentElement, depth) {
75 //if (currentElement.class_name.match(/roo-dynamic/)) {
78 //print(currentElement.node_name);
80 var nodeName = currentElement.node_name;
81 var tagName = currentElement.tag_name;
83 if (nodeName == '#text') {
84 cb(currentElement.node_value);
93 if (nodeName == 'SCRIPT') {
97 //if (nodeName == 'STYLE') { return; }
99 // Prints the node tagName, such as <A>, <IMG>, etc
100 var outNodeName = nodeName;
101 if (nodeName == 'IFRAME') {
102 //outNodeName = 'DIV';
111 for(i = 0; i < currentElement.attributes.length;i++) {
112 var aname = currentElement.attributes.item(i).name;
113 //if (aname =='class' || aname == 'style') {
116 if (aname =='src' && tagName == 'IFRAME') {
120 attr.push(aname + '="' + currentElement.attributes.item(i).value + '"' );
122 if (tagName == 'IFRAME') {
123 attr.push('src="' + File.basename(cb.fn).replace(/\.html$/, '')+ '.' + cb.sub + '.html"' );
126 //if (nodeName == 'IFRAME') {
127 // attr.push('src="' + currentElement.attributes.item(i).value + embeded_file '"' );
130 //var style = elClassToStyle(currentElement);
131 //if (style.length) {
132 // attr.push('style="' + style + '"' );
136 //if (depth > 1000 && (tagName == 'BODY' || tagName == 'HEAD' )) {
137 // cb("<DIV"+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
139 cb("<"+outNodeName + ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
147 if (nodeName == 'IFRAME') {
150 traversedom(currentElement.content_document, cb.fn, cb.sub )
159 var currentElementChild = currentElement.child_nodes.item(i);
161 while (currentElementChild) {
162 // Formatting code (indent the tree so it looks nice on the screen)
164 if (currentElementChild.node_name == '#text') {
165 // if (currentElementChild.node_value.length) {
166 cb(currentElementChild.node_value);
170 currentElementChild=currentElement.child_nodes.item(i);
175 //for (j = 0; j < depth; j++) {
176 // ¦ is just a vertical line
181 // Recursively traverse the tree structure of the child node
182 traverseDOMTree(cb, currentElementChild, depth+1);
184 currentElementChild=currentElement.child_nodes.item(i);
187 // The remaining code is mostly for formatting the tree
189 //for (j = 0; j < depth - 1; j++) {
194 // if (depth > 1000 && (tagName == 'BODY' || tagName == 'HEAD' )) {
197 cb("</"+outNodeName+">");
205 var update_url = function (web_view, web_frame)
207 var toolbar = tab.get_toolbar();
209 toolbar.set_url(web_frame.get_uri());
210 toolbar.set_can_go_back(web_view.can_go_back());
211 toolbar.set_can_go_forward(web_view.can_go_forward());
221 var create_new_tab = function (web_view, web_frame, new_web_view)
223 new_web_view = new BrowserView();
224 new_web_view.signal.web_view_ready.connect(show_new_tab);
228 var show_new_tab = function (new_web_view)
230 TabbedBrowser.browser.new_tab("", new_web_view);
235 var hover_link = function (web_view, link, url)
237 tab.get_statusbar().set_status(url);
242 this.add_inject = function(force)
245 if (force || (typeof(injected[this.uri]) == 'undefined' )) {
246 injected[this.uri] = 0;
248 if (injected[this.uri] > 2) {
251 injected[this.uri]++;
252 var fn = __script_path__ + "/inject.js";
253 if (File.exists(fn)) {
254 // print("Adding inject");
255 var newjs = File.read(__script_path__ + "/inject.js");
256 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
264 var after_login = false;
267 var load_finished_called = false;
269 var done_print = false;
270 var do_print = function(web_frame) {
274 print("do_print called -- while already doing this...");
278 print("do_print called");
281 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
282 File.read( __script_path__ + "/domains/remove_print_css.js")
285 var url_p = current_url.split('/');
287 var dom_p = url_p[2].split('.');
288 var chk = dom_p.pop();
289 chk = dom_p.pop() + '.' + chk;
293 print("CHECK: " + chk +"\n");
295 if (current_url.match(/\.coconuts\.co\//) ) {
296 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
297 File.read( __script_path__ + "/domains/coconuts.co.js")
301 if (current_url.match(/\.itnewsafrica\.com\//) ) {
302 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
303 File.read( __script_path__ + "/domains/itnewsafrica.com.js")
306 if (current_url.match(/\.indiatimes\.com\//) ) {
307 print("running indiatimes code");
308 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
309 File.read( __script_path__ + "/domains/indiatimes.com.js")
313 if (current_url.match(/\.inquirer\.net\//) ) {
314 print("add inquirer.net code");
315 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
316 File.read( __script_path__ + "/domains/inquirer.net.js")
320 if (current_url.match(/\.puntocellulare\.it\//) ) {
321 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
322 File.read( __script_path__ + "/domains/puntocellulare.it.js")
327 // motorme - requires a scroll to make content appear..
328 if (current_url.match(/\.motorme\.my\//) ) {
329 TabbedBrowser.browser.current_tab().get_web_view().execute_script("window.scrollTo(0,500);");
333 if (current_url.match(/\.efytimes\.com\//) || current_url.match(/\/efytimes\.com\//) ) {
334 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
335 File.read( __script_path__ + "/domains/efytimes.com.js")
340 print("Delay:" + BrowserSettings.delay);
342 GLib.timeout_add(GLib.PRIORITY_DEFAULT, BrowserSettings.delay *1, function() {
346 if (current_url.match(/theindependent\.sg\//) ) {
347 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
348 File.read( __script_path__ + "/domains/theindependent.sg.js")
354 if (web_frame && BrowserSettings.export_filename_html ) {
355 var html = traversedom(web_frame.get_dom_document(), BrowserSettings.export_filename_html);
356 //File.write(BrowserSettings.export_filename_html, html);
360 if (!BrowserSettings.export_filename) {
361 if (!BrowserSettings.export_filename_html) {
362 print("no export filename / and html filename");
368 var mf = _t.get_main_frame();
370 print("Creating paper");
371 var ar = Gtk.PaperSize.get_paper_sizes();
372 var psetup = new Gtk.PageSetup();
373 for(var i = 0; i < ar.length; i++) {
374 if (ar[i].get_name() =='iso_a2') {
375 psetup.set_paper_size(ar[i]);
378 print("doing print operation");
379 var p = new Gtk.PrintOperation({ export_filename : BrowserSettings.export_filename });
380 print("doing print operation - set page");
382 p.set_default_page_setup(psetup);
384 print("doing print operation - print_full");
385 mf.print_full(p, Gtk.PrintOperationAction.EXPORT);
386 print("made image - exiting");
391 print("error occured");
392 print(JSON.stringify(e));
398 var weibo_added = false;
400 var is_weibo = false;
403 var load_finished = function (webkit, web_frame, wb)
414 print("load finished");
417 if (after_login === true) {
423 if (after_login === false) {
426 print("adding timeout?");
428 GLib.timeout_add(GLib.PRIORITY_LOW, 2000, function() {
429 print("Redirecting after login?" + after_login);
431 _t.browse(after_login);
438 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
439 File.read( __script_path__ + "/weibo.js")
441 print("run_weibo(" + JSON.stringify( BrowserSettings.username ) + ", " + JSON.stringify(BrowserSettings.passwd) + ");");
443 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
444 "run_weibo(" + JSON.stringify( BrowserSettings.username ) + ", " + JSON.stringify(BrowserSettings.passwd) + ");"
450 if (after_login !== false) {
453 // wait a bit then load the real page..
454 GLib.timeout_add(GLib.PRIORITY_LOW, 500, function() {
455 print("Redirecting after login?");
456 _t.browse(after_login);
462 if (load_finished_called) {
466 load_finished_called = true;
470 // if(document.location.host=='weibo.com') {
471 // // clear login dialog from weibo.
472 // //check and hidden the login dialog and overlay .....
473 // var els = document.querySelectorAll('div[node-type]');
475 // for (i = 0; i < els.length; i++) {
476 // if (els[i].hasAttribute('node-type')) {
477 // if(els[i].getAttribute('node-type') == 'outer'){
482 // for (i = 0; i < bbc.length; i++) {// hide all the outer.....
483 // bbc[i].style.display = 'none';
487 // if(document.location.pathname == '/login.php'){
489 // // fills in the user name and password
490 // var els = document.querySelectorAll('input[node-type]');
492 // for (i = 0; i < els.length; i++) {
493 // if (els[i].hasAttribute('node-type')) {
494 // if(els[i].getAttribute('node-type') == 'username'){
495 // els[i].value = BrowserSettings.username;
497 // if(els[i].getAttribute('node-type') == 'password'){
498 // els[i].value = BrowserSettings.passwd;
504 // // simulating click event to login ....
505 // var elss = document.querySelectorAll('a[node-type]');
507 // for (i = 0; i < elss.length; i++) {
508 // if (elss[i].hasAttribute('node-type')) {
509 // if(elss[i].getAttribute('node-type') == 'submitBtn'){
521 // clear login dialog from weibo.
522 // TabbedBrowser.browser.current_tab().get_web_view().execute_script(
523 // " if (document.location.host=='weibo.com') { " +
525 // " var a = document.getElementsByClassName('W_layer')[0]; " +
526 // " a.parentNode.removeChild(a.previousSibling); " +
527 // " a.parentNode.removeChild(a); " +
528 // " } catch(e) { } } " );
532 GLib.timeout_add(GLib.PRIORITY_LOW, BrowserSettings.delay, function() {
534 var mf = _t.get_main_frame();
536 var ar = Gtk.PaperSize.get_paper_sizes();
537 var psetup = new Gtk.PageSetup();
538 for(var i = 0; i < ar.length; i++) {
539 if (ar[i].get_name() =='iso_a2') {
540 psetup.set_paper_size(ar[i]);
544 var p = new Gtk.PrintOperation({ export_filename : BrowserSettings.export_filename });
545 p.set_default_page_setup(psetup);
546 mf.print_full(p, Gtk.PrintOperationAction.EXPORT);
547 print("made image - exiting");
559 var load_committed = function (web_view, web_frame)
561 print("load commited");
563 update_url(web_view, web_frame);
565 // call load finished after 20seconds??
566 // so even if it never complets we try and print the thing.
567 GLib.timeout_add(GLib.PRIORITY_LOW, 40000, function() {
568 print("load commited - 3000 ms?");
574 var clicked_link = function (web_view, web_frame, request,
575 action, decision, window)
577 if(action.get_reason() == WebKit.WebNavigationReason.LINK_CLICKED &&
578 action.get_button() == 2)
580 browser.new_tab(request.get_uri(), null);
590 this.browse = function (url)
592 if(url.search("://") < 0)
593 url = "http://" + url;
597 print("BROWSE: " + url);
598 if (url.match(/\/weibo\.com\//) && after_login === false) {
601 url = "http://weibo.com/login.php";
603 else if (url.match(/\/weibo\.com\//) && after_login !== false) {
606 print("BROWSE -really: " + url);
610 this.set_tab = function (new_tab)
615 this.get_tab = function ()
622 //this.set_scroll_adjustments(null, null);
624 //this.signal.title_changed.connect(update_title);
625 //this.signal.load_committed.connect(load_committed);
626 this.signal.load_finished.connect(load_finished);
629 // For some reason, this segfaults seed in the instance init closure handler
630 // Once that's fixed, uncommenting the next line will give middle-click-open-in-new tab
631 //this.signal.navigation_policy_decision_requested.connect(clicked_link);
633 //this.signal.hovering_over_link.connect(hover_link);
635 this.signal.create_web_view.connect(create_new_tab);
639 // print("ADDing console message sig handler");
644 this.toFilename = function(url)
646 url = url.replace(/^http[s]*:\/\//, '');
647 var p = url.split('/');
648 p.unshift(storedir+'/output');
649 for (var i =1 ;i < p.length; i++) {
650 p[i] = encodeURIComponent(p[i]);
653 p[p.length-1] = decodeURIComponent(p[p.length-1]);
655 var dir = File.dirname(ret);
660 this.checkdomain = function(comp)
662 var b = parseUri(this.uri);
663 var d = parseUri(comp);
664 return (d.host == b.host && d.protocol == b.protocol);
669 this.dupeCheck = function(url)
672 // order - return highest up the queue first..
673 if (File.exists(downloaddir +'/' + encodeURIComponent(url))) {
674 return downloaddir +'/' + encodeURIComponent(url);
676 if (File.exists(parsedir +'/' + encodeURIComponent(url))) {
677 return parsedir +'/' + encodeURIComponent(url);
679 if (File.exists(donedir +'/' + encodeURIComponent(url))) {
680 return donedir +'/' + encodeURIComponent(url);
686 this.moveToParse = function(url)
688 var old = this.dupeCheck(url);
689 var target =parsedir +'/' + encodeURIComponent(url);
693 File.write(target, old ? File.read(old) : '');
700 this.moveToDownload= function(url)
702 var old = this.dupeCheck(url);
703 var target =downloaddir +'/' + encodeURIComponent(url);
707 File.write(target, old ? File.read(old) : '');
713 this.moveToDone= function(url)
715 var old = this.dupeCheck(url);
716 var target = donedir +'/' + encodeURIComponent(url);
720 File.write(target, old ? File.read(old) : '');
730 function parseUri (str) {
731 var o = parseUri.options,
732 m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
736 while (i--) uri[o.key[i]] = m[i] || "";
739 uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
740 if ($1) uri[o.q.name][$1] = $2;
748 key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
751 parser: /(?:^|&)([^&=]*)=?([^&]*)/g
754 strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
755 loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/