Building your own Java Script Editor (Part 3 of 3)
In this last part I will discuss how to use the editor first you need to initalize an object from the editor class and give it the div id that you want to make it as an editor but to initialize it you need to put it this way
var editor;
RBM.AddListener(window,'load',RbmInit);
function RbmInit(){
editor = new RBMEditor.Editor('oDiv')
}
now to call a command simply type the following, you could change the BOLD Command with any of the commands listed in the EditorCommands which you could find it in the code or any other added command in it.
editor.ExecuteCommand(RBMEditor.EditorCommands.BOLD);
Finally hope that those post would help you to start your way in building your own editor. please feel free to ask me if you have any questions about more advanced techniques or more features like how to add a link , image etc.. I will try later to make seperate posts for how to enhance the editor with such commands.
Building your own Java Script Editor (Part 2 of 3)
In the last part we discussed the RBM Utility functions that will help us building our editor here we will discuss the editor it self
you could download the source from http://www.ramymostafa.com/wp-content/editordemos/RBMEditor.zip
you could view the demo from http://www.ramymostafa.com/wp-content/editordemos/TestEditor.htm
Basically the editor is initialized inside RBMEditor Namespace. I will highlight here some important methods in the editor
The Execute Command method first get the current selected range then extract the HTML from the range after that it checks if the effect is already applied or not and if it is it removes the effect using the ExecuteUndoCommand method if the effect isn’t applied then we create a new element from the command then the SetHTMLFromSelection method will replace the current selected range with the new command element in it the selected html
ExecuteCommand: function(sCommand,id,value,name,isControl){
var selection = RBM.GetSelectedRange(this.controlContent);
if(selection == null)
return;
var html = this.GetHTMLFromSelection(selection);
var undo = this.ExecuteUndoCommand(sCommand,new String(html));
if(!undo){
var element = this.CreateNewNode(sCommand,id,value,html);
if(element != null)
this.SetHTMLFromSelection(selection,element);
}
}
The GET HTML Method will parse the html and code and remove the unsupported tags and attributes from the html code
GetHTML: function(sCode){
//return sCode;
var ts = new String(sCode);
var parts = ts.split("<");
var subpart = '';
var i = 0;
var j = 0;
var totalStr = '';
var tagName = '';
var readTag = true;
var readSub = true;
for(i = 0; i < parts.length;i++)
{
if(parts[i] == '')
continue;
subpart = '';
tagName = '';
readTag = true;
readSub = true;
for(j = 0; j < parts[i].length; j++)
{
if(parts[i].substr(j,1) == '>')
readSub = false;
if(parts[i].substr(j,1) == ' ' || parts[i].substr(j,1) == '>')
readTag = false;
if(readSub == true)
subpart = subpart + parts[i].substr(j,1);
if(readTag == true)
tagName = tagName + parts[i].substr(j,1);
}
if(this.IsSupportedTag(tagName) == false)
{
parts[i] = parts[i].replace(subpart + '>',' ');
parts[i] = parts[i].replace('/' + tagName + '>',' ');
}
else
{
parts[i] = '<' + parts[i];
parts[i] = this.RemoveUnknownAttributes(
subpart.replace(tagName,''),parts[i]);
}
}
var retValue = '';
for(i = 0; i < parts.length;i++)
{
if(parts[i] != '')
retValue = retValue + parts[i];
}
var tnewValue = new String(retValue);
return tnewValue;
}
Next Part I will enhance the editor a little bit to have a code section also I will show how to use the editor for now you could check the demo code for knowing how to use the editor
Building your own Java Script Editor (Part 1 of 3)
few Months ago I had a situation in which i needed to build my own editor that will accept certain tags and attributes. I thought it would be very interesting to share how I built my editor in a browser independent way.
The first thing that came up to my mind then was what will be the container of my designer an IFrame a div or what then I decided that I will make it a div that I will set it’s contentEditable attribute to true.
The second thing was ok now my div could be edited by the end user in the design time how will I apply the tags to the selected content below you will find a utility library I have built that have the basic misc methods we will need built the editor in the next part I will show and explain the Editor Class for now let’s start up with the important methods in the utility library. (you could download it from here)
GetSelectedRange : function(controlContent){
var selectedRange = null;
if(document.selection)
selectedRange = document.selection.createRange();
else if(window.selection)
selectedRange = window.selection.createRange();
if(selectedRange == null){
if(window.getSelection() != null)
{
if (Exists(window.getSelection().getRangeAt))
selectedRange = window.getSelection().getRangeAt(0);
else { // Safari!
var range = document.createRange();
range.setStart(window.getSelection().anchorNode,
window.getSelection().anchorOffset);
range.setEnd(window.getSelection().focusNode,
window.getSelection().focusOffset);
selectedRange = range;
}
}
}
var t = null;
if(selectedRange != null && BrowserType.IE)
{
//Check if the range is within the editor div range
t = CheckParentById(controlContent.id,
selectedRange.parentElement());
}
else{
//Check if the range is within the editor div range
t = RangeCompareNode(selectedRange,controlContent);
}
if(!t && controlContent != null)
selectedRange = null;
return selectedRange;
}
The above code gets the selected range object in a browser independent way in order to work on it later on in the editor then it’s check if the selected range is within our editor div range if it’s not then return null otherwise return the range.
Here we check if the range is withing a parent node or not for browsers other than IE
// This function is used to get if the selected range in the required parent in firefox.
RangeCompareNode : function(range,node){
var nodeRange = node.ownerDocument.createRange();
try {
nodeRange.selectNode(node);
}
catch (e) {
nodeRange.selectNodeContents(node);
}
var nodeIsBefore = range.compareBoundaryPoints(Range.START_TO_START, nodeRange) == 1;
var nodeIsAfter = range.compareBoundaryPoints(Range.END_TO_END, nodeRange) == -1;
if (nodeIsBefore && !nodeIsAfter)
return false;
if (!nodeIsBefore && nodeIsAfter)
return false;
if (nodeIsBefore && nodeIsAfter)
return true;
return false;
}
Here we check if the range is withing a parent node or not for IE Browser
// This function is used to Check whether a parent element contains the child element or not using the parentId.
CheckParentById : function(parentId,child){
while(child != null){
if(child.id == parentId) return true;
child = child.parentNode;
}
return false;
}
Next part I will put the editor class and highlight the main parts of it with a demo of the editor working.
Add & Remove the SyntaxHighlighter Toolbar on MouseOver,MouseOut Events
The Syntax Highlighter Iam using here is syntaxhighlighter_2.0.296 made by alexgorbatchev It’s an amazing syntax highlighter actually nevertheless I had comment from one of my friends that the toolbar is hiding the code which is a little bit distracting so I decided to add a functionality on it so that the toolbar is initially not visible then it becomes visible when the mouse comes over the code section like that it will maintain the functionality and it will look nicer.
My first thought to do this was to edit the code highlighter my self then I decided to make it as an add on so that any updates in the original code doesn’t make me to re do the modification.
- First you need to have a utility file I made (click here) to have it
- Put a reference to the javascript file in the head of your html
- Place the following code in the head element
//Here I attach to the window onload event the method RbmInit to be called when the event is fired RbmBindEvent(window,'load',RbmInit); //Those are the two lines of initializing the SyntaxHighlighter SyntaxHighlighter.config.clipboardSwf = 'scripts/clipboard.swf'; SyntaxHighlighter.all(); function RbmInit() { var tags = RbmGetElementsByTagName(document,'div'); for (var i = 0; i < tags.length; i++) { var x = tags[i].className; if(RbmIsExists(x) && RbmStringContains(x,'syntaxhighlighter')) { //on mouse over I set the toolbar div visibility to visible tags[i].onmouseover = function(){ var childTags = RbmGetElementsByTagName(this,'div'); for (var j = 0; j < childTags.length; j++){ var y = childTags[j].className; if(RbmIsExists(y) && y == 'toolbar') { childTags[j].visible = true; childTags[j].style.visibility = 'visible'; } } } //on mouse out I set the toolbar div visibility to hidden tags[i].onmouseout = function(){ var childTags = RbmGetElementsByTagName(this,'div'); for (var j = 0; j < childTags.length; j++){ var y = childTags[j].className; if(RbmIsExists(y) && y == 'toolbar') { childTags[j].visible = false; childTags[j].style.visibility = 'hidden'; } } } } //Remove all div's with class toolbar if(RbmIsExists(x) && x == 'toolbar') { tags[i].visible = false; tags[i].style.visibility = 'hidden'; } } }
you could check the effect on any code section in my site hope you enjoy this feature
Solving ga_shade problem from Google Analytics
I have placed the Google Analytics Script in my site however today I have encountered a weird problem an overlay div called ga_shade
have been placed on top of my site disallowing me from using it. This was little bit scary since oops are my site viewers seeing what I see so I have tried to view the site on several browsers I found that this problem only arouses in my Firefox browser so I have made a little research and I found that this problem only arouses when you are logging in your analatycs account and it happens only to the owner of the account after you try to view the statistics of the page to know the traffic on each part of the page. Then to solve the problem I only cleared my browser cache and every thing worked for me.
