2 GLib = imports.gi.GLib;
3 WebKit = imports.gi.WebKit;
5 TabbedBrowser = imports.TabbedBrowser;
6 BrowserSettings = imports.BrowserSettings;
7 BrowserTab = imports.BrowserTab;
9 File = imports.File.File;
11 base64 = imports.base64.base64;
13 BrowserView = new GType({
14 parent: WebKit.WebView.type,
24 var browsePage = false;
30 var update_title = function (web_view, web_frame, title)
33 print("calling update title");
35 title = title.slice(0,25) + "...";
37 tab.get_tab_label().label = title;
44 var traversedom = function(doc, fn, sub ) {
45 //print("TRAVERSE DOM?");
50 var cb = function(s) {
60 //Roo.select('body > div',true).each(function(el) {
61 traverseDOMTree(cb, doc.head, 1);
62 traverseDOMTree(cb, doc.body, 1);
64 File.write(cb.fn.replace(/\.html$/, '')+ (sub ? ('.' + sub ) : '') + '.html' , ret +'</HTML>');
70 var traverseDOMTree = function(cb, currentElement, depth) {
73 //if (currentElement.class_name.match(/roo-dynamic/)) {
76 //print(currentElement.node_name);
78 var nodeName = currentElement.node_name;
79 var tagName = currentElement.tag_name;
81 if (nodeName == '#text') {
82 cb(currentElement.node_value);
91 if (nodeName == 'SCRIPT') {
95 //if (nodeName == 'STYLE') { return; }
97 // Prints the node tagName, such as <A>, <IMG>, etc
98 var outNodeName = nodeName;
99 if (nodeName == 'IFRAME') {
100 //outNodeName = 'DIV';
109 for(i = 0; i < currentElement.attributes.length;i++) {
110 var aname = currentElement.attributes.item(i).name;
111 //if (aname =='class' || aname == 'style') {
114 if (aname =='src' && tagName == 'IFRAME') {
118 attr.push(aname + '="' + currentElement.attributes.item(i).value + '"' );
120 if (tagName == 'IFRAME') {
121 attr.push('src="' + File.basename(cb.fn).replace(/\.html$/, '')+ '.' + cb.sub + '.html"' );
124 //if (nodeName == 'IFRAME') {
125 // attr.push('src="' + currentElement.attributes.item(i).value + embeded_file '"' );
128 //var style = elClassToStyle(currentElement);
129 //if (style.length) {
130 // attr.push('style="' + style + '"' );
134 //if (depth > 1000 && (tagName == 'BODY' || tagName == 'HEAD' )) {
135 // cb("<DIV"+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
137 cb("<"+outNodeName + ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
145 if (nodeName == 'IFRAME') {
148 traversedom(currentElement.content_document, cb.fn, cb.sub )
157 var currentElementChild = currentElement.child_nodes.item(i);
159 while (currentElementChild) {
160 // Formatting code (indent the tree so it looks nice on the screen)
162 if (currentElementChild.node_name == '#text') {
163 // if (currentElementChild.node_value.length) {
164 cb(currentElementChild.node_value);
168 currentElementChild=currentElement.child_nodes.item(i);
173 //for (j = 0; j < depth; j++) {
174 // ¦ is just a vertical line
179 // Recursively traverse the tree structure of the child node
180 traverseDOMTree(cb, currentElementChild, depth+1);
182 currentElementChild=currentElement.child_nodes.item(i);
185 // The remaining code is mostly for formatting the tree
187 //for (j = 0; j < depth - 1; j++) {
192 // if (depth > 1000 && (tagName == 'BODY' || tagName == 'HEAD' )) {
195 cb("</"+outNodeName+">");
203 var update_url = function (web_view, web_frame)
205 var toolbar = tab.get_toolbar();
207 toolbar.set_url(web_frame.get_uri());
208 toolbar.set_can_go_back(web_view.can_go_back());
209 toolbar.set_can_go_forward(web_view.can_go_forward());
219 var create_new_tab = function (web_view, web_frame, new_web_view)
221 new_web_view = new BrowserView();
222 new_web_view.signal.web_view_ready.connect(show_new_tab);
226 var show_new_tab = function (new_web_view)
228 TabbedBrowser.browser.new_tab("", new_web_view);
233 var hover_link = function (web_view, link, url)
235 tab.get_statusbar().set_status(url);
240 this.add_inject = function(force)
243 if (force || (typeof(injected[this.uri]) == 'undefined' )) {
244 injected[this.uri] = 0;
246 if (injected[this.uri] > 2) {
249 injected[this.uri]++;
250 var fn = __script_path__ + "/inject.js";
251 if (File.exists(fn)) {
252 // print("Adding inject");
253 var newjs = File.read(__script_path__ + "/inject.js");
254 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
262 var after_login = false;
265 var load_finished_called = false;
268 var do_print = function(web_frame) {
272 var scr_a = " var r = document.getElementsByTagName('link');" +
273 "for (var i=0;i < r.length;i++) { " +
275 "if ( a.getAttribute('media') == '') { continue; } " +
276 "if ( a.getAttribute('media') == 'screen') { "+
277 "a.removeAttribute('media'); continue;" +
279 //"a.parentNode.removeChild(a);" +
281 var scr_b = "var a = document.body.querySelectorAll('*'); "+
283 "for(var i =i;i<a.length;i++) { "+
284 " var cs = window.getComputedStyle(a[i],null);"+
285 " if ('none' == cs.display) {"+
286 " dnodes.push(a[i]); "+
289 "console.log(dnodes.length);" +
290 "dnodes.forEach(function(n) { "+
291 " try { n.parentNode.removeChild(n); } catch(e) { } "+
295 //TabbedBrowser.browser.current_tab().get_web_view().execute_script(
299 //TabbedBrowser.browser.current_tab().get_web_view().execute_script(
303 if (current_url.match(/\.coconuts\.co\//) ) {
304 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
305 File.read( __script_path__ + "/domains/coconuts.co.js")
309 // motorme - requires a scroll to make content appear..
310 if (current_url.match(/\.motorme\.my\//) ) {
311 TabbedBrowser.browser.current_tab().get_web_view().execute_script("window.scrollTo(0,500)");
316 window.scrollTo(0,500)
317 print("Delay:" + BrowserSettings.delay);
319 GLib.timeout_add(GLib.PRIORITY_LOW, BrowserSettings.delay *1, function() {
323 if (web_frame && BrowserSettings.export_filename_html ) {
324 var html = traversedom(web_frame.get_dom_document(), BrowserSettings.export_filename_html);
325 //File.write(BrowserSettings.export_filename_html, html);
329 if (!BrowserSettings.export_filename) {
330 if (!BrowserSettings.export_filename_html) {
336 var mf = _t.get_main_frame();
339 var ar = Gtk.PaperSize.get_paper_sizes();
340 var psetup = new Gtk.PageSetup();
341 for(var i = 0; i < ar.length; i++) {
342 if (ar[i].get_name() =='iso_a2') {
343 psetup.set_paper_size(ar[i]);
347 var p = new Gtk.PrintOperation({ export_filename : BrowserSettings.export_filename });
348 p.set_default_page_setup(psetup);
349 mf.print_full(p, Gtk.PrintOperationAction.EXPORT);
350 print("made image - exiting");
358 var weibo_added = false;
360 var is_weibo = false;
363 var load_finished = function (webkit, web_frame, wb)
374 print("load finished");
377 if (after_login === true) {
383 if (after_login === false) {
386 print("adding timeout?");
388 GLib.timeout_add(GLib.PRIORITY_LOW, 2000, function() {
389 print("Redirecting after login?" + after_login);
391 _t.browse(after_login);
398 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
399 File.read( __script_path__ + "/weibo.js")
401 print("run_weibo(" + JSON.stringify( BrowserSettings.username ) + ", " + JSON.stringify(BrowserSettings.passwd) + ");");
403 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
404 "run_weibo(" + JSON.stringify( BrowserSettings.username ) + ", " + JSON.stringify(BrowserSettings.passwd) + ");"
410 if (after_login !== false) {
413 // wait a bit then load the real page..
414 GLib.timeout_add(GLib.PRIORITY_LOW, 500, function() {
415 print("Redirecting after login?");
416 _t.browse(after_login);
422 if (load_finished_called) {
426 load_finished_called = true;
430 // if(document.location.host=='weibo.com') {
431 // // clear login dialog from weibo.
432 // //check and hidden the login dialog and overlay .....
433 // var els = document.querySelectorAll('div[node-type]');
435 // for (i = 0; i < els.length; i++) {
436 // if (els[i].hasAttribute('node-type')) {
437 // if(els[i].getAttribute('node-type') == 'outer'){
442 // for (i = 0; i < bbc.length; i++) {// hide all the outer.....
443 // bbc[i].style.display = 'none';
447 // if(document.location.pathname == '/login.php'){
449 // // fills in the user name and password
450 // var els = document.querySelectorAll('input[node-type]');
452 // for (i = 0; i < els.length; i++) {
453 // if (els[i].hasAttribute('node-type')) {
454 // if(els[i].getAttribute('node-type') == 'username'){
455 // els[i].value = BrowserSettings.username;
457 // if(els[i].getAttribute('node-type') == 'password'){
458 // els[i].value = BrowserSettings.passwd;
464 // // simulating click event to login ....
465 // var elss = document.querySelectorAll('a[node-type]');
467 // for (i = 0; i < elss.length; i++) {
468 // if (elss[i].hasAttribute('node-type')) {
469 // if(elss[i].getAttribute('node-type') == 'submitBtn'){
481 // clear login dialog from weibo.
482 // TabbedBrowser.browser.current_tab().get_web_view().execute_script(
483 // " if (document.location.host=='weibo.com') { " +
485 // " var a = document.getElementsByClassName('W_layer')[0]; " +
486 // " a.parentNode.removeChild(a.previousSibling); " +
487 // " a.parentNode.removeChild(a); " +
488 // " } catch(e) { } } " );
492 GLib.timeout_add(GLib.PRIORITY_LOW, BrowserSettings.delay, function() {
494 var mf = _t.get_main_frame();
496 var ar = Gtk.PaperSize.get_paper_sizes();
497 var psetup = new Gtk.PageSetup();
498 for(var i = 0; i < ar.length; i++) {
499 if (ar[i].get_name() =='iso_a2') {
500 psetup.set_paper_size(ar[i]);
504 var p = new Gtk.PrintOperation({ export_filename : BrowserSettings.export_filename });
505 p.set_default_page_setup(psetup);
506 mf.print_full(p, Gtk.PrintOperationAction.EXPORT);
507 print("made image - exiting");
519 var load_committed = function (web_view, web_frame)
521 print("load commited");
523 update_url(web_view, web_frame);
525 // call load finished after 20seconds??
526 // so even if it never complets we try and print the thing.
527 GLib.timeout_add(GLib.PRIORITY_LOW, 40000, function() {
528 print("load commited - 3000 ms?");
534 var clicked_link = function (web_view, web_frame, request,
535 action, decision, window)
537 if(action.get_reason() == WebKit.WebNavigationReason.LINK_CLICKED &&
538 action.get_button() == 2)
540 browser.new_tab(request.get_uri(), null);
550 this.browse = function (url)
552 if(url.search("://") < 0)
553 url = "http://" + url;
557 print("BROWSE: " + url);
558 if (url.match(/\/weibo\.com\//) && after_login === false) {
561 url = "http://weibo.com/login.php";
563 else if (url.match(/\/weibo\.com\//) && after_login !== false) {
566 print("BROWSE -really: " + url);
570 this.set_tab = function (new_tab)
575 this.get_tab = function ()
582 //this.set_scroll_adjustments(null, null);
584 //this.signal.title_changed.connect(update_title);
585 //this.signal.load_committed.connect(load_committed);
586 this.signal.load_finished.connect(load_finished);
589 // For some reason, this segfaults seed in the instance init closure handler
590 // Once that's fixed, uncommenting the next line will give middle-click-open-in-new tab
591 //this.signal.navigation_policy_decision_requested.connect(clicked_link);
593 //this.signal.hovering_over_link.connect(hover_link);
595 this.signal.create_web_view.connect(create_new_tab);
599 // print("ADDing console message sig handler");
604 this.toFilename = function(url)
606 url = url.replace(/^http[s]*:\/\//, '');
607 var p = url.split('/');
608 p.unshift(storedir+'/output');
609 for (var i =1 ;i < p.length; i++) {
610 p[i] = encodeURIComponent(p[i]);
613 p[p.length-1] = decodeURIComponent(p[p.length-1]);
615 var dir = File.dirname(ret);
620 this.checkdomain = function(comp)
622 var b = parseUri(this.uri);
623 var d = parseUri(comp);
624 return (d.host == b.host && d.protocol == b.protocol);
629 this.dupeCheck = function(url)
632 // order - return highest up the queue first..
633 if (File.exists(downloaddir +'/' + encodeURIComponent(url))) {
634 return downloaddir +'/' + encodeURIComponent(url);
636 if (File.exists(parsedir +'/' + encodeURIComponent(url))) {
637 return parsedir +'/' + encodeURIComponent(url);
639 if (File.exists(donedir +'/' + encodeURIComponent(url))) {
640 return donedir +'/' + encodeURIComponent(url);
646 this.moveToParse = function(url)
648 var old = this.dupeCheck(url);
649 var target =parsedir +'/' + encodeURIComponent(url);
653 File.write(target, old ? File.read(old) : '');
660 this.moveToDownload= function(url)
662 var old = this.dupeCheck(url);
663 var target =downloaddir +'/' + encodeURIComponent(url);
667 File.write(target, old ? File.read(old) : '');
673 this.moveToDone= function(url)
675 var old = this.dupeCheck(url);
676 var target = donedir +'/' + encodeURIComponent(url);
680 File.write(target, old ? File.read(old) : '');
690 function parseUri (str) {
691 var o = parseUri.options,
692 m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
696 while (i--) uri[o.key[i]] = m[i] || "";
699 uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
700 if ($1) uri[o.q.name][$1] = $2;
708 key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
711 parser: /(?:^|&)([^&=]*)=?([^&]*)/g
714 strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
715 loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/