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;
51 var traversedom = function(web_frame) {
52 //print("TRAVERSE DOM?");
54 var dom = web_frame.get_dom_document();
57 var cb = function(s) {
62 curdoc = web_frame.get_dom_document();
63 //Roo.select('body > div',true).each(function(el) {
64 traverseDOMTree(cb, dom.head, 1);
65 traverseDOMTree(cb, dom.body, 1);
67 return ret +'</HTML>';
74 var elClassToStyle = function(el)
82 var def = bd.document_element.append_child( bd.create_element(el.node_name));
85 var par_ds = el.node_name == 'BODY' ? false : bd.get_default_view().get_computed_style(el.parent_node, '');
87 var ds = bd.get_default_view().get_computed_style(def, '');
88 var cs = el.owner_document.default_view.get_computed_style(el, '');
94 for (var i = 0; i < cs.length; i++ ) {
97 //print([ k, cs.get_property_value(k) , ds.get_property_value(k) ]);
100 if (!cs.get_property_value(k).length) {
103 if (par_ds && (cs.get_property_value(k) == ds.get_property_value(k) )) {
106 //if (par_ds && (cs.get_property_value(k) == par_ds.get_property_value(k) )) {
110 ns.push(k + ':'+ cs.get_property_value(k) +';');
113 bd.document_element.remove_child(def);
114 //print(ns.join(''));
116 return ns.length ? ns.join('') : '';
118 //el.remove_attribute('class');
119 //el.set_attribute('style', ns.length ? ns.join('') : '');
126 var traverseDOMTree = function(cb, currentElement, depth) {
127 if (currentElement) {
129 //if (currentElement.class_name.match(/roo-dynamic/)) {
132 //print(currentElement.node_name);
134 var nodeName = currentElement.node_name;
135 var tagName = currentElement.tag_name;
137 if (nodeName == '#text') {
138 cb(currentElement.node_value);
142 if(nodeName == 'BR'){
147 if (nodeName == 'SCRIPT') {
151 //if (nodeName == 'STYLE') { return; }
153 // Prints the node tagName, such as <A>, <IMG>, etc
154 var outNodeName = nodeName;
155 if (nodeName == 'IFRAME') {
156 //outNodeName = 'DIV';
165 for(i = 0; i < currentElement.attributes.length;i++) {
166 var aname = currentElement.attributes.item(i).name;
167 //if (aname =='class' || aname == 'style') {
170 if (aname =='src' && tagName == 'IFRAME') {
174 attr.push(aname + '="' + currentElement.attributes.item(i).value + '"' );
177 //if (nodeName == 'IFRAME') {
178 // attr.push('src="' + currentElement.attributes.item(i).value + embeded_file '"' );
181 //var style = elClassToStyle(currentElement);
182 //if (style.length) {
183 // attr.push('style="' + style + '"' );
187 //if (depth > 1000 && (tagName == 'BODY' || tagName == 'HEAD' )) {
188 // cb("<DIV"+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
190 cb("<"+outNodeName + ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
198 if (nodeName == 'IFRAME') {
201 //traverseDOMTree(cb, currentElement.content_document.head, depth+1000);
202 traverseDOMTree(cb, currentElement.content_document.get_document_element(), depth+1000);
212 var currentElementChild = currentElement.child_nodes.item(i);
214 while (currentElementChild) {
215 // Formatting code (indent the tree so it looks nice on the screen)
217 if (currentElementChild.node_name == '#text') {
218 // if (currentElementChild.node_value.length) {
219 cb(currentElementChild.node_value);
223 currentElementChild=currentElement.child_nodes.item(i);
228 //for (j = 0; j < depth; j++) {
229 // ¦ is just a vertical line
234 // Recursively traverse the tree structure of the child node
235 traverseDOMTree(cb, currentElementChild, depth+1);
237 currentElementChild=currentElement.child_nodes.item(i);
240 // The remaining code is mostly for formatting the tree
242 //for (j = 0; j < depth - 1; j++) {
247 // if (depth > 1000 && (tagName == 'BODY' || tagName == 'HEAD' )) {
250 cb("</"+outNodeName+">");
258 var update_url = function (web_view, web_frame)
260 var toolbar = tab.get_toolbar();
262 toolbar.set_url(web_frame.get_uri());
263 toolbar.set_can_go_back(web_view.can_go_back());
264 toolbar.set_can_go_forward(web_view.can_go_forward());
274 var create_new_tab = function (web_view, web_frame, new_web_view)
276 new_web_view = new BrowserView();
277 new_web_view.signal.web_view_ready.connect(show_new_tab);
281 var show_new_tab = function (new_web_view)
283 TabbedBrowser.browser.new_tab("", new_web_view);
288 var hover_link = function (web_view, link, url)
290 tab.get_statusbar().set_status(url);
292 this.grab = function()
294 var wv = TabbedBrowser.browser.current_tab().get_web_view();
295 print (traversedom(wv));
301 this.add_inject = function(force)
304 if (force || (typeof(injected[this.uri]) == 'undefined' )) {
305 injected[this.uri] = 0;
307 if (injected[this.uri] > 2) {
310 injected[this.uri]++;
311 var fn = __script_path__ + "/inject.js";
312 if (File.exists(fn)) {
313 // print("Adding inject");
314 var newjs = File.read(__script_path__ + "/inject.js");
315 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
323 var after_login = false;
326 var load_finished_called = false;
329 var do_print = function(web_frame) {
333 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
334 " var r = document.getElementsByTagName('link');" +
335 "for (var i=0;i < r.length;i++) { " +
336 "var a = r[i]; if (a.getAttribute('media') == 'screen') { a.removeAttribute('media'); } " +
342 if (current_url.match(/\.coconuts\.co\//) ) {
343 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
344 File.read( __script_path__ + "/domains/coconuts.co.js")
348 print("Delay:" + BrowserSettings.delay);
350 GLib.timeout_add(GLib.PRIORITY_LOW, BrowserSettings.delay *1, function() {
352 if (web_frame && BrowserSettings.export_filename_html ) {
353 var html = traversedom(web_frame, BrowserSettings.export_filename_html);
354 //File.write(BrowserSettings.export_filename_html, html);
358 if (!BrowserSettings.export_filename) {
359 if (!BrowserSettings.export_filename_html) {
365 var mf = _t.get_main_frame();
367 var ar = Gtk.PaperSize.get_paper_sizes();
368 var psetup = new Gtk.PageSetup();
369 for(var i = 0; i < ar.length; i++) {
370 if (ar[i].get_name() =='iso_a2') {
371 psetup.set_paper_size(ar[i]);
375 var p = new Gtk.PrintOperation({ export_filename : BrowserSettings.export_filename });
376 p.set_default_page_setup(psetup);
377 mf.print_full(p, Gtk.PrintOperationAction.EXPORT);
378 print("made image - exiting");
386 var weibo_added = false;
388 var is_weibo = false;
391 var load_finished = function (webkit, web_frame, wb)
402 print("load finished");
405 if (after_login === true) {
411 if (after_login === false) {
414 print("adding timeout?");
416 GLib.timeout_add(GLib.PRIORITY_LOW, 2000, function() {
417 print("Redirecting after login?" + after_login);
419 _t.browse(after_login);
426 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
427 File.read( __script_path__ + "/weibo.js")
429 print("run_weibo(" + JSON.stringify( BrowserSettings.username ) + ", " + JSON.stringify(BrowserSettings.passwd) + ");");
431 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
432 "run_weibo(" + JSON.stringify( BrowserSettings.username ) + ", " + JSON.stringify(BrowserSettings.passwd) + ");"
438 if (after_login !== false) {
441 // wait a bit then load the real page..
442 GLib.timeout_add(GLib.PRIORITY_LOW, 500, function() {
443 print("Redirecting after login?");
444 _t.browse(after_login);
450 if (load_finished_called) {
454 load_finished_called = true;
458 // if(document.location.host=='weibo.com') {
459 // // clear login dialog from weibo.
460 // //check and hidden the login dialog and overlay .....
461 // var els = document.querySelectorAll('div[node-type]');
463 // for (i = 0; i < els.length; i++) {
464 // if (els[i].hasAttribute('node-type')) {
465 // if(els[i].getAttribute('node-type') == 'outer'){
470 // for (i = 0; i < bbc.length; i++) {// hide all the outer.....
471 // bbc[i].style.display = 'none';
475 // if(document.location.pathname == '/login.php'){
477 // // fills in the user name and password
478 // var els = document.querySelectorAll('input[node-type]');
480 // for (i = 0; i < els.length; i++) {
481 // if (els[i].hasAttribute('node-type')) {
482 // if(els[i].getAttribute('node-type') == 'username'){
483 // els[i].value = BrowserSettings.username;
485 // if(els[i].getAttribute('node-type') == 'password'){
486 // els[i].value = BrowserSettings.passwd;
492 // // simulating click event to login ....
493 // var elss = document.querySelectorAll('a[node-type]');
495 // for (i = 0; i < elss.length; i++) {
496 // if (elss[i].hasAttribute('node-type')) {
497 // if(elss[i].getAttribute('node-type') == 'submitBtn'){
509 // clear login dialog from weibo.
510 // TabbedBrowser.browser.current_tab().get_web_view().execute_script(
511 // " if (document.location.host=='weibo.com') { " +
513 // " var a = document.getElementsByClassName('W_layer')[0]; " +
514 // " a.parentNode.removeChild(a.previousSibling); " +
515 // " a.parentNode.removeChild(a); " +
516 // " } catch(e) { } } " );
520 GLib.timeout_add(GLib.PRIORITY_LOW, BrowserSettings.delay, function() {
522 var mf = _t.get_main_frame();
524 var ar = Gtk.PaperSize.get_paper_sizes();
525 var psetup = new Gtk.PageSetup();
526 for(var i = 0; i < ar.length; i++) {
527 if (ar[i].get_name() =='iso_a2') {
528 psetup.set_paper_size(ar[i]);
532 var p = new Gtk.PrintOperation({ export_filename : BrowserSettings.export_filename });
533 p.set_default_page_setup(psetup);
534 mf.print_full(p, Gtk.PrintOperationAction.EXPORT);
535 print("made image - exiting");
547 var load_committed = function (web_view, web_frame)
549 print("load commited");
551 update_url(web_view, web_frame);
553 // call load finished after 20seconds??
554 // so even if it never complets we try and print the thing.
555 GLib.timeout_add(GLib.PRIORITY_LOW, 40000, function() {
556 print("load commited - 3000 ms?");
562 var clicked_link = function (web_view, web_frame, request,
563 action, decision, window)
565 if(action.get_reason() == WebKit.WebNavigationReason.LINK_CLICKED &&
566 action.get_button() == 2)
568 browser.new_tab(request.get_uri(), null);
578 this.browse = function (url)
580 if(url.search("://") < 0)
581 url = "http://" + url;
585 print("BROWSE: " + url);
586 if (url.match(/\/weibo\.com\//) && after_login === false) {
589 url = "http://weibo.com/login.php";
591 else if (url.match(/\/weibo\.com\//) && after_login !== false) {
594 print("BROWSE -really: " + url);
598 this.set_tab = function (new_tab)
603 this.get_tab = function ()
610 //this.set_scroll_adjustments(null, null);
612 //this.signal.title_changed.connect(update_title);
613 //this.signal.load_committed.connect(load_committed);
614 this.signal.load_finished.connect(load_finished);
617 // For some reason, this segfaults seed in the instance init closure handler
618 // Once that's fixed, uncommenting the next line will give middle-click-open-in-new tab
619 //this.signal.navigation_policy_decision_requested.connect(clicked_link);
621 //this.signal.hovering_over_link.connect(hover_link);
623 this.signal.create_web_view.connect(create_new_tab);
627 // print("ADDing console message sig handler");
632 this.toFilename = function(url)
634 url = url.replace(/^http[s]*:\/\//, '');
635 var p = url.split('/');
636 p.unshift(storedir+'/output');
637 for (var i =1 ;i < p.length; i++) {
638 p[i] = encodeURIComponent(p[i]);
641 p[p.length-1] = decodeURIComponent(p[p.length-1]);
643 var dir = File.dirname(ret);
648 this.checkdomain = function(comp)
650 var b = parseUri(this.uri);
651 var d = parseUri(comp);
652 return (d.host == b.host && d.protocol == b.protocol);
657 this.dupeCheck = function(url)
660 // order - return highest up the queue first..
661 if (File.exists(downloaddir +'/' + encodeURIComponent(url))) {
662 return downloaddir +'/' + encodeURIComponent(url);
664 if (File.exists(parsedir +'/' + encodeURIComponent(url))) {
665 return parsedir +'/' + encodeURIComponent(url);
667 if (File.exists(donedir +'/' + encodeURIComponent(url))) {
668 return donedir +'/' + encodeURIComponent(url);
674 this.moveToParse = function(url)
676 var old = this.dupeCheck(url);
677 var target =parsedir +'/' + encodeURIComponent(url);
681 File.write(target, old ? File.read(old) : '');
688 this.moveToDownload= function(url)
690 var old = this.dupeCheck(url);
691 var target =downloaddir +'/' + encodeURIComponent(url);
695 File.write(target, old ? File.read(old) : '');
701 this.moveToDone= function(url)
703 var old = this.dupeCheck(url);
704 var target = donedir +'/' + encodeURIComponent(url);
708 File.write(target, old ? File.read(old) : '');
718 function parseUri (str) {
719 var o = parseUri.options,
720 m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
724 while (i--) uri[o.key[i]] = m[i] || "";
727 uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
728 if ($1) uri[o.q.name][$1] = $2;
736 key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
739 parser: /(?:^|&)([^&=]*)=?([^&]*)/g
742 strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
743 loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/