This probably still has a lot of holes in it, because there are so many different morphs and rules, but I think this fixes your problem about the labels:
var ms = this.world().hand.mouseOverList[0];
if (ms instanceof ArgMorph || ms instanceof BlockLabelMorph
|| eval(ms.constructor.name + '.uber') instanceof StringMorph
|| ms instanceof ArgMorph){
return new Context(null, ms.parent.fullCopy());
} else if (ms instanceof BlockMorph){
return new Context(null, ms.fullCopy());
} else if (ms instanceof InputSlotStringMorph){
return new Context(null, ms.parent.parent.fullCopy());
} else {
return ms.fullCopy();
}