I'm guessing that my attempt here isn't correct since I've never done Javascript before. Can someone help me out?
Code:
<SCRIPT LANGUAGE = "VBScript">
Dim oWindow,oDocument,oSelect,oSelectRange
Set oWindow = window.external.menuArguments
Set oSource = oWindow.event.srcElement
Set oDocument = oWindow.document
Set oSelect = oDocument.selection
Set oSelectRange = oSelect.createRange()
If oSource.tagName = "TEXTAREA" Then
oSelectRange.text = "[b]" & oSelectRange.text & "[/b]"
End If
</SCRIPT>
The javascript looks ok to me. Are you getting any errors?
.
I am not a complete idiot. Some parts are still missing. Check out the rtf-help tutorial General VB Faq Thread Change is the only constant thing. I have not changed my signature in a long while and now it has started to stink! Get more power for your floppy disks. ; View honeybee's Elite Club: Use meaningfull thread titles. And add "[Resolved]" in the thread title when you have got a satisfactory response.
And if that response was mine, please think about giving me a rep. I like to collect them!
which I take to mean that line 1 is wrong. That doesn't make sense and I think I'm missing some needed lines before that and I might know what they are. Since you say everything looks okay I'm going to make another attempt now.
Not familiar with Safari extension authoring in particular, but you don't normally include the <script> tags when Javascript is contained in a .js file; they're for embedding Javascript in HTML.
Not familiar with Safari extension authoring in particular, but you don't normally include the <script> tags when Javascript is contained in a .js file; they're for embedding Javascript in HTML.
Okay, that's progress Now the line oWindow = window.external.menuArguments is generating a 'Result of expression 'window.external' [undefined] is not an object.' error message
window.external is an MS-created Javascript extension, so it would seem that it mostly doesn't work with non-IE browsers (reference here). If you need a reference to the window, you should be able to just use "window".
window.external is an MS-created Javascript extension, so it would seem that it mostly doesn't work with non-IE browsers (reference here). If you need a reference to the window, you should be able to just use "window".
@SambaNeko: I don't normally ask for people to do my coding for me but I'm completely ignorant of Javascript so could you please show me the code to have javascript add bold tags to selected text in, say, a reply to this post? That's what the above VBScript code does. Once I have an example I can build on it. BTW in case you aren't aware, you need to add [noparse][/noparse] around the [b][/bold] tags in the code so that they'll show up.
So, explanation: to get a reference to an element which has an "id" attribute, you can use document.getElementById('idOfElement') [you do not need an explicit reference to window; document is presumed as window.document]. Once you have a reference, you can assign callbacks for events like "onclick". You can also use a reference to access information about the selection inside of that element. When the button gets clicked, the script looks for the start and end points of the selection in the textarea, and then uses a few substrings() to add in extra content (the b tags) where needed.
If you are unable to add an "id" attribute to the textarea that you're working with, there are other means of getting a reference to it.
Note that on a typical web page, you'd need to have some branching code to handle different methods of selection for multiple browsers, but if you're writing specifically for Safari, then you need not concern yourself.
Sorry but I think we have a misunderstanding. I don't want to change a webpage but rather I want to add tags around the text that someone enters in a new post, selects all or some of it, and then clicks on my extension's name in the context menu.
Your original post looked like you were using a <textarea> for selection, so I thought the previous example would be useful for adaptation, but perhaps not. In any case, setting the text property of getSelection() doesn't really work that way. You need to create a range object and use that instead...
Code:
var range = window.getSelection().getRangeAt(0);
var selectionParentText = range.startContainer.textContent;
range.startContainer.textContent = selectionParentText.substring(0,range.startOffset) + "[B]" + range.toString() + "[/B]" + selectionParentText.substring(range.endOffset,selectionParentText.length);
This is using the same concept as the previous code snippet with substrings. I've tested this out on FireFox - hopefully it's good for Safari too...
It seems that my End Script executes before I get a chance to clink my new context item so I put some of the code in my Global.html file. This is what it looks like:
Code:
<!DOCTYPE HTML>
<script>
safari.application.addEventListener("command", performCommand, false);
function performCommand(event) {
if (event.command == "Bold")
{
if (window.getSelection) { // Firefox, Opera, Google Chrome and Safari
alert(document.activeElement.tagName.toLowerCase());
var selRange = window.getSelection ();
selText = selRange.toString ();
alert("selText:"+selText);
var range = window.getSelection().getRangeAt(0);
selectionParentText = range.startContainer.textContent;
alert("selectionParentText:"+selectionParentText);
}
}
}
</script>
The first alert (blue) says "body".
The second alert (green) says "selText: so it's blank
The third alert (red) isn't reached because the the previous line gives a 'INDEX_SIZE_ERR: DOM Exception 1: Index or size was negative, or greater than the allowed value' error
Two questions:
Why am I getting "body" rather than "textarea"? Note that my old VBScript code looked for TEXTAREA.
As said before, I'm not familiar with Safari extension authoring, but here's what I think is going on, from what I've read on the subject so far.
From the Safari Extension Development Guide: "Code in your global HTML page and extension bars interacts with the Safari application; it can’t directly access the contents of a webpage loaded in a browser tab." So, anywhere in a global HTML that you try to access the contents of a webpage, it's just not going to work (so trying to get document.activeElement will essentially fail, but will return the default: body; and trying to get window.anything will also fail).
It sounds like you need to use an injected script, but since you want the script's behavior to occur when an extension button is clicked, you'll need to use interaction between the injected script and the global HTML file. I don't know how that works - but the Extension Guide link above might help (it's specifically a page talking about communicating between the two).
function handleMessage(event) {
var range = window.getSelection().getRangeAt(0);
var selectionParentText = range.startContainer.textContent;
range.startContainer.textContent = selectionParentText.substring(0,range.startOffset) + "[b]" + range.toString() + "[/b]" + selectionParentText.substring(range.endOffset,selectionParentText.length);
}
safari.self.addEventListener("message", handleMessage, false);
This code doesn't check the event.command value, or the messageEvent.name value, both of which should probably be employed to differentiate behaviors based on input.
I had pretty much figured that out, but the line var range = window.getSelection().getRangeAt(0); is still giving the 'INDEX_SIZE_ERR: DOM Exception 1: Index or size was negative, or greater than the allowed value' error.
Are you using an old version of Safari? Older versions didn't support getRangeAt(), supposedly. The code posted in my previous post worked as expected (inserted [b][/b] tags around the selected text) for me on Safari on a Mac. I can retry it on Windows though.
Edit: same code works on Safari 5.0.4 on Windows Vista.
Last edited by SambaNeko; Mar 12th, 2011 at 08:44 PM.
I have Safari 5.0.4 and I'll try your code again. Just so we're on the same page (so to speak) I'm trying to change text in the window that I'm now typing in.
When I selected a word in this sentence and then clicked on my menu extension, this is what it did to the window. Note that except for the bold tags, the rest of the window is destroyed.
Hm, yes - I see your problem, and haven't really found a true solution to it. Here's a bit of a kludge that seems to work though:
Code:
function handleMessage(event) {
var e = document.activeElement;
var selLen = e.selectionEnd - e.selectionStart;
e.value = e.value.substr(0, e.selectionStart) + "[b]" + e.value.substr(e.selectionStart, selLen) + "[/b]" + e.value.substr(e.selectionEnd, e.value.length);
}
safari.self.addEventListener("message", handleMessage, false);
This assumes that document.activeElement is the textarea (should add a check for tagName), which should be true if the user has made a selection in the textarea, right?