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;
43 var cleanClasses = function (document) {
44 // should do it for all rules???
46 //var rules = document.style_sheets[document.styleSheets.length-1].cssRules;
47 //document.style_sheets.item(i).css_rules
49 var stylesheets = document.style_sheets;
50 print("stylesheets length:" + stylesheets.length);
51 for (var si = 0; si < stylesheets.length; si++) {
53 var rules = stylesheets.item(si).get_css_rules();
55 print('stylesheet' + stylesheets.item(si));
56 print('media:' + stylesheets.item(si).get_media());
57 print('href:' + stylesheets.item(si).get_href());
59 print(stylesheets.item(si).get_rules())
60 print(stylesheets.item(si).get_css_rules())
61 print(stylesheets.item(si).get_media().item(0));
66 print("RULES: " + rules.get_length());
68 for (var idx = 0; idx < rules.length ; idx++) {
70 var text=rules.item(idx).css_text||"{}";
72 var selector=text.split("{")[0].trim();
74 var style=text.split(/[\{\}]/g)[1].trim();
75 print(selector +' ={ '+ style );
76 var els = document.query_selector_all(selector);
78 for (var i = 0; i<els.length; i++) {
79 var elem = els.item(i);
80 elem.set_attribute('style', elem.get_attribute('style' ) + style);
86 var els = document.query_selector_all('style');
87 for (var i = 0;i<els.length;i++) {
88 els.item(i).parent_node.remove_child(els.item(i));
90 var els = document.query_selector_all('link');
91 for (var i = 0;i<els.length;i++) {
92 els.item(i).parent_node.remove_child(els.item(i));
94 var els = document.query_selector_all('*');
96 for (var i = 0; i<els.length; i++) {
97 els.item(i).remove_attribute('class');
112 var traversedom = function(web_frame) {
113 //print("TRAVERSE DOM?");
115 var dom = web_frame.get_dom_document().body;
117 cleanClasses(web_frame.get_dom_document());
120 curdoc = web_frame.get_dom_document();
122 //Roo.select('body > div',true).each(function(el) {
123 traverseDOMTree(function(s) { ret+=s; }, dom, 1);
132 var traverseDOMTree = function(cb, currentElement, depth) {
133 if (currentElement) {
135 //if (currentElement.class_name.match(/roo-dynamic/)) {
138 print(currentElement.node_name);
140 var nodeName = currentElement.node_name;
141 var tagName = currentElement.tag_name;
143 if (nodeName == '#text') {
144 cb(currentElement.node_value);
148 if(nodeName == 'BR'){
153 if (nodeName == 'SCRIPT') {
157 //if (nodeName == 'STYLE') { return; }
159 // Prints the node tagName, such as <A>, <IMG>, etc
160 var outNodeName = nodeName;
161 if (nodeName == 'IFRAME') {
171 for(i = 0; i < currentElement.attributes.length;i++) {
172 var aname = currentElement.attributes.item(i).name;
175 attr.push(aname + '="' + currentElement.attributes.item(i).value + '"' );
179 //if (depth > 1000 && (tagName == 'BODY' || tagName == 'HEAD' )) {
180 // cb("<DIV"+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
182 cb("<"+outNodeName + ( attr.length ? (' ' + attr.join(' ') ) : '') + ">");
190 if (nodeName == 'IFRAME') {
192 cleanClasses(currentElement.content_document);
193 //traverseDOMTree(cb, currentElement.content_document.head, depth+1000);
194 traverseDOMTree(cb, currentElement.content_document.body, depth+1000);
202 var currentElementChild = currentElement.child_nodes.item(i);
204 while (currentElementChild) {
205 // Formatting code (indent the tree so it looks nice on the screen)
207 if (currentElementChild.node_name == '#text') {
208 cb(currentElementChild.node_value);
210 currentElementChild=currentElement.child_nodes.item(i);
215 for (j = 0; j < depth; j++) {
216 // ¦ is just a vertical line
221 // Recursively traverse the tree structure of the child node
222 traverseDOMTree(cb, currentElementChild, depth+1);
224 currentElementChild=currentElement.child_nodes.item(i);
227 // The remaining code is mostly for formatting the tree
229 for (j = 0; j < depth - 1; j++) {
234 // if (depth > 1000 && (tagName == 'BODY' || tagName == 'HEAD' )) {
237 cb("</"+outNodeName+">");
245 var update_url = function (web_view, web_frame)
247 var toolbar = tab.get_toolbar();
249 toolbar.set_url(web_frame.get_uri());
250 toolbar.set_can_go_back(web_view.can_go_back());
251 toolbar.set_can_go_forward(web_view.can_go_forward());
261 var create_new_tab = function (web_view, web_frame, new_web_view)
263 new_web_view = new BrowserView();
264 new_web_view.signal.web_view_ready.connect(show_new_tab);
268 var show_new_tab = function (new_web_view)
270 TabbedBrowser.browser.new_tab("", new_web_view);
275 var hover_link = function (web_view, link, url)
277 tab.get_statusbar().set_status(url);
283 this.add_inject = function(force)
286 if (force || (typeof(injected[this.uri]) == 'undefined' )) {
287 injected[this.uri] = 0;
289 if (injected[this.uri] > 2) {
292 injected[this.uri]++;
293 var fn = __script_path__ + "/inject.js";
294 if (File.exists(fn)) {
295 // print("Adding inject");
296 var newjs = File.read(__script_path__ + "/inject.js");
297 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
305 var after_login = false;
308 var load_finished_called = false;
311 var do_print = function(web_frame) {
315 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
316 " var r = document.getElementsByTagName('link');" +
317 "for (var i=0;i < r.length;i++) { " +
318 "var a = r[i]; if (a.getAttribute('media') == 'screen') { a.removeAttribute('media'); } " +
324 if (current_url.match(/\.coconuts\.co\//) ) {
325 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
326 File.read( __script_path__ + "/domains/coconuts.co.js")
330 print("Delay:" + BrowserSettings.delay);
332 GLib.timeout_add(GLib.PRIORITY_LOW, BrowserSettings.delay *1, function() {
334 if (web_frame && BrowserSettings.export_filename_html ) {
335 var html = traversedom(web_frame);
336 File.write(BrowserSettings.export_filename_html, html);
340 if (!BrowserSettings.export_filename) {
343 var mf = _t.get_main_frame();
345 var ar = Gtk.PaperSize.get_paper_sizes();
346 var psetup = new Gtk.PageSetup();
347 for(var i = 0; i < ar.length; i++) {
348 if (ar[i].get_name() =='iso_a2') {
349 psetup.set_paper_size(ar[i]);
353 var p = new Gtk.PrintOperation({ export_filename : BrowserSettings.export_filename });
354 p.set_default_page_setup(psetup);
355 mf.print_full(p, Gtk.PrintOperationAction.EXPORT);
356 print("made image - exiting");
364 var weibo_added = false;
366 var is_weibo = false;
369 var load_finished = function (webkit, web_frame, wb)
380 print("load finished");
383 if (after_login === true) {
389 if (after_login === false) {
392 print("adding timeout?");
394 GLib.timeout_add(GLib.PRIORITY_LOW, 2000, function() {
395 print("Redirecting after login?" + after_login);
397 _t.browse(after_login);
404 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
405 File.read( __script_path__ + "/weibo.js")
407 print("run_weibo(" + JSON.stringify( BrowserSettings.username ) + ", " + JSON.stringify(BrowserSettings.passwd) + ");");
409 TabbedBrowser.browser.current_tab().get_web_view().execute_script(
410 "run_weibo(" + JSON.stringify( BrowserSettings.username ) + ", " + JSON.stringify(BrowserSettings.passwd) + ");"
416 if (after_login !== false) {
419 // wait a bit then load the real page..
420 GLib.timeout_add(GLib.PRIORITY_LOW, 500, function() {
421 print("Redirecting after login?");
422 _t.browse(after_login);
428 if (load_finished_called) {
432 load_finished_called = true;
436 // if(document.location.host=='weibo.com') {
437 // // clear login dialog from weibo.
438 // //check and hidden the login dialog and overlay .....
439 // var els = document.querySelectorAll('div[node-type]');
441 // for (i = 0; i < els.length; i++) {
442 // if (els[i].hasAttribute('node-type')) {
443 // if(els[i].getAttribute('node-type') == 'outer'){
448 // for (i = 0; i < bbc.length; i++) {// hide all the outer.....
449 // bbc[i].style.display = 'none';
453 // if(document.location.pathname == '/login.php'){
455 // // fills in the user name and password
456 // var els = document.querySelectorAll('input[node-type]');
458 // for (i = 0; i < els.length; i++) {
459 // if (els[i].hasAttribute('node-type')) {
460 // if(els[i].getAttribute('node-type') == 'username'){
461 // els[i].value = BrowserSettings.username;
463 // if(els[i].getAttribute('node-type') == 'password'){
464 // els[i].value = BrowserSettings.passwd;
470 // // simulating click event to login ....
471 // var elss = document.querySelectorAll('a[node-type]');
473 // for (i = 0; i < elss.length; i++) {
474 // if (elss[i].hasAttribute('node-type')) {
475 // if(elss[i].getAttribute('node-type') == 'submitBtn'){
487 // clear login dialog from weibo.
488 // TabbedBrowser.browser.current_tab().get_web_view().execute_script(
489 // " if (document.location.host=='weibo.com') { " +
491 // " var a = document.getElementsByClassName('W_layer')[0]; " +
492 // " a.parentNode.removeChild(a.previousSibling); " +
493 // " a.parentNode.removeChild(a); " +
494 // " } catch(e) { } } " );
498 GLib.timeout_add(GLib.PRIORITY_LOW, BrowserSettings.delay, function() {
500 var mf = _t.get_main_frame();
502 var ar = Gtk.PaperSize.get_paper_sizes();
503 var psetup = new Gtk.PageSetup();
504 for(var i = 0; i < ar.length; i++) {
505 if (ar[i].get_name() =='iso_a2') {
506 psetup.set_paper_size(ar[i]);
510 var p = new Gtk.PrintOperation({ export_filename : BrowserSettings.export_filename });
511 p.set_default_page_setup(psetup);
512 mf.print_full(p, Gtk.PrintOperationAction.EXPORT);
513 print("made image - exiting");
525 var load_committed = function (web_view, web_frame)
527 print("load commited");
529 update_url(web_view, web_frame);
531 // call load finished after 20seconds??
532 // so even if it never complets we try and print the thing.
533 GLib.timeout_add(GLib.PRIORITY_LOW, 40000, function() {
534 print("load commited - 3000 ms?");
540 var clicked_link = function (web_view, web_frame, request,
541 action, decision, window)
543 if(action.get_reason() == WebKit.WebNavigationReason.LINK_CLICKED &&
544 action.get_button() == 2)
546 browser.new_tab(request.get_uri(), null);
556 this.browse = function (url)
558 if(url.search("://") < 0)
559 url = "http://" + url;
563 print("BROWSE: " + url);
564 if (url.match(/\/weibo\.com\//) && after_login === false) {
567 url = "http://weibo.com/login.php";
569 else if (url.match(/\/weibo\.com\//) && after_login !== false) {
572 print("BROWSE -really: " + url);
576 this.set_tab = function (new_tab)
581 this.get_tab = function ()
588 //this.set_scroll_adjustments(null, null);
590 //this.signal.title_changed.connect(update_title);
591 //this.signal.load_committed.connect(load_committed);
592 this.signal.load_finished.connect(load_finished);
595 // For some reason, this segfaults seed in the instance init closure handler
596 // Once that's fixed, uncommenting the next line will give middle-click-open-in-new tab
597 //this.signal.navigation_policy_decision_requested.connect(clicked_link);
599 //this.signal.hovering_over_link.connect(hover_link);
601 this.signal.create_web_view.connect(create_new_tab);
605 // print("ADDing console message sig handler");
610 this.toFilename = function(url)
612 url = url.replace(/^http[s]*:\/\//, '');
613 var p = url.split('/');
614 p.unshift(storedir+'/output');
615 for (var i =1 ;i < p.length; i++) {
616 p[i] = encodeURIComponent(p[i]);
619 p[p.length-1] = decodeURIComponent(p[p.length-1]);
621 var dir = File.dirname(ret);
626 this.checkdomain = function(comp)
628 var b = parseUri(this.uri);
629 var d = parseUri(comp);
630 return (d.host == b.host && d.protocol == b.protocol);
635 this.dupeCheck = function(url)
638 // order - return highest up the queue first..
639 if (File.exists(downloaddir +'/' + encodeURIComponent(url))) {
640 return downloaddir +'/' + encodeURIComponent(url);
642 if (File.exists(parsedir +'/' + encodeURIComponent(url))) {
643 return parsedir +'/' + encodeURIComponent(url);
645 if (File.exists(donedir +'/' + encodeURIComponent(url))) {
646 return donedir +'/' + encodeURIComponent(url);
652 this.moveToParse = function(url)
654 var old = this.dupeCheck(url);
655 var target =parsedir +'/' + encodeURIComponent(url);
659 File.write(target, old ? File.read(old) : '');
666 this.moveToDownload= function(url)
668 var old = this.dupeCheck(url);
669 var target =downloaddir +'/' + encodeURIComponent(url);
673 File.write(target, old ? File.read(old) : '');
679 this.moveToDone= function(url)
681 var old = this.dupeCheck(url);
682 var target = donedir +'/' + encodeURIComponent(url);
686 File.write(target, old ? File.read(old) : '');
696 function parseUri (str) {
697 var o = parseUri.options,
698 m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
702 while (i--) uri[o.key[i]] = m[i] || "";
705 uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
706 if ($1) uri[o.q.name][$1] = $2;
714 key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
717 parser: /(?:^|&)([^&=]*)=?([^&]*)/g
720 strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
721 loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/