Refresh/show current html file from TextWrangler in Safari

The objective of this script is to show what an html file looks like when displayed in Safari, by just hitting command-R or a short cut key of your preference.

It works on the active document in TextWrangler and if the html file is already displayed in Safari it will just be refreshed. If the current tab of Safari doesn’t contain the same file then it will be opened in Safari.

Ignoring any other tabs in Safari is a feature and not a bug since you sometimes want to compare the result of css etc.

You install the script in the script folder of TextWrangler, and set the short cut key from TextWranglers preferences, the list item that contains “menu”.

It is convenient to open the window - pallette at the same time, since it displays the chosen short cut immediately, which the latest version of TextWrangler don’t.

TextWrangler is the greatest value for money anyways - free which is pretty unbelievable!

I found the script via a blog post at CNET, gave it some thought concerning my own needs, and ended up with a general solution, after I had updated it according to my own taste.

Enjoy!


-- Based on Sam Dutton's http://goo.gl/27XlZ script
-- which was based on Mike Piontek's script http://goo.gl/SBkkL
-- this is Safari specific
-- see https://gist.github.com/3232063 for a Chrome Script.
-- Rewritten  by McUsr based on: https://gist.github.com/mbierman/3232318
-- http://macscripter.net/viewtopic.php?pid=178129#p178129

to removeSegmentIdentifer(aUrl)
	tell (a reference to my text item delimiters)
		set {astid, contents of it} to {contents of it, "#"}
		set urlparts to text item 1 of aUrl
		set contents of it to ""
		set cleanedUrl to urlparts as text
		set contents of it to astid
	end tell
	return cleanedUrl
end removeSegmentIdentifer

tell application "TextWrangler"
	if (count text documents) = 0 then
		display alert "No documents was open in TextWrangler."
		return
	else
		tell document 1
			try
				save
				set activeFile to file of it as alias
				set currentURL to URL
			on error
				return
			end try
		end tell
	end if
end tell

tell (a reference to my text item delimiters)
	set {astid, contents of it} to {contents of it, "localhost"}
	set urlparts to text items of currentURL
	set contents of it to ""
	set currentURL to urlparts as text
	set contents of it to astid
end tell

if currentURL does not end with "html" then
	display alert "The text document 1 of TextWrangler  isn't a web page"
else
	tell application "TextWrangler"
		find "<title>([^<]*)" searching in text 1 of text document 1 options {search mode:grep, starting at top:true, wrap around:false, backwards:false, case sensitive:false, match words:false, extend selection:false} without selecting match
		
		if found of result = true then
			set theTitle to grep substitution of "\\1"
		else
			set theTitle to missing value
		end if
	end tell
	
	
	if theTitle is missing value then
		display alert "There were no title defined in text document 1 of TextWrangler"
	else
		set refreshSuccess to false -- So We'll open it if we didn't find it.
		do shell script "open -b  com.apple.Safari"
		tell application "Safari"
			-- using the <title> tag above, we compare to the current open tab. If they are equal, replace the contents, otherwise, open a new tab.
			
			if (count (windows whose visible = true)) > 0 then
				set foundTab to false
				try
					tell current tab of front window
						set {currentTabName, currentTabUrl, foundTab} to {its name, its URL, true}
					end tell
				end try
				-- checks if the the current tab url is undefined 
				try
					set probe to currentTabUrl
				on error
					set currentTabUrl to space
				end try
				if currentTabUrl is not space then
					set currentTabUrl to my removeSegmentIdentifer(currentTabUrl)
				else
					set {currentTabUrl, currentTabName} to {currentURL, theTitle}
					-- So we reuse an empty tab
				end if
				
				if foundTab and (currentTabName is theTitle) and (currentTabUrl is currentURL) then
					set URL of current tab of front window to currentURL
					set refreshSuccess to true
				end if
			end if
			
			if not refreshSuccess then open location currentURL
		end tell
	end if
end if

“To my taste”: I have now removed the activate of Safari, and instead uses a

do shell script "open -b com.apple.Safari"

This sees to that the Screen real estate is interrupted as little as possible. :confused:

Removed a stray line that I somehow overlooked yesterday.

There is always room for some improvement.

I now let Finder get the url of the text document of TextWrangler, since it escapes any spaces in a file name correctly.
-You can’t really have spaces in a url, they need to be escaped (%20).

The script now, also checks the URL, and not just the title when it decides whether the document should be refreshed or not. A feature not a bug!

I solidified it a little bit further, probably unnecessary, but still: I checked for open text documents in TextWrangler.

I used the URL of the document in TextWrangler instead of invoking Finder, when I was addressing TextWrangler anyway.

I removed one last caveat, and that was that if the front window of Safari is say a debugger window, then we just open the location of the url, which should bring a window to front with the file loaded, Safari will reuse a tab with the page of the last url, if it is in the first window behind a debugger window at least.

Hello.

I realized that the urls TextWrangler returns contains ‘localhost’, which makes them unsuitable in some cases, so I have reverted to using Finder to produce the url.

Hi,

instead of GUI scripting ⌘R in Safari you can set the URL of the current tab to the current value, this has the same effect


set URL of current tab of front window to currentURL

Thanks, I implemented that, and I also used text item delimiters to remove the localhost from TextWranglers url, in order to save the call to Finder.

Here is the advanced version, that lets you update a page within a frame. :slight_smile:

-- Based on Sam Dutton's http://goo.gl/27XlZ script
-- which was based on Mike Piontek's script http://goo.gl/SBkkL
-- this is Safari specific
-- see https://gist.github.com/3232063 for a Chrome Script.
-- Rewritten  by McUsr based on: https://gist.github.com/mbierman/3232318
-- http://macscripter.net/viewtopic.php?pid=178129#p178129
-- Advanced edition, for those that may have webpages within frame[0].
to removeSegmentIdentifer(aUrl)
	tell (a reference to my text item delimiters)
		set {astid, contents of it} to {contents of it, "#"}
		set urlparts to text item 1 of aUrl
		set contents of it to ""
		set cleanedUrl to urlparts as text
		set contents of it to astid
	end tell
	return cleanedUrl
end removeSegmentIdentifer

tell application "TextWrangler"
	if (count text documents) = 0 then
		display alert "No documents was open in TextWrangler."
		return
	else
		tell document 1
			try
				save
				set activeFile to file of it as alias
				set currentURL to URL
			on error
				return
			end try
		end tell
	end if
end tell


tell (a reference to my text item delimiters)
	set {astid, contents of it} to {contents of it, "localhost"}
	set urlparts to text items of currentURL
	set contents of it to ""
	set currentURL to urlparts as text
	set contents of it to astid
end tell

if currentURL does not end with "html" then
	display alert "The text document 1 of TextWrangler  isn't a web page"
else
	tell application "TextWrangler"
		find "<title>([^<]*)" searching in text 1 of text document 1 options {search mode:grep, starting at top:true, wrap around:false, backwards:false, case sensitive:false, match words:false, extend selection:false} without selecting match
		
		if found of result = true then
			set theTitle to grep substitution of "\\1"
		else
			set theTitle to missing value
		end if
	end tell
	
	
	if theTitle is missing value then
		display alert "There were no title defined in text document 1 of TextWrangler"
	else
		set refreshSuccess to false -- So We'll open it if we didn't find it.
		do shell script "open -b  com.apple.Safari"
		tell application "Safari"
			-- using the <title> tag above, we compare to the current open tab. If they are equal, replace the contents, otherwise, open a new tab.
			
			if (count (windows whose visible = true)) > 0 then
				set foundTab to false
				try
					tell current tab of front window
						set {currentTabName, currentTabUrl, foundTab} to {its name, its URL, true}
					end tell
				end try
				-- checks if the the current tab url is undefined 
				try
					set probe to currentTabUrl
				on error
					set currentTabUrl to space
				end try
				
				if foundTab then
					if currentTabUrl is not space then
						set currentTabUrl to my removeSegmentIdentifer(currentTabUrl)
					else
						set {currentTabUrl, currentTabName} to {currentURL, theTitle}
						-- So we reuse an empty tab
					end if
					
					if (currentTabName is theTitle) then
						if (currentTabUrl is currentURL) then
							
							set URL of current tab of front window to currentURL
							set refreshSuccess to true
						end if
					else
						tell current tab of front window
							set hasFrame to (do JavaScript "var x=(function (){
var hasFrame='true' ;
	try {
		pgsrc= window.frames[0].location;
	}
	catch( err ) {
		hasFrame='false' ;
	}
	return hasFrame ;
})();x") as boolean
						end tell
						
						if hasFrame then
							
							tell current tab of front window
								set frameLocation to do JavaScript "var x= ''+window.frames[0].location.toString();x;"
								if frameLocation is not missing value then
									set frameLocation to my removeSegmentIdentifer(frameLocation)
								else
									set frameLocation to "--NOGOOD--"
									-- Nothing sane to get out of this frame location - maybe Google . . . 
								end if
								
								if currentURL = frameLocation then
									do JavaScript "var x=window.frames[0].location;
window.frames[0].location=x;"
									set refreshSuccess to true
								end if
								
							end tell
						end if
					end if
				end if
			end if
			
			if not refreshSuccess then open location currentURL
		end tell
	end if
end if

Hello.

The script above (Advanced version) had a flaw that was that I didn’t consider that I had to remove any id tags from the frame location. when the url is fetched from within a frame, when a link on the page had been clicked.
(Something like ‘#References’).

That is now fixed.

Edit

Removed a couple of invalid comments from both scripts.

The scripts in post #1, and #8 now both removes any ‘segment identifers’ (#Reference) from the url’s in Safari’s Url bar, before comparing with the document in TextWrangler.

Also added some robustness to the save process of the front text document of TextWrangler.

The scripts in post #1, and #8 now both reuses ‘empty tabs’.

Fixed the script in post #8 for the case that there were some problems with frames[0].location.( I ran into those problems when having a google results page open when running the script.)