When running "rails server" I was getting the following error...
'require': no such file to load -- sqlite3/sqlite3_native (LoadError)
Banging my head on the desk for ages with this one. Then realised the default Aptana workspace name contained white space chars! Remove these and all is fine.
Shame on me!
Monday, 4 April 2011
Friday, 27 August 2010
Chrome extension, accessing extension variables from scripts

Just went all around the houses trying to access variables from a script running within a web page. In actual fact it's quite easy. You need two things, a background pages and an options page to administer your options. So the first thing you need to do is make sure you have a reference to background and options in your extention manifest...
...
"background_page": "background.html",
"options_page": "options.html",
...
From within your script you can then access variables using...
chrome.extension.sendRequest({action:"getItem",item:"somekey"}, function(response) {
var myvar = response.value
console.log("somekey:"+myvar);
});Background page should look something like this...
<html>
<head><title>background</title>
<script type="text/javascript">
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"from a content script:" + sender.tab.url :
"from the extension");
switch(request.action){
case "clear" :
localStorage.clear();
sendResponse({message:"Thanks, localStorage has been cleared"});
break;
case "getItem" :
var value = localStorage.getItem(request.item);
sendResponse({value:value,message:"value returned from background.html"});
break;
case "getItems" :
var value = {};
for (var i=0;ivalue[request.items[i]] = localStorage.getItem(request.items[i])
}
sendResponse({value:value,message:"value returned from background.html"});
break;
case "setItem" :
localStorage.setItem(request.item,request.value);
sendResponse({message:"Thanks, your update has been saved"});
break;
case "setItems" :
for (name in request.items){
localStorage.setItem(name,request.items[name]);
}
sendResponse({message:"Thanks, your updates have been saved"});
break;
}
});
</script>
</head>
</html>
The above will give you a simple way to store variables.
Your options page needs to use the background.html to save variables to
<html>
<head>
<title>Extention options</title>
<script type="text/javascript">
window.myOptions = {
init:function(){
chrome.extension.sendRequest({action:"getItem",item:"optionOne"}, function(response) {
console.log("!responce.value"+response.value);
document.getElementById("optionOne").checked = (response.value=="off") ? false : true;
});
chrome.extension.sendRequest({action:"getItem",item:"optionTwo"}, function(response) {
console.log("!responce.value"+response.value);
document.getElementById("optionTwo").checked = (response.value=="off") ? false : true;
});
document.getElementById("optionOne").addEventListener("click",function(){
myOptions.change("optionOne");
},false)
document.getElementById("optionTwo").addEventListener("click",function(){
myOptions.change("optionTwo");
},false)
document.getElementById("resetButton").addEventListener("click",function(){
myOptions.reset();
},false)
}
,change:function(key){
var value = document.getElementById(key).checked ? "on" : "off";
chrome.extension.sendRequest({action:"setItem",item:key,value:value}, function(response) {
console.log("!responce.message"+response.message);
var m = (value == "off")? "disabled" : "enabled"
document.getElementById("settings").innerHTML = key + " has been "+ m;
});
}
,reset:function(){
chrome.extension.sendRequest({action:"clear"}, function(response) {
location.reload();
});
}
}
window.addEventListener("load", window.myOptions.init, false)
</script>
</head>
<body>
<form>
<h1>Options</h1>
<p>
Intro text
</p>
<p>
<span class="option">
<input type="checkbox" name="optionOne" id="optionOne" value="on" />
</span>
<label for="optionOne" class="wiki">Enable option one</label>
</p>
<p>
<span class="option">
<input type="checkbox" name="optionTwo" id="optionTwo" value="on" />
</span>
<label for="optionTwo" class="wiki">Enable option two</label>
</p>
<p style="height:1.3em;color:red" class="alert">
<span id="settings"></span>
</p>
<p>
<input type="button" id="resetButton" value="Reset default options"/>
</p>
</form>
</body>
</html>
Thursday, 12 August 2010
Math.random()
Note to self... for a three number 100 - 999
var min = 100
var max = 1000
Math.floor(Math.random()*(max-min)+min)
Monday, 4 January 2010
funny font size in safari on the iPhone
body {
-webkit-text-size-adjust:none;
}
Wednesday, 23 December 2009
hasLayout problems after all these years
Having terrible trouble with all version of IE trying to get some peekaboo text to stay put. In this scenario a div was not paying ball at all, after setting hasLayout on pretty much every element in the entire page I realised that the system was outputting HTML without a DTD, dogh, I feel like i've just called tech support to complain about not being able to print, only to find out that the cleaner unplugged the printer.
Note to self, always check the most obvious thing first!
In IE7 I have a normal input type = button which as the behaviour that when you scroll the text in the button gets visually corrupted. So very slowly scrolling the button into view will wipe the text and the button will appear empty. The offending button is fine in IE6 and IE8, I was tempted to ignore this and mark it down as a bug in the browser but weakened and decided to fix it.
After tinkering with the CSS for a while I couldn't find any hack/fix for this issue, setting the writing-mode style to top to bottom, did fix it but didn't think having the button text written out vertically would go down well!
In the end....
total MADNESS !
Note to self, always check the most obvious thing first!
In IE7 I have a normal input type = button which as the behaviour that when you scroll the text in the button gets visually corrupted. So very slowly scrolling the button into view will wipe the text and the button will appear empty. The offending button is fine in IE6 and IE8, I was tempted to ignore this and mark it down as a bug in the browser but weakened and decided to fix it.
After tinkering with the CSS for a while I couldn't find any hack/fix for this issue, setting the writing-mode style to top to bottom, did fix it but didn't think having the button text written out vertically would go down well!
In the end....
window.attachEvent ('onscroll', function(){
// layout fix for IE7 disappearing text, element has layout so resorting to this madness!
document.getElementById('buttonMoreSections').style.backgroundColor=(document.documentElement.scrollTop % 2)? '#fff':'white';
})
total MADNESS !
Wednesday, 16 December 2009
Image Replacement, but only if images are enabled
The fact that you don't know whether the user has images enabled or not is a real problem with image replacement. You can't hide the existing text if images are disabled as the user will just end up with nothing, the standard way to handle this problem is to keep the text visible and have an image bigger than the text and place the image over the text, if the user doesn't have images they will still see the text. This is only ok if your replacing a header where the image is bigger than the text, but no good for any small images like icons where the text is always going to be bigger.
One way round this is to only add images if your sure the user has images enabled and to keep the text in the HTML flow for screen reader users.
One way of testing for images is to use JavaScript and set a class name on the HTML element if image are enabled/supported, then you can apply styles based on the existence of this class name, using this technique you'll only do image replacement if the user has JavaScript, CSS and Images enabled which is a good thing. If the user doesn't have any of these three you probably don't want to mess with the UI at all.
See the image replacement test page for some uses.
One way round this is to only add images if your sure the user has images enabled and to keep the text in the HTML flow for screen reader users.
One way of testing for images is to use JavaScript and set a class name on the HTML element if image are enabled/supported, then you can apply styles based on the existence of this class name, using this technique you'll only do image replacement if the user has JavaScript, CSS and Images enabled which is a good thing. If the user doesn't have any of these three you probably don't want to mess with the UI at all.
See the image replacement test page for some uses.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Image Replacment example</title>
<style type="text/css">
/* styles if images are enabled */
html.img span.enabled {
color:#080;
display:inline;
}
html.img span.disabled {
display:none;
}
span.enabled {
display:none;
}
span.disabled {
color:#f00;
display:inline;
}
/* hide text if images are enebled */
html.img h1 span,
html.img a span span {
display:block;
height:1px;
overflow:hidden;
width:1px;
}
/* add images */
html.img a span.img {
display:inline-block;
height:12px;
overflow:hidden;
width:12px;
}
html.img a.external span.img {
background-image:url(http://upload.wikimedia.org/wikipedia/commons/6/64/Icon_External_Link.png);
}
html.img a.doc span.img {
background-image:url(http://pclancey.com/i/btf/doc.png);
}
html.img a.pdf span.img {
background-image:url(http://pclancey.com/i/btf/pdf.png);
}
html.img h1 {
background-image:url(http://pclancey.com/i/btf/h103.png);
height:88px;
width:680px;
}
/* menu styles */
*.menu a {
text-decoration:none;
}
*.menu a:active,
*.menu a:focus,
*.menu a:hover {
text-decoration:underline;
}
</style>
</head>
<body>
<h1><span>Beneath the Fold</span></h1>
<p>
Image replacement test:
Can you see an image of a mouse?
<img src="http://news.nationalgeographic.com/news/2009/03/images/090320-new-mouse-picture_big.jpg" height="60" alt="image of a wet mouse" />
<br/>Images seem to be:
<span class="enabled">enabled, using image replacement</span>
<span class="disabled">disabled or can't tell, not using image replacement</span>
</p>
<ul class="menu">
<li><a href="http://google.com" class="external" target="_blank">
External link
<span class="img">
<span>(opens in new window)</span>
</span>
</a></li>
<li><a href="http://google.com" class="doc">
Link to some document
<span class="img">
<span>(Word DOC)</span>
</span>
</a></li>
<li><a href="http://google.com" class="pdf">
Link to some other document
<span class="img">
<span>(PDF)</span>
</span>
</a></li>
</ul>
</body>
<script type="text/javascript">
/*
* set the img class name on the HTML doc
* run this oncontentready, onload or
* at the bottom of the page
*
*/
(function(){
if (!document.getElementsByTagName){return}
var existentimg = new Image;
var html = document.getElementsByTagName('html')[0];
existentimg.onload = function(){
html.className+=' img';
var nonexistentimg = new Image;
nonexistentimg.onload = function(){
html.className=html.className.replace(/\bimg\b/,'');
}
nonexistentimg.src="/nonexistentimg.gif";
}
existentimg.src = (document.images.length)? document.images[0].src : 'http://upload.wikimedia.org/wikipedia/commons/6/64/Icon_External_Link.png' ;
})();
</script>
</html>
Tuesday, 10 November 2009
IE, butters text after filter is applied
TODO: add image of butters text...
I haven't looked into this in any great depth, but the problem seems to be with clearType text in IE and obj.style.filter. If you apply the Alpha(opacity) filter the text gets mashed up, so setting obj.style.filter="Alpha(opacity=100)" breaks the anti-alias on text.
One work around is to set a background colour on the element your going to apply a filter to. If you don't know which elements your going to fade in advance you can reset the filter after the fade has run, which isn't ideal but better than nothing.
I user a method similar to the bellow for setting opacity
/** @id Transition.SetOpacity */
function SetOpacity(el,opacity){
opacity = (opacity>=100)? 100 : opacity;
el.style.opacity = (opacity / 100);
el.style.MozOpacity = (opacity / 100);
el.style.KhtmlOpacity = (opacity / 100);
// private method to set opacity in IE
setIEOpacity(el,opacity)
function setIEOpacity(el,opacity){
if (!el.currentStyle.hasLayout){
// give element layout
el.style.zoom = 1;
}
if (!el.originalFilter){
// save the original filter, if one exists, so you can replace it after fade
el.originalFilter = el.currentStyle.filter || 'none';
}
// if opacity = 100 put the original filter back
el.style.filter = (opacity == 100) ?
el.originalFilter :
'progid:DXImageTransform.Microsoft.Alpha(opacity='+ opacity + ')';
}
}
NB. for a fade to work in IE at all, the element needs to have layout (obj.currentStyle.hasLayout) this is a read only attribute, to set it to true you need to give the element a style that will trigger it to set .hasLayout to true. I normally set the zoom style to 1 in an IE only stylesheet. For other ways of tringering hasLayout see haslayout.net
Subscribe to:
Comments (Atom)