Analyse du code source de FCKEDITH (i) Analyse annotation chinoise de fckEditor.js a étudié le code source de fckEditor ces derniers jours (FckEditor est un éditeur Web avec un large éventail d'applications dans le réseau). J'ai besoin de remercier NileaderBlog pour sa traduction dure.
J'ai recherché presque tout Internet, et il semble que j'ai expliqué beaucoup sur le fichier fckconfig.js, mais les informations sur le fichier FCK de base de fckeditor.js sont presque 0.
Par conséquent, j'ai passé une journée à serrer le dentifrice pour commenter le fichier de base fckeditor.js, fckeditor.js, pour référence par des internautes qui apprennent également fckeditor.
Étant donné que le niveau de l'auteur est limité, ici, veuillez souligner les points inappropriés dans mes commentaires pour éviter les autres en erreur. Merci.
Il est recommandé de le copier dans votre IDE ou
Remarque: Cet article est basé sur fckEditor2.6.5
Pour plus d'informations faisant autorité, veuillez vous référer au Guide des développeurs officiels du FCK
La copie de code est la suivante:
/ **
*
********** Copyright *************
* -------- annoté par Nileader ----
* ---- Version 1.00 2009-10-18 ----
* ---- Une fois copié, marqué http://www.nileader.cn
*
* Classe FckEditor annotée par Nileader
* @param {objet} instanceName Le nom unique de l'éditeur (équivalent à ID) est un paramètre non sauvé.
* La largeur, la hauteur, le point d'outils, la valeur sont tous des paramètres facultatifs
* /
var fckEditor = fonction (instanceName, largeur, hauteur, barbe à outils, valeur)
{
// Propriétés de base de l'éditeur Remarque: Ces choses ont priorité sur la configuration dans fckconfig.js
this.instanceName = instanceName; // Le nom unique de l'éditeur (équivalent à ID) (doit avoir!)
this.width = largeur || «100%»; // La largeur est à 100% par défaut
this.height = hauteur || «200»; // La largeur est de 200 par défaut
this.toolBarSet = ToolbarSet || 'Par défaut'; // le nom de jeu d'outil, la valeur par défaut est par défaut
this.value = valeur || ''; // Initialise le code HTML de l'éditeur, la valeur par défaut est vide
// Le chemin racine par défaut lorsque l'éditeur est initialisé est d'écrire FCK. Tous les chemins utilisés sont par défaut vers / fckEditor / From the fckEditor.BasePath.
this.basepath = fckEditor.basepath;
this.CheckBrowser = true; // s'il faut vérifier la compatibilité du navigateur avant d'afficher l'éditeur, la valeur par défaut est vraie
this.displayErrors = true; // s'il s'affiche avec des erreurs, la valeur par défaut est vraie
this.config = new object ();
// événements
this.onerror = null; // Fonction (source, errornumber, errordescription) Fonction de gestion des erreurs personnalisées
}
FckEditor.BasePath = '/ fckEditor /'; // Répertoire racine par défaut de FCK
FckEditor.Minheight = 200; // les limites de la hauteur et de la largeur
FckEditor.minwidth = 750;
FckEditor.prototype.version = '2.6.5'; // Numéro de version
FckEditor.prototype.versionBuild = '23959';
/ **
* Appelez CreateHtml () pour générer le code HTML de l'éditeur et sortir l'éditeur sur la page
* /
FckEditor.prototype.create = function ()
{
// appelle la méthode createhtml ()
document.write (this.createhtml ());
}
/ **
* Code HTML @return shtml utilisé pour générer l'éditeur
* /
Fckeditor.prototype.createhtml = fonction ()
{
// Vérifiez s'il y a un nom d'instance, aucun code HTML ne sera généré
if (! this.instancename || this.instanceName.length == 0)
{
this._throwerror (701, «vous devez spécifier un nom d'instance.»);
retour '' ;
}
// Valeur de retour de la fonction
var shtml = '';
/ *
* Lorsque le navigateur de l'utilisateur rencontre plusieurs navigateurs prédéfinis,
* Générer une zone de texte avec id = this.instanceName name = this.instanceName, le stockage de contenu de facto
* /
if (! this.checkbrowser || this._iscompatibleBrowser ())
{
// Mettez cette entrée après l'échappement de la valeur initiale FCK
shtml + = '<input type = Hidden id =' + this.instanceName + 'name =' + this.instanneName + 'value =' + this._htmlencode (this.value) + 'style = affiche: Aucun style = affichage: non />';
// Générez une entrée cachée pour placer le contenu dans ce.config
shtml + = this._getconfightml ();
// Code pour générer l'iframe de l'éditeur
shtml + = this._GetIframeHtml ();
}
/ **
* Si le navigateur de l'utilisateur n'est pas compatible avec les navigateurs FCK par défaut
* Seuls les textares traditionnels peuvent être trouvés
* /
autre
{
var swidth = this.width.toString (). indexof ('%')> 0? this.width: this.width + 'px';
var sheight = this.height.toString (). indexof ('%')> 0? this.height: this.height + 'px';
shtml + = '<textarea name =' + this.instanceName +
'lignes = 4 cols = 40 style = largeur:' + swidth +
'; hauteur:' + sheight;
if (this.tabindex)
shtml + = 'tabindex =' + this.tabindex;
shtml + = '>' +
this._htmlencode (this.value) +
'<// textarea>';
}
retour shtml;
}
/ **
* Utilisez l'éditeur pour remplacer la zone de texte correspondante
* /
FckEditor.prototype.replaceTextArea = function ()
{
// Si vous avez déjà le trame TAG ID = this.instanceName ___, retournez directement
if (document.getElementById (this.instanceName + '___frame')))
retour ;
// lorsque le navigateur de l'utilisateur rencontre plusieurs navigateurs de préréglage
if (! this.checkbrowser || this._iscompatibleBrowser ())
{
// Nous devons vérifier les éléments en utilisant d'abord l'ID puis le nom.
// Obtenez la balise HTML de id = this.instanceName
var otextarea = document.getElementById (this.instanceName);
// Obtenez toutes les balises de nom = this.instanceName
var ColelementsByName = document.getElementsByName (this.instanceName);
var i = 0;
/ *
* Étant donné que la dénomination de la balise HTML de l'utilisateur n'est pas standardisée, l'enregistrement suivant est fait pour déterminer que l'auteur se réfère à l'utilisateur à l'aide de Name = this.instanceName dans la balise TextArea.
* Name = this.instancename est également utilisé sur d'autres balises sur la même page
* /
while (otextarea || i == 0)
{
// voyage jusqu'à la tag de nom de nom = this.instancename est trouvé et affecté à otextarea
if (otextarea && otextarea.tagname.tolowercase () == 'textarea')
casser;
otextarea = colementsByName [i ++];
}
// S'il n'y a pas de balise avec ID ou nom de ce.instanceName, une boîte d'erreur apparaît
si (! otextarea)
{
alert ('error: le textarea avec ID ou nom défini sur' + this.instanceName + 'n'a pas été trouvé');
retour ;
}
/ *
* Après avoir confirmé que la balise TextArea avec nom = this.instancename existe, attribuez le code de l'éditeur
* /
otextarea.style.display = 'Aucun';
// Si l'ordre des clés de l'abat est défini sur la page pour ces balises textarea, affectez-le à ce.tabindex pour une utilisation ultérieure
if (otextarea.tabindex)
this.tabindex = otextarea.tabindex;
this._inserthtmlbefore (this._getconfightml (), otextarea);
this._inserthtmlbefore (this._getiframehtml (), otextarea);
}
}
/ **
* Insérez le code HTML devant la balise de page spécifiée
* @param {objet} code html à insérer
* @param {objet} Tag de page spécifiée (objet)
* /
Fckeditor.prototype._inserthtmlbefore = fonction (html, élément)
{
if (element.insertadjacenthtml) // ie insertadjacenthtml méthode
element.insertAdjacentHtml ('avantbegin', html);
Else // Navigateur non IE
{
var orange = document.Createrange ();
orange.setStartBefore (élément);
var ofragment = orange.CreateContextualFragment (html);
element.parentNode.insertBefore (Ofragment, élément);
}
}
/ *
* Générez un domaine caché en modifiant ce.config [].
* Par exemple:
* this.config ['nileader'] = 1104, this.config ['Leaderni'] = Nichao ...
* Ensuite, Sconfig =… & Nileader = 1104 & Leaderni = Nichao…
* Bien sûr, en fin de compte, SCONFIG sera converti en un pourcentage de codage par la fonction d'encodérée et mis dans une entrée cachée
* /
FckEditor.prototype._getConfightml = fonction ()
{
var sconfig = '';
pour (var o dans ce.config)
{
if (sconfig.length> 0) sconfig + = '&';
// La fonction d'encododirocomponent est convertie en pourcentage
SCONFIG + = EncodeuRIComponent (O) + '=' + EncodeuRIComponent (this.config [o]);
}
return '<input type = Hidden id =' + this.instanceName + '___config value =' + sconfig + 'style = affiche: aucun style = affichage: non />';
}
/ *
* Générez le HTML de l'Iframe. Ici, cela implique la détermination de SRC
* /
Fckeditor.prototype._getiframehtml = function ()
{
var sfile = 'fckEditor.html';
// Cas spéciale, la fenêtre où se trouve fckedito n'est pas intégré dans le navigateur
essayer
{
if ((/ fcksource = true / i) .test (window.top.location.search))
sfile = 'fckeditor.original.html';
}
Catch (e) {/ * ignore cette exception. Plusieurs fois, la fenêtre où se trouve fckedito est intégrée dans le navigateur. * /}
/ *
* Une chose à noter ici:
* Comment fonctionne Iframe: lorsque l'Iframe est à l'état modifiable, la page où SRC est réellement édité
* Voici un slink pour le mettre dans la balise iframe
* /
// slink est cette page de facto, à partir du répertoire racine de fck, par exemple, slink = / fckEditor / editor / fckEditor.html? InstanceName = Nileader & Toolbar = Nileadersbar
var slink = this.basepath + 'editor /' + sfile + '? instancename =' + encodeuRIComponent (this.instanceName);
if (this.toolbarset)
slink + = '& toolbar =' + this.toolbarset;
// Générer un véritable code HTML pour éditer Iframer, bien sûr, mettez Src = Slink
var html = '<iframe id =' + this.instanceName +
'___Frame src =' + slink +
'src =' + slink +
'width =' + this.width +
'height =' + this.height;
// Si l'ordre de traversée à l'aide de la touche Tab est définis, alors attribuez-le à l'IFRAME
if (this.tabindex)
html + = 'tabindex =' + this.tabindex;
html + = 'frameborder = 0 Scrolling = no> </ iframe>';
retour html;
}
/ *
* Vérifiez si le Bowser de l'utilisateur est la valeur par défaut de FCK
* Cette méthode est juste une entreprise FK qui poursuit OO, sans signification
* /
FckEditor.prototype._iscompatibleBrowser = function ()
{
return fckEditor_iscompatibleBrowser ();
}
/ **
* Erreur lancée
* @param {objet} ErrorNumber Error Number
* @param {objet} Présentation de l'erreur ErrorDescription
* /
Fckeditor.prototype._throwerror = fonction (errornumber, errordescription)
{
this.errornumber = errorNumber;
this.errorDescription = errorDescription;
// s'il s'affiche avec des erreurs, la valeur par défaut est vraie
if (this.displayerrors)
{// Imprimez le numéro d'erreur et la vue d'ensemble d'erreur
Document.Write ('<div Style = Color: # FF0000 Style = Color: # FF0000>');
Document.Write ('[FCKEDITOR ERROR' + This.ErrorNumber + ':' + this.errorDescription + ']');
Document.Write ('</div>');
}
// onerror si la fonction de gestion des erreurs est personnalisée, si elle est définie, elle sera gérée par elle
if (typeof (this.onerror) == 'fonction')
this.onerror (this, errorNumber, errordescription);
}
/ **
* Texte d'échappement
* @param {objet} Texte à échapper
* @return string text après échappement
* /
FckEditor.prototype._htmlencode = fonction (texte)
{
if (typeof (texte)! = chaîne)
text = text.toString ();
// remplacer All & <> dans la chaîne avec les caractères d'échappement correspondants
text = text.replace (
/ & / g, &). Remplacer (
// g,) .replace (
/ </ g, <). Remplacer (
/> / g,>);
Retour Texte;
}
;(fonction()
{
// Attribuez l'élément TextArea sur la page à la variable de l'éditeur
var textareatoEditor = function (textarea)
{
var editor = new fckEditor (textarea.name);
editor.width = math.max (textarea.offsetwidth, fckEditor.minwidth);
editor.height = math.max (textarea.offsetheight, fckEditor.minheight);
Return Editor;
}
/ **
* Remplacez tous les éléments <Textarea> disponibles dans le document par fckEditor
* Instances.
*
* // Remplacez tous les éléments <TextArea> de la page.
* FckEditor.replaceAlTTextAreas ();
*
* // Remplacez tous les éléments <textarea class = myClassName> dans la page.
* FckEditor.replaceAllTextAreas ('myClassName');
*
* // Remplacer sélectivement les éléments <TextArea>, basés sur des affirmations personnalisées.
* FckEditor.replaceAllTextAreas (Fonction (TextArea, éditeur)
* {
* // Code personnalisé pour évaluer le remplacement, renvoyant faux si elle
* // ne doit pas être fait.
* // il passe également le paramètre de l'éditeur, afin que le développeur puisse
* // Personnalisez l'instance.
*});
* /
FckEditor.ReplaceAllTextAreas = function ()
{
// Obtenez tous les éléments de TextArea
var textAreas = document.getElementsByTagName ('textArea');
pour (var i = 0; i <textareas.length; i ++)
{
var editor = null;
var textArea = textAreas [i];
var name = textarea.name;
// L'attribut de nom doit exister.
if (! name || name.length == 0)
continuer ;
if (typeof arguments [0] == 'String')
{
// Le nom de la classe TextArea pourrait être passé comme fonction
// paramètre.
var classRegex = new regexp ('(?: ^ |)' + arguments [0] + '(?: $ |)');
if (! classRegex.test (textarea.classname)))
continuer ;
}
else if (typeof arguments [0] == 'function')
{
// Une fonction d'affirmation pourrait être adoptée comme paramètre de fonction.
// il doit renvoyer explicitement False pour ignorer un <TextArea> spécifique.
editor = textAreatoEditor (TextArea);
if (arguments [0] (textarea, éditeur) === false)
continuer ;
}
if (! éditeur)
editor = textAreatoEditor (TextArea);
editor.replaceTextArea ();
}
}
}) ();
/ **
* Détecter la compatibilité du navigateur
* À l'aide de certaines informations renvoyées par l'objet Navigator, il détermine que le navigateur renvoie les informations, y compris le nom de code du navigateur, le nom du navigateur, le langage de la version du navigateur et d'autres informations et minuscules
* Par exemple:
* Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)
*
* Lors du jugement du navigateur IE, la compilation conditionnelle prise en charge après l'utilisation de IE4.0 est ajoutée.
* Puisqu'il n'est pris en charge que par IE, cette propriété n'est pas prise en charge dans les navigateurs standard W3C. Par conséquent, l'IE est jugé de manière appropriée en utilisant cette fonctionnalité
* /
fonction fckEditor_iscompatibleBrowser ()
{
var sagent = navigator.useragent.tolowercase ();
// Le navigateur actuel est Internet Explorer 5.5+
// Utilisez une compilation conditionnelle pour juger IE dans IE, / * @ cc_on! @ * / False ==! false == true,
// S'il s'agit d'un navigateur non IE, ignorez-le, / * @ cc_on! @ * / False == false
if (/ * @ cc_on! @ * / false && sagent.indexof (mac) == -1) // pas Apple mac os
{
var sbrowserVersion = Navigator.Appversion.match (/ msie (./..)/) )1];
return (sbrowserVersion> = 5.5);
}
// Gecko (Opera 9 essaie de se comporter comme Gecko à ce stade).
// Détection si c'est le navigateur Opera 9
if (Navigator.Product == Gecko && navigator.productSub> = 20030210 &&! (typeof (opera) == 'objet' && opera.posterror))
Retour Vrai;
// Opera 9.50+
if (window.opera && window.opera.version && parsefloat (window.opera.version ())> = 9.5)
Retour Vrai;
// Adobe Air
// vérifié avant safari car l'air a l'éditeur de texte riche en webkit
// Caractéristiques de Safari 3.0.4, mais la version rapportée est 420.
if (sagent.indexof ('Adobeaur /')! = -1)
return (sagent.match (/ adobeair // (/ d +) /) [1]> = 1); // La construction doit être au moins V1
// Safari 3+
if (sagent.indexof ('Applewebkit /')! = -1)
return (sagent.match (/ applewebkit // (/ d +) /) [1]> = 522); // Build doit être d'au moins 522 (V3)
retourne false;
}