Posts Tagged ‘safari’

Open IEEE pdf without banner

Tuesday, February 11th, 2014

The IEEE Xplore library has a very annoying way of serving up PDFs. The page has two frames, one’s a small banner at the top and the bother is the PDF. Both Safari and Chrome keep the banner in focus so when I try to zoom I’m just zooming the banner. Here’s a javascript bookmarklet to open that second frame as a proper page:

javascript:(function(){window.location.href=document.getElementsByTagName("frame")[1].src;})()

Flushing php output on Safari with php scripts (hosted by Bluehost)

Thursday, June 13th, 2013

There are many, many posts about getting php to flush its output while a script is executing. No one solution worked for me, but I finally found a combination of things that did.

First of all my default php.ini shows these two relevant lines:


output_buffering = On
zlib.output_compression = Off

Then I put an .htaccess file in the directory that I’d like to have my buffering script with the following line:


SetEnv no-gzip dont-vary

Finally here was my small test php file:


<?php  // not in table tags for IE                         
    @ini_set('zlib.output_compression', 0);
    @ini_set('implicit_flush', 1);
    //for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
    ob_end_flush();
    ob_implicit_flush(1);
?>
<html>
<body>
<?php
echo str_pad('',1024);  // minimum start for Safari
for ($i=10; $i>0; $i--) {
  echo str_pad("$i<br>\n",8);
  // tag after text for Safari & Firefox
  // 8 char minimum for Firefox
  usleep(100000);
}
?>
</body>
</html>

Safari 6 (almost) hangs when adding new bookmarks

Tuesday, March 26th, 2013

I upgraded to Safari 6 and was upset that when I added a new bookmark I got the beach ball of death (is there also a beach ball of life). I impatiently killed Safari after 10 secs or so.
I tried adding bookmarks in any way I could, but always it seemed to hang.
Finally I resolved to give up but left Safari spinning. When I came back the bookmark was added. Not sure what it was doing or thinking about (perhaps whether there is also a beach ball of life), but now I can add bookmarks again without any delay.

Switch search to google scholar bookmarklet

Monday, March 25th, 2013

I upgraded to Safari 6 and was happy to see the search bar gone and keyword search directly in the address bar. However I was annoyed to see that when searching you don’t see the full google url but just the query keywords. This nullified my previous hack to switch a google search to a google scholar search.

Instead here’s a little bookmarklet to switch a google search to a google scholar search:


javascript:(function(){window.location.href=window.location.href.replace("search?", "scholar?");})()

Just paste that into you address bar and create a bookmark for it. Then any time you do a normal google search, you can switch it to a google scholar search by hitting the bookmark.

source

Scroll a bit in safari window, take screenshot repeat

Friday, February 22nd, 2013

Here’s an applescript I used to make a series of screen captures of scrolling through a web page in safari:


tell application "Safari"
	activate
	set sc to 0
	repeat
		set thescript to "if((window.pageYOffset + window.innerHeight)<document.body.clientHeight)
		{
    	window.scrollBy(0,10); // horizontal and vertical scroll increments
		}"
		do JavaScript thescript in current tab of first window
		set imagePath to (path to desktop as text) & "screenCapture_" & my zero_pad(sc, 6) & ".png"
		delay 1.5
		do shell script "screencapture -o -mx -T0 " & quoted form of POSIX path of imagePath
		delay 0.5
		set sc to sc + 1
	end repeat
	
end tell

on zero_pad(value, string_length)
	set string_zeroes to ""
	set digits_to_pad to string_length - (length of (value as string))
	if digits_to_pad > 0 then
		repeat digits_to_pad times
			set string_zeroes to string_zeroes & "0" as string
		end repeat
	end if
	set padded_value to string_zeroes & value as string
	return padded_value
end zero_pad

Source

Fullscreen, blank homepage

Saturday, September 3rd, 2011

I usually use a blank or empty page as my homepage. This makes for quick browser start up and minimal waiting when making new tabs/windows.

I find myself often opening a new browser window resizing it to fill the whole screen and then browsing. This goes against how apple wants me to use my mac. The little green plus sign button on the top left corner of the screen is supposed to be smart enough to always maximize the current window only as much as it needs to/should. But what is the correct maximization of a blank page? Apparently its a full height window with some arbitrary width. Why not make it a full height and full width window. To do this for my browsers (Safari, Firefox, Chrom(e|ium)) I made a little html file that displays a blank, fullscreen-able page. Save the following in a file on your computer called fullscreen-homepage.html:


<html>
  <head>
    <title>Fullscreen Homepage</title>
  </head>
  <body style="min-width:10000px;overflow:hidden">
  </body>
</html>

Open the file with your browser and copy the address at the top (starting with file:// to your browser’s preferences as your homepage for new tabs and windows. Here’s what to change in the Safari preferences:
safari preferences local fullscreen homepage

Getting Safari to play a short audio clip with HTML5’s audio tag

Friday, August 19th, 2011

I had a really annoying time trying to get Safari to load and play a small audio clip (mp3) I’d posted. The clip is only 2 seconds. Here’s the HTML I was using


<audio src="audio.mp3" autoplay preload="auto" controls loop>

But this resulting in nothing. Upon closer inspection I found out the the “onstalled” even was being fired so I added an “onstalled” even handler to try to load the clip again:


<audio onstalled="this.load();" src="audio.mp3" autoplay preload="auto" controls loop>

But this was to no avail, the “onstalled” event just fired each time recursively.

In the end I gave up on Safari’s ability to play/load small mp3 files. I’m not sure what the problem is since quicktime played the file fine. Also if my html and audio.mp3 files lived locally, Safari played it correctly.

I instead made use of HTML5 ability to specify fallback sources. For this I converted my mp3 file to a m4a:

First convert to wav with mplayer:


mplayer -quiet -vo null -vc dummy -ao pcm:waveheader:file="audio.wav" "audio.mp3"

Then convert to m4a with faac:


faac -o audio.m4a audio.wav

Finally use the .m4a file as a fallback source in the audio tag:


<audio autoplay preload="auto" controls loop>
<source src="audio.mp3" >
<source src="audio.m4a" >
<audio>

Ignore the onion paywall

Saturday, August 13th, 2011

Was watching the onion video channel today and to my surprise they have a paywall like nytimes. To be honest at first I thought it was a joke. But in the end it’s just as easy to get around as the nytimes one.

Just a little client side javascript gets ride of the paywall screen:


document.getElementById('gregbox-overlay').style.display = "none";
document.getElementById('gregbox-wrap').style.display = "none";

And here’s an applescript which calls that javascript on the frontmost safari window.


tell application "Safari"
	try
		set doc to front document
		do JavaScript "document.getElementById('gregbox-overlay').style.display = 'none';" in doc
		do JavaScript "document.getElementById('gregbox-wrap').style.display = 'none';" in doc
	on error errText number errNum
	end try
end tell

Ad blocking one website at a time

Monday, June 7th, 2010

I wrote a small piece of Applescript code that allows me to zap ads from web pages that I browse using Safari. It uses javascript to remove the ads or containing objects from the page directly. It doesn’t use intelligent ad recognition in any way. Rather my idea was much simpler. Most people spend 90% of there time on the web looking at a small number of websites: facebook, new york times, twitter, google, wikipedia, gmail, youtube, etc. See Pareto principle. If I can block 100% of the ads on 90% of the pages I look at then my ad blocker is effectively 90% efficient.

The ads on these big sites are usually in the same place on the page making them very easy to remove from the html with javascript. I organized my applescript so that adding a new site on which to block ads is very simple (just a line or two) and blocking a certain type of ad on that site is just another line.

I use the magnifying glass tool, in the Safari Developer tool, Web Inspector, to select the ad object on the page. Inevitably the website has used a class or id which then I feed into my script. Often the containing object is as simple as “ad” or “bigAd”.

screenshot of web inspector, selecting ad

When I have my blocker running in the background, it usually takes up 2% of the CPU. If I crank down the delay in the script so that the ads disappear even faster then it can get as high as 10% or so, but it’s not really worth it.

There is no reason why you couldn’t easily port this style of ad blocker to grease monkey, opera, or anything that runs client-side javascript.

Here is the applescript, it creates a few useful javascript methods and sets up the blocker to run in the background (with a little error checking).


-- Safari AdBlocker Applescript
-- Author: Alec Jacobson http://alecjacobson.com
--


-- this might not be necessary... 
-- because safari already has getelementbyclassname... 
-- but perhaps without localization?
-- and perhaps not older safari?
set getElementsByClass to "
/*
  Developed by Robert Nyman, http://www.robertnyman.com
  Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/  
var getElementsByClassName = function (className, tag, elm){
  if (document.getElementsByClassName) {
    getElementsByClassName = function (className, tag, elm) {
      elm = elm || document;
      var elements = elm.getElementsByClassName(className),
        nodeName = (tag)? new RegExp(\"\\b\" + tag + \"\\b\", \"i\") : null,
        returnElements = [],
        current;
      for(var i=0, il=elements.length; i<il; i+=1){
        current = elements[i];
        if(!nodeName || nodeName.test(current.nodeName)) {
          returnElements.push(current);
        }
      }
      return returnElements;
    };
  }
  else if (document.evaluate) {
    getElementsByClassName = function (className, tag, elm) {
      tag = tag || \"*\";
      elm = elm || document;
      var classes = className.split(\" \"),
        classesToCheck = \"\",
        xhtmlNamespace = \"http://www.w3.org/1999/xhtml\",
        namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
        returnElements = [],
        elements,
        node;
      for(var j=0, jl=classes.length; j<jl; j+=1){
        classesToCheck += \"[contains(concat(' ', @class, ' '), ' \" + classes[j] + \" ')]\";
      }
      try  {
        elements = document.evaluate(\".//\" + tag + classesToCheck, elm, namespaceResolver, 0, null);
      }
      catch (e) {
        elements = document.evaluate(\".//\" + tag + classesToCheck, elm, null, 0, null);
      }
      while ((node = elements.iterateNext())) {
        returnElements.push(node);
      }
      return returnElements;
    };
  }
  else {
    getElementsByClassName = function (className, tag, elm) {
      tag = tag || \"*\";
      elm = elm || document;
      var classes = className.split(\" \"),
        classesToCheck = [],
        elements = (tag === \"*\" && elm.all)? elm.all : elm.getElementsByTagName(tag),
        current,
        returnElements = [],
        match;
      for(var k=0, kl=classes.length; k<kl; k+=1){
        classesToCheck.push(new RegExp(\"(^|\\s)\" + classes[k] + \"(\\s|$)\"));
      }
      for(var l=0, ll=elements.length; l<ll; l+=1){
        current = elements[l];
        match = false;
        for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
          match = classesToCheck[m].test(current.className);
          if (!match) {
            break;
          }
        }
        if (match) {
          returnElements.push(current);
        }
      }
      return returnElements;
    };
  }
  return getElementsByClassName(className, tag, elm);
};"
set setElementsToEmpty to "function setElementsToEmpty(a){
  for ( var i=0, len=a.length; i<len; ++i ){
    a[i].innerHTML = '';
  }
};
"

set this_url to ""
repeat
  try
    repeat while appIsRunning("Safari")
      tell application "Safari"
        
        try
          set doc to front document
          set this_url to URL of doc
          do JavaScript getElementsByClass in doc
          do JavaScript setElementsToEmpty in doc
          if this_url starts with "http://www.google.com/search?" then
            -- Regular google search
            -------------------------------------------------------------
            --
            -- ZAP CONTAINING DIV BY ITS ID
            --
            -------------------------------------------------------------
            do JavaScript "document.getElementById('rhsline').innerHTML = ''" in doc
            do JavaScript "document.getElementById('tads').innerHTML = ''" in doc
          else if this_url starts with "http://search.yahoo.com/search" then
            -- Regular yahoo search
            do JavaScript "document.getElementById('east').innerHTML = ''" in doc
            -------------------------------------------------------------
            --
            -- ZAP DIVS OF CERTAIN CLASS WITHIN  CERTAIN CONTAINING DIV (COULD BE NULL)
            --
            -------------------------------------------------------------
            do JavaScript "setElementsToEmpty(getElementsByClassName('ads horiz',null,document.getElementById('main')))" in doc
          -------------------------------------------------------------
          --
          -- ADD OTHER SITES HERE
          --
          -------------------------------------------------------------
          end if
          -- set delay amount accordingly to manage how much CPU to devote to blocking ads
          -- recommended between 1.0 and 0.001 seconds
          delay 0.1
        on error errText number errNum
          -- if anything but doc changing before ads removed or safari open but no windows
          -- pause so that CPU isn't stolen
          delay 2
        end try
      end tell
    end repeat
  on error errText number errNum
    if errNum is equal to -128 or errNum is equal to -609 then
      -- safari no longer open
    else
      display dialog errText & " " & errNum
    end if
    
  end try
  delay 5
end repeat

-- from http://codesnippets.joyent.com/posts/show/1124
on appIsRunning(appName)
  tell application "System Events" to (name of processes) contains appName
end appIsRunning

Download the ad blocker with all the sites I’ve blocked ads on

Imagine how strong this ad blocker could be if an army of users were updating the site specific zaps. Imagine the cold war it would start.

Note: Some sites inject their ads deeper into the content of the site like youtube does with its flash videos. I haven’t come up with a way to single this one out yet…

Hack infinite scroll javascript with infinite auto-scroll to bottom of page

Thursday, January 7th, 2010

This is a hack to have your browser load all search results when a page is using jQuery’s infinite scroll feature, like this site: http://instantwatcher.com/titles/all?infinite=1.
Here’s the client side javascript to keep auto-scrolling this page to the bottom, thus triggering infinite scroll to load more results. It runs until there are no more results to load:

    function scrollToBottom(){
      bottom = document.body.scrollHeight;
      current = window.innerHeight+ document.body.scrollTop;
      if((bottom-current) >0){
        window.scrollTo(0, bottom);
        setTimeout ( 'scrollToBottom()', 1000 );
      }
    };
    scrollToBottom();

I run this on Safari using this short applescript:


tell application "Safari"
  set doc to front document
  set this_url to URL of doc
  do JavaScript "
    function scrollToBottom(){
      bottom = document.body.scrollHeight;
      current = window.innerHeight+ document.body.scrollTop;
      if((bottom-current) >0){
        window.scrollTo(0, bottom);
        setTimeout ( 'scrollToBottom()', 1000 );
      }
    };
    scrollToBottom();
    " in doc
end tell

Try it!