@ -0,0 +1,38 @@ | |||
* text=auto !eol | |||
barre_outils/edition.php -text | |||
barre_outils/forum.php -text | |||
/barre_outils_icones.css.html -text | |||
css/barre_outils.css -text | |||
css/images/handle.png -text | |||
css/images/menu.png -text | |||
css/images/submenu.png -text | |||
icones_barre/clean.png -text | |||
icones_barre/eye.png -text | |||
icones_barre/keyboard.png -text | |||
icones_barre/text_bold.png -text | |||
icones_barre/text_indent.png -text | |||
icones_barre/text_indent_remove.png -text | |||
icones_barre/text_italic.png -text | |||
icones_barre/text_list_bullets.png -text | |||
icones_barre/text_list_numbers.png -text | |||
icones_barre/text_strikethrough.png -text | |||
inc/barre.php -text | |||
inc/barre_outils.php -text | |||
javascript/jquery.markitup.js -text | |||
javascript/jquery.markitup_pour_spip.js -text | |||
javascript/jquery.previsu_spip.js -text | |||
lang/barre_outils_ar.php -text | |||
lang/barre_outils_en.php -text | |||
lang/barre_outils_fr.php -text | |||
markitup/readme.txt -text | |||
markitup/templates/preview.css -text | |||
markitup/templates/preview.html -text | |||
/plugin.xml -text | |||
/porte_plume.js.html -text | |||
/porte_plume.js_fonctions.php -text | |||
/porte_plume_options.php -text | |||
/porte_plume_pipelines.php -text | |||
/preview.html -text | |||
tests/all_tests.php -text | |||
tests/barre_outil_markitup.php -text | |||
tests/lanceur_spip.php -text |
@ -0,0 +1,408 @@ | |||
<?php | |||
/* | |||
* Plugin Porte Plume pour SPIP 2 | |||
* Licence GPL | |||
* Auteur Matthieu Marcillaud | |||
*/ | |||
if (!defined("_ECRIRE_INC_VERSION")) return; | |||
/** | |||
* Definition de la barre 'edition' pour markitup | |||
*/ | |||
function barre_outils_edition(){ | |||
$set = new Barre_outils(array( | |||
'nameSpace' => 'edition', | |||
#'previewAutoRefresh'=> true, | |||
#'previewParserPath' => url_absolue(generer_url_public('preview')), | |||
'onShiftEnter' => array('keepDefault'=>false, 'replaceWith'=>"\n_ "), | |||
'onCtrlEnter' => array('keepDefault'=>false, 'replaceWith'=>"\n\n"), | |||
// garder les listes si on appuie sur entree | |||
'onEnter' => array('keepDefault'=>false, 'selectionType'=>'return', 'replaceWith'=>"\n"), | |||
'onTab' => array('keepDefault'=>false, 'replaceWith'=>"\t"), | |||
'markupSet' => array( | |||
// H1 - {{{ | |||
array( | |||
"id" => 'header1', | |||
"name" => _T('barre_outils:barre_intertitre'), | |||
"key" => "H", | |||
"className" => "outil_header1", | |||
"openWith" => "\n{{{", | |||
"closeWith" => "}}}\n", | |||
"display" => true, | |||
"selectionType" => "line", | |||
), | |||
// Bold - {{ | |||
array( | |||
"id" => 'bold', | |||
"name" => _T('barre_outils:barre_gras'), | |||
"key" => "B", | |||
"className" => "outil_bold", | |||
"openWith" => "{{", | |||
"closeWith" => "}}", | |||
"display" => true, | |||
"selectionType" => "word", | |||
), | |||
// Italic - { | |||
array( | |||
"id" => 'italic', | |||
"name" => _T('barre_outils:barre_italic'), | |||
"key" => "I", | |||
"className" => "outil_italic", | |||
"openWith" => "{", | |||
"closeWith" => "}", | |||
"display" => true, | |||
"selectionType" => "word", | |||
), | |||
// montrer une suppression | |||
array( | |||
"id" => 'stroke_through', | |||
"name" => _T('barre_outils:barre_barre'), // :-) | |||
"className" => "outil_stroke_through", | |||
"openWith" => "<del>", | |||
"closeWith" => "</del>", | |||
"display" => true, | |||
"selectionType" => "word", | |||
), | |||
// listes -* | |||
array( | |||
"id" => 'liste_ul', | |||
"name" => _T('barre_outils:barre_liste_ul'), | |||
"className" => "outil_liste_ul", | |||
"replaceWith" => "function(h){ return outil_liste(h, '*');}", | |||
"display" => true, | |||
"selectionType" => "line", | |||
"forceMultiline" => true, | |||
"dropMenu" => array( | |||
// liste -# | |||
array( | |||
"id" => 'liste_ol', | |||
"name" => _T('barre_outils:barre_liste_ol'), | |||
"className" => "outil_liste_ol", | |||
"replaceWith" => "function(h){ return outil_liste(h, '#');}", | |||
"display" => true, | |||
"selectionType" => "line", | |||
"forceMultiline" => true, | |||
), | |||
// indenter | |||
array( | |||
"id" => 'indenter', | |||
"name" => _T('barre_outils:barre_indenter'), | |||
"className" => "outil_indenter", | |||
"replaceWith" => "function(h){return outil_indenter(h);}", | |||
"display" => true, | |||
"selectionType" => "line", | |||
"forceMultiline" => true, | |||
), | |||
// desindenter | |||
array( | |||
"id" => 'desindenter', | |||
"name" => _T('barre_outils:barre_desindenter'), | |||
"className" => "outil_desindenter", | |||
"replaceWith" => "function(h){return outil_desindenter(h);}", | |||
"display" => true, | |||
"selectionType" => "line", | |||
"forceMultiline" => true, | |||
), | |||
), | |||
), | |||
// separation | |||
array( | |||
"id" => "sepLink", // trouver un nom correct ! | |||
"separator" => "---------------", | |||
"display" => true, | |||
), | |||
// lien spip | |||
array( | |||
"id" => 'link', | |||
"name" => _T('barre_outils:barre_lien'), | |||
"key" => "L", | |||
"className" => "outil_link", | |||
"openWith" => "[", | |||
"closeWith" => "->[!["._T('barre_outils:barre_lien_input')."]!]]", | |||
"display" => true, | |||
), | |||
// note en bas de page spip | |||
array( | |||
"id" => 'notes', | |||
"name" => _T('barre_outils:barre_note'), | |||
"className" => "outil_notes", | |||
"openWith" => "[[", | |||
"closeWith" => "]]", | |||
"display" => true, | |||
"selectionType" => "word", | |||
), | |||
// separation | |||
// (affichee dans forum) | |||
array( | |||
"id" => "sepCitations", // trouver un nom correct ! | |||
"separator" => "---------------", | |||
"display" => false, | |||
), | |||
// quote spip | |||
// (affichee dans forum) | |||
array( | |||
"id" => 'quote', | |||
"name" => _T('barre_outils:barre_quote'), | |||
"key" => "Q", | |||
"className" => "outil_quote", | |||
"openWith" => "\n<quote>", | |||
"closeWith" => "</quote>\n", | |||
"display" => false, | |||
"selectionType" => "word", | |||
), | |||
// separation | |||
array( | |||
"id" => "sepGuillemets", | |||
"separator" => "---------------", | |||
"display" => true, | |||
), | |||
// guillemets | |||
array( | |||
"id" => 'guillemets', | |||
"name" => _T('barre_outils:barre_guillemets'), | |||
"className" => "outil_guillemets", | |||
"openWith" => "«", | |||
"closeWith" => "»", | |||
"display" => true, | |||
"lang" => array('fr','eo','cpf','ar','es'), | |||
"selectionType" => "word", | |||
), | |||
// guillemets internes | |||
array( | |||
"id" => 'guillemets_simples', | |||
"name" => _T('barre_outils:barre_guillemets_simples'), | |||
"className" => "outil_guillemets_simples", | |||
"openWith" => "“", | |||
"closeWith" => "”", | |||
"display" => true, | |||
"lang" => array('fr','eo','cpf','ar','es'), | |||
"selectionType" => "word", | |||
), | |||
// guillemets de | |||
array( | |||
"id" => 'guillemets_de', | |||
"name" => _T('barre_outils:barre_guillemets'), | |||
"className" => "outil_guillemets_de", | |||
"openWith" => "„", | |||
"closeWith" => "“", | |||
"display" => true, | |||
"lang" => array('bg','de','pl','hr','src'), | |||
"selectionType" => "word", | |||
), | |||
// guillemets de, simples | |||
array( | |||
"id" => 'guillemets_de_simples', | |||
"name" => _T('barre_outils:barre_guillemets_simples'), | |||
"className" => "outil_guillemets_de_simples", | |||
"openWith" => "‚", | |||
"closeWith" => "‘", | |||
"display" => true, | |||
"lang" => array('bg','de','pl','hr','src'), | |||
"selectionType" => "word", | |||
), | |||
// guillemets autres langues | |||
array( | |||
"id" => 'guillemets_autres', | |||
"name" => _T('barre_outils:barre_guillemets'), | |||
"className" => "outil_guillemets_simples", | |||
"openWith" => "“", | |||
"closeWith" => "”", | |||
"display" => true, | |||
"lang_not" => array('fr','eo','cpf','ar','es','bg','de','pl','hr','src'), | |||
"selectionType" => "word", | |||
), | |||
// guillemets simples, autres langues | |||
array( | |||
"id" => 'guillemets_autres_simples', | |||
"name" => _T('barre_outils:barre_guillemets_simples'), | |||
"className" => "outil_guillemets_uniques", | |||
"openWith" => "‘", | |||
"closeWith" => "’", | |||
"display" => true, | |||
"lang_not" => array('fr','eo','cpf','ar','es','bg','de','pl','hr','src'), | |||
"selectionType" => "word", | |||
), | |||
// separation | |||
array( | |||
"id" => "sepCaracteres", | |||
"separator" => "---------------", | |||
"display" => true, | |||
), | |||
// icones clavier | |||
array( | |||
"id" => 'grpCaracteres', | |||
"name" => _T('barre_outils:barre_inserer_caracteres'), | |||
"className" => 'outil_caracteres', | |||
"display" => true, | |||
"dropMenu" => array( | |||
// A majuscule accent grave | |||
array( | |||
"id" => 'A_grave', | |||
"name" => _T('barre_outils:barre_a_accent_grave'), | |||
"className" => "outil_a_maj_grave", | |||
"replaceWith" => "À", | |||
"display" => true, | |||
"lang" => array('fr','eo','cpf'), | |||
), | |||
// E majuscule accent aigu | |||
array( | |||
"id" => 'E_aigu', | |||
"name" => _T('barre_outils:barre_e_accent_aigu'), | |||
"className" => "outil_e_maj_aigu", | |||
"replaceWith" => "É", | |||
"display" => true, | |||
"lang" => array('fr','eo','cpf'), | |||
), | |||
// oe | |||
array( | |||
"id" => 'oe', | |||
"name" => _T('barre_outils:barre_eo'), | |||
"className" => "outil_oe", | |||
"replaceWith" => "œ", | |||
"display" => true, | |||
"lang" => array('fr'), | |||
), | |||
// OE | |||
array( | |||
"id" => 'OE', | |||
"name" => _T('barre_outils:barre_eo_maj'), | |||
"className" => "outil_oe_maj", | |||
"replaceWith" => "Œ", | |||
"display" => true, | |||
"lang" => array('fr'), | |||
), | |||
), | |||
), | |||
// separation | |||
array( | |||
"id" => "sepPreview", // trouver un nom correct ! | |||
"separator" => "---------------", | |||
"display" => true, | |||
), | |||
// clean | |||
array( | |||
"id" => 'clean', | |||
"name" => _T('barre_outils:barre_clean'), | |||
"className" => "outil_clean", | |||
"replaceWith" => 'function(markitup) { return markitup.selection.replace(/<(.*?)>/g, "") }', | |||
"display" => true, | |||
), | |||
// preview | |||
array( | |||
"id" => 'preview', | |||
"name" => _T('barre_outils:barre_preview'), | |||
"className" => "outil_preview", | |||
"call" => "preview", | |||
"display" => true, | |||
), | |||
), | |||
'functions' => " | |||
// remplace ou cree -* ou -** ou -# ou -## | |||
function outil_liste(h, c) { | |||
if ((s = h.selection) && (r = s.match(/^-([*#]+) (.*)\$/))) { | |||
r[1] = r[1].replace(/[#*]/g, c); | |||
s = '-'+r[1]+' '+r[2]; | |||
} else { | |||
s = '-' + c + ' '+s; | |||
} | |||
return s; | |||
} | |||
// indente des -* ou -# | |||
function outil_indenter(h) { | |||
if (s = h.selection) { | |||
if (s.substr(0,2)=='-*') { | |||
s = '-**' + s.substr(2); | |||
} else if (s.substr(0,2)=='-#') { | |||
s = '-##' + s.substr(2); | |||
} else { | |||
s = '-* ' + s; | |||
} | |||
} | |||
return s; | |||
} | |||
// desindente des -* ou -** ou -# ou -## | |||
function outil_desindenter(h){ | |||
if (s = h.selection) { | |||
if (s.substr(0,3)=='-**') { | |||
s = '-*' + s.substr(3); | |||
} else if (s.substr(0,3)=='-* ') { | |||
s = s.substr(3); | |||
} else if (s.substr(0,3)=='-##') { | |||
s = '-#' + s.substr(3); | |||
} else if (s.substr(0,3)=='-# ') { | |||
s = s.substr(3); | |||
} | |||
} | |||
return s; | |||
} | |||
", | |||
)); | |||
$set->cacher(array( | |||
'stroke_through', | |||
'clean', 'preview', | |||
)); | |||
return $set; | |||
} | |||
/** | |||
* Definitions des liens entre css et icones | |||
*/ | |||
function barre_outils_edition_icones(){ | |||
return array( | |||
//'outil_header1' => 'text_heading_1.png', | |||
'outil_header1' => 'intertitre.png', | |||
'outil_bold' => 'text_bold.png', | |||
'outil_italic' => 'text_italic.png', | |||
'outil_stroke_through' => 'text_strikethrough.png', | |||
'outil_liste_ul' => 'text_list_bullets.png', | |||
'outil_liste_ol' => 'text_list_numbers.png', | |||
'outil_indenter' => 'text_indent.png', | |||
'outil_desindenter' => 'text_indent_remove.png', | |||
//'outil_quote' => 'text_indent.png', | |||
'outil_quote' => 'quote.png', | |||
//'outil_link' => 'world_link.png', | |||
'outil_link' => 'lien.png', | |||
'outil_notes' => 'notes.png', | |||
'outil_guillemets' => 'guillemets.png', | |||
'outil_guillemets_simples' => 'guillemets-simples.png', | |||
'outil_guillemets_de' => 'guillemets-de.png', | |||
'outil_guillemets_de_simples' => 'guillemets-uniques-de.png', | |||
'outil_guillemets_uniques' => 'guillemets-uniques.png', | |||
'outil_caracteres' => 'keyboard.png', | |||
'outil_a_maj_grave' => 'agrave-maj.png', | |||
'outil_e_maj_aigu' => 'eacute-maj.png', | |||
'outil_oe' => 'oelig.png', | |||
'outil_oe_maj' => 'oelig-maj.png', | |||
'outil_clean' => 'clean.png', | |||
'outil_preview' => 'eye.png', | |||
); | |||
} | |||
?> |
@ -0,0 +1,33 @@ | |||
<?php | |||
/* | |||
* Plugin Porte Plume pour SPIP 2 | |||
* Licence GPL | |||
* Auteur Matthieu Marcillaud | |||
*/ | |||
if (!defined("_ECRIRE_INC_VERSION")) return; | |||
/** | |||
* Definition de la barre 'forum' pour markitup | |||
*/ | |||
function barre_outils_forum(){ | |||
// on modifie simplement la barre d'edition | |||
$edition = charger_fonction('edition','barre_outils'); | |||
$barre = $edition(); | |||
$barre->nameSpace = 'forum'; | |||
$barre->cacherTout(); | |||
$barre->afficher(array( | |||
'bold','italic', | |||
'sepLink','link', | |||
'sepCitations', 'quote', | |||
'sepCaracteres','guillemets', 'guillemets_simples', | |||
'guillemets_de', 'guillemets_de_simples', | |||
'guillemets_autres', 'guillemets_autres_simples', | |||
'A_grave', 'E_aigu', 'oe', 'OE', | |||
)); | |||
return $barre; | |||
} | |||
?> |
@ -0,0 +1,7 @@ | |||
#CACHE{7*24*3600} | |||
#HTTP_HEADER{Content-Type: text/css; charset=utf-8} | |||
#HTTP_HEADER{Vary: Accept-Encoding} | |||
[(#VAL|barre_outils_css_icones)] | |||
/* roue ajax */ | |||
.ajaxLoad{background:white url('[(#CHEMIN{images/searching.gif}|url_absolue)]') top left no-repeat;} |
@ -0,0 +1,141 @@ | |||
.formulaire_spip textarea.markItUpEditor { | |||
width:96%; /* reduire la taille par defaut des formulaires spip */ | |||
} | |||
/* ------------------------------------------------------------------- | |||
// markItUp! Universal MarkUp Engine, JQuery plugin | |||
// By Jay Salvat - http://markitup.jaysalvat.com/ | |||
// ------------------------------------------------------------------*/ | |||
.markItUp .markItUpHeader a, | |||
.markItUp .markItUpTabs a, | |||
.markItUp .markItUpFooter a { | |||
color:#000; | |||
text-decoration:none; | |||
} | |||
.markItUp { | |||
margin:5px 0 5px 0; | |||
clear:both; | |||
} | |||
.markItUp .markItUpContainer { | |||
margin:0px; padding:0px; | |||
} | |||
.markItUp .markItUpEditor { | |||
padding:5px; | |||
height:320px; /* la hauteur est calculee par SPIP */ | |||
clear:both; display:block; | |||
overflow:auto; | |||
} | |||
.markItUp .markItUpPreviewFrame {} | |||
.markItUp .markItUpFooter { | |||
margin:0px; padding:0px; | |||
width:100%; | |||
} | |||
.markItUp .markItUpResizeHandle { | |||
overflow:hidden; | |||
width:22px; height:5px; | |||
margin-left:auto; | |||
margin-right:auto; | |||
background-image:url(images/handle.png); | |||
cursor:ns-resize; | |||
} | |||
/***************************/ | |||
/* tabs */ | |||
.markItUp .markItUpTabs { | |||
text-align:right; margin-bottom:3px; padding:1px 1px 0; | |||
border-bottom:1px solid #888; overflow:hidden; | |||
width:auto; float:right; clear:both;} | |||
.markItUp .markItUpTabs a { | |||
display:block; float:right; border:1px solid #888; margin:0px 1px; border-bottom:none; | |||
padding:3px 4px 2px 4px; background:#f0f0f0; | |||
-moz-border-radius:5px 5px 0 0;-webkit-border-top-left-radius:5px;-webkit-border-top-right-radius:5px;} | |||
.markItUp .markItUpTabs a.on {background:#fff; } | |||
.markItUp .markItUpTabs a:hover {background:#fff;} | |||
/***************************/ | |||
/* previsu */ | |||
.markItUp .markItUpPreview { | |||
clear:both; | |||
border:1px solid #888; | |||
background:#fff; | |||
overflow:auto; | |||
padding:1em; | |||
} | |||
/* correction des styles spip_formulaires appliques par defaut (grr) */ | |||
.markItUp .preview p {margin-bottom:1em;} | |||
.markItUp .preview ul {margin-bottom:1em; margin-top:0.5em;} | |||
.markItUp .preview li {border:none; padding:1px;} | |||
/* coloration code */ | |||
.markItUp .preview .cadre ol, | |||
.markItUp .preview .cadre ul {padding:0.5em;} | |||
/***************************************************************************************/ | |||
/* first row of buttons */ | |||
.markItUp .markItUpHeader { margin:0px; padding:0px;} | |||
.markItUp .markItUpHeader ul li { | |||
list-style:none; | |||
float:left; | |||
position:relative; | |||
clear:none; | |||
border:0; | |||
margin:0; | |||
padding:0; | |||
overflow:visible; | |||
} | |||
.markItUp .markItUpHeader ul li:first-child { /* annuler un reglage des forms prive */ | |||
padding-top:0; | |||
} | |||
.markItUp .markItUpHeader ul .markItUpDropMenu { | |||
/*background:inherit url(images/menu.png) no-repeat 100% 80%; | |||
padding-right:10px;*/ | |||
} | |||
.markItUp .markItUpHeader ul .markItUpDropMenu li { | |||
margin-right:0px; | |||
background-color: #eee; | |||
padding:2px 1px 2px 0; | |||
} | |||
.markItUp .markItUpHeader ul .markItUpDropMenu li:first-child{padding-left:2px;} | |||
/* next rows of buttons */ | |||
.markItUp .markItUpHeader ul ul { | |||
display:none; | |||
position:absolute; | |||
top:24px; left:-2px; | |||
width:150px; | |||
} | |||
.markItUp .markItUpHeader ul ul li { | |||
float:left; | |||
} | |||
.markItUp .markItUpHeader ul ul .markItUpDropMenu { | |||
background:#F5F5F5 url(images/submenu.png) no-repeat 50% 50%; | |||
} | |||
.markItUp .markItUpHeader ul .markItUpSeparator { | |||
margin:0 6px; | |||
width:0px; | |||
height:16px; | |||
overflow:hidden; | |||
} | |||
.markItUp .markItUpHeader ul ul .markItUpSeparator { | |||
width:auto; height:1px; | |||
margin:0px; | |||
} | |||
.markItUp .markItUpHeader ul a { | |||
display:block; | |||
width:16px; height:16px; | |||
text-indent:-10000px; | |||
background-repeat:no-repeat; | |||
background-position:50% 50%; | |||
background-color:#f5f5f5; | |||
border:1px solid #ccc; | |||
padding:3px; | |||
margin-right:1px; | |||
} | |||
.markItUp .markItUpHeader ul a:hover{border:1px solid #888; background-color:#fff;} | |||
@ -0,0 +1,42 @@ | |||
<?php | |||
/** | |||
* | |||
* Ce fichier est la uniquement pour compatibilite avec SPIP < 2.1 | |||
* Il est inutile ensuite | |||
* | |||
*/ | |||
if (!defined("_ECRIRE_INC_VERSION")) return; | |||
// construit un bouton (ancre) de raccourci avec icone et aide | |||
// http://doc.spip.org/@bouton_barre_racc | |||
function bouton_barre_racc($action, $img, $help, $champhelp) { | |||
return; | |||
} | |||
// construit un tableau de raccourcis pour un noeud de DOM | |||
// http://doc.spip.org/@afficher_barre | |||
function afficher_barre($champ, $forum=false, $lang='') { | |||
return; | |||
} | |||
// expliciter les 3 arguments pour avoir xhtml strict | |||
// http://doc.spip.org/@afficher_textarea_barre | |||
function afficher_textarea_barre($texte, $forum=false, $form='') | |||
{ | |||
global $spip_display, $spip_ecran; | |||
$rows = ($spip_ecran == "large") ? 28 : 15; | |||
$class = 'formo' . ($forum ? ' textarea_forum':''); | |||
return | |||
"<textarea name='texte' id='texte' " | |||
. " rows='$rows' class='$class' cols='40'>" | |||
. entites_html($texte) | |||
. "</textarea>\n"; | |||
} | |||
?> |
@ -0,0 +1,546 @@ | |||
<?php | |||
/* | |||
* Plugin Porte Plume pour SPIP 2 | |||
* Licence GPL | |||
* Auteur Matthieu Marcillaud | |||
*/ | |||
include_spip('public/admin'); // pour stripos() | |||
/* pour compat 2.0 (inutile a partir de 2.1) */ | |||
if (version_compare($GLOBALS['spip_version_branche'],'2.1.0 dev','<')) { | |||
include_spip('inc/layer'); // pour effacer la globale browser_caret | |||
$GLOBALS['browser_caret']=""; | |||
} | |||
/** | |||
* La class Barre_outils est un objet contenant les differents | |||
* parametres definissant une barre markitup | |||
* | |||
*/ | |||
class Barre_outils{ | |||
var $id = ""; | |||
var $nameSpace = ""; | |||
var $lang = ""; | |||
var $previewAutoRefresh = false; | |||
var $previewParserPath = ""; | |||
var $onEnter = array(); | |||
var $onShiftEnter = array(); | |||
var $onCtrlEnter = array(); | |||
var $onTab = array(); | |||
var $beforeInsert = ""; | |||
var $afterInsert = ""; | |||
var $markupSet = array(); | |||
// liste de fonctions supplementaires a mettre apres le json | |||
var $functions = ""; | |||
// private | |||
var $_liste_params_autorises = array( | |||
'keepDefault', | |||
'replaceWith', | |||
'openWith', | |||
'closeWith', | |||
'placeHolder', // remplace par ce texte lorsqu'il n'y a pas de selection | |||
'beforeInsert', // avant l'insertion | |||
'afterInsert', // apres l'insertion | |||
'beforeMultiInsert', | |||
'afterMultiInsert', | |||
'dropMenu', // appelle un sous menu | |||
'name', // nom affiche au survol | |||
'key', // raccourcis clavier | |||
'className', // classe css utilisee | |||
'lang', // langues dont le bouton doit apparaitre - array | |||
'lang_not', // langues dont le bouton ne doit pas apparaitre - array | |||
'selectionType', // '','word','line' : type de selection (normale, aux mots les plus proches, a la ligne la plus proche) | |||
'forceMultiline', // pour faire comme si on faisait systematiquement un control+shift (multi ligne) | |||
'separator', | |||
'call', | |||
'keepDefault', | |||
// icon est ajoute pour eventuellement creer un jour | |||
// la css automatiquement... | |||
// mais ca pose des problemes la tout de suite | |||
// car il faudrait generer une css differente des qu'un bouton change | |||
// ce qui est assez idiot | |||
// ou alors il faudrait que jquery mette l'icone en fond des boutons automatiquement | |||
'icon', | |||
// cacher ou afficher facilement des boutons | |||
'display', | |||
// donner un identifiant unique au bouton (pour le php) | |||
'id', | |||
); | |||
/** | |||
* Initialise les parametres | |||
* @param array $params : param->valeur | |||
*/ | |||
function Barre_outils($params=array()){ | |||
foreach ($params as $p=>$v) { | |||
if (isset($this->$p)) { | |||
// si tableau, on verifie les entrees | |||
if (is_array($v)) { | |||
$v = $this->verif_params($p,$v); | |||
} | |||
$this->$p = $v; | |||
} | |||
} | |||
} | |||
/** | |||
* Verifie que les parametres transmis existent | |||
* et retourne un tableau des parametres valides | |||
* | |||
* @param string $nom : cle du parametre (eventuel) | |||
* @param array $params : parametres du parametre (param->valeur) | |||
*/ | |||
function verif_params($nom, $params=array()) { | |||
// si markupset, on boucle sur les items | |||
if (stripos($nom, 'markupSet')!==false) { | |||
foreach ($params as $i=>$v) { | |||
$params[$i] = $this->verif_params($i, $v); | |||
} | |||
} | |||
// sinon on teste la validite | |||
else { | |||
foreach ($params as $p=>$v) { | |||
if (!in_array($p, $this->_liste_params_autorises)) { | |||
unset($params[$p]); | |||
} | |||
} | |||
} | |||
return $params; | |||
} | |||
/** | |||
* Permet d'affecter des parametres a un element de la barre | |||
* La fonction retourne les parametres, de sorte qu'on peut s'en servir pour simplement recuperer ceux-ci. | |||
* | |||
* Il est possible d'affecter des parametres avant/apres l'element trouve | |||
* en definisant une valeur differente pour le $lieu : 'dedans','avant','apres' | |||
* par defaut 'dedans' (modifie l'element trouve). | |||
* | |||
* Lorsqu'on demande d'inserer avant ou apres, la fonction retourne les parametres inseres | |||
* | |||
* @param string $identifiant : identifiant du bouton a afficher | |||
* @param array $params : parametres a affecter a la trouvaille | |||
* @param string $lieu : lieu d'affectation des parametres (dedans, avant, apres) | |||
* @param false/array $tableau : tableau ou chercher les elements (sert pour la recursion) | |||
*/ | |||
function affecter(&$tableau, $identifiant, $params=array(), $lieu='dedans'){ | |||
static $cle_de_recherche = 'id'; // ou className ? | |||
if ($tableau === null) | |||
$tableau = &$this->markupSet; | |||
if (!in_array($lieu, array('dedans','avant','apres'))) | |||
$lieu = 'dedans'; | |||
// present en premiere ligne ? | |||
$trouve = false; | |||
foreach ($tableau as $i=>$v){ | |||
if (isset($v[$cle_de_recherche]) and ($v[$cle_de_recherche] == $identifiant)) { | |||
$trouve = $i; | |||
break; | |||
} | |||
} | |||
// si trouve, affectations | |||
if (($trouve !== false)) { | |||
if ($params) { | |||
$params = $this->verif_params($identifiant, $params); | |||
// dedans on merge | |||
if ($lieu == 'dedans') { | |||
return $tableau[$trouve] = array_merge($tableau[$trouve], $params); | |||
} | |||
// avant ou apres, on insere | |||
elseif ($lieu == 'avant') { | |||
array_splice($tableau, $trouve, 0, array($params)); | |||
return $params; | |||
} | |||
elseif ($lieu == 'apres') { | |||
array_splice($tableau, $trouve+1, 0, array($params)); | |||
return $params; | |||
} | |||
} | |||
return $tableau[$trouve]; | |||
} | |||
// recursivons sinon ! | |||
foreach ($tableau as $i=>$v){ | |||
if (is_array($v)) { | |||
foreach ($v as $m=>$n) { | |||
if (is_array($n) AND ($r = $this->affecter($tableau[$i][$m], $identifiant, $params, $lieu))) | |||
return $r; | |||
} | |||
} | |||
} | |||
return false; | |||
} | |||
/** | |||
* Permet d'affecter des parametres toutes les elements de la barre | |||
* | |||
* @param array $params : parametres a affecter a la trouvaille | |||
* @param array $ids : tableau identifiants particuliers a qui on affecte les parametres | |||
* si vide, tous les identifiants seront modifies | |||
* @param false/array $tableau : tableau ou chercher les elements (sert pour la recursion) | |||
*/ | |||
function affecter_a_tous(&$tableau, $params=array(), $ids=array()){ | |||
if (!$params) | |||
return false; | |||
if ($tableau === null) | |||
$tableau = &$this->markupSet; | |||
$params = $this->verif_params('divers', $params); | |||
// merge de premiere ligne | |||
foreach ($tableau as $i=>$v){ | |||
if (!$ids OR in_array($v['id'], $ids)) { | |||
$tableau[$i] = array_merge($tableau[$i], $params); | |||
} | |||
// recursion si sous-menu | |||
if (isset($tableau[$i]['dropMenu'])) { | |||
$this->affecter_a_tous($tableau[$i]['dropMenu'], $params, $ids); | |||
} | |||
} | |||
return true; | |||
} | |||
/** | |||
* Affecte les valeurs des parametres indiques au bouton demande | |||
* et retourne l'ensemble des parametres du bouton (sinon false) | |||
* | |||
* @param string/array $identifiant : id du ou des boutons a afficher | |||
* @param array $params : param->valeur | |||
* @return mixed | |||
*/ | |||
function set($identifiant, $params=array()) { | |||
// prudence tout de meme a pas tout modifier involontairement (si array) | |||
if (!$identifiant) return false; | |||
if (is_string($identifiant)) { | |||
return $this->affecter($this->markupSet, $identifiant, $params); | |||
} | |||
elseif (is_array($identifiant)) { | |||
return $this->affecter_a_tous($this->markupSet, $params, $identifiant); | |||
} | |||
return false; | |||
} | |||
/** | |||
* Retourne les parametres du bouton demande | |||
* | |||
* @param string $identifiant : nom (de la classe du) bouton | |||
* @return mixed | |||
*/ | |||
function get($identifiant) { | |||
if ($a = $this->affecter($this->markupSet, $identifiant)) { | |||
return $a; | |||
} | |||
return false; | |||
} | |||
/** | |||
* Affiche le bouton demande | |||
* | |||
* @param string $identifiant : nom (de la classe du) bouton a afficher | |||
* @return true/false | |||
*/ | |||
function afficher($identifiant){ | |||
return $this->set($identifiant,array('display'=>true)); | |||
} | |||
/** | |||
* Cache le bouton demande | |||
* | |||
* @param string $identifiant : nom (de la classe du) bouton a afficher | |||
* @return true/false | |||
*/ | |||
function cacher($identifiant){ | |||
return $this->set($identifiant,array('display'=>false)); | |||
} | |||
/** | |||
* Affiche tous les boutons | |||
* | |||
* @param string $identifiant : nom (de la classe du) bouton a afficher | |||
* @return true/false | |||
*/ | |||
function afficherTout(){ | |||
return $this->affecter_a_tous($this->markupSet, array('display'=>true)); | |||
} | |||
/** | |||
* Cache tous les boutons | |||
* | |||
* @param string $identifiant : nom (de la classe du) bouton a afficher | |||
* @return true/false | |||
*/ | |||
function cacherTout(){ | |||
return $this->affecter_a_tous($this->markupSet, array('display'=>false)); | |||
} | |||
/** | |||
* ajouter un bouton ou quelque chose, avant un autre deja present | |||
* | |||
* @param string $identifiant : identifiant du bouton ou l'on doit se situer | |||
* @param array $params : parametres de l'ajout | |||
*/ | |||
function ajouterAvant($identifiant, $params){ | |||
return $this->affecter($this->markupSet, $identifiant, $params, 'avant'); | |||
} | |||
/** | |||
* ajouter un bouton ou quelque chose, apres un autre deja present | |||
* | |||
* @param string $identifiant : identifiant du bouton ou l'on doit se situer | |||
* @param array $params : parametres de l'ajout | |||
*/ | |||
function ajouterApres($identifiant, $params){ | |||
return $this->affecter($this->markupSet, $identifiant, $params, 'apres'); | |||
} | |||
/** | |||
* ajouter une fonction js pour etre utilises dans les boutons | |||
* | |||
* @param string $fonction : code de la fonction js | |||
* @return null | |||
*/ | |||
function ajouterFonction($fonction){ | |||
if (false === strpos($this->functions, $fonction)){ | |||
$this->functions .= "\n" . $fonction . "\n"; | |||
} | |||
} | |||
/** | |||
* Supprimer les elements non affiches (display:false) | |||
* | |||
* @param false/array $tableau : tableau a analyser (sert pour la recursion) | |||
*/ | |||
function enlever_elements_non_affiches(&$tableau){ | |||
if ($tableau === null) | |||
$tableau = &$this->markupSet; | |||
foreach ($tableau as $p=>$v){ | |||
if (isset($v['display']) AND !$v['display']) { | |||
unset($tableau[$p]); | |||
$tableau = array_values($tableau); // remettre les cles automatiques sinon json les affiche et รงa plante. | |||
} | |||
// sinon, on lance une recursion sur les sous-menus | |||
else { | |||
if (isset($v['dropMenu']) and is_array($v['dropMenu'])) { | |||
$this->enlever_elements_non_affiches($tableau[$p]['dropMenu']); | |||
// si le sous-menu est vide, on enleve l'icone | |||
if (!$tableau[$p]['dropMenu']) { | |||
unset($tableau[$p]); | |||
$tableau = array_values($tableau); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Supprime les elements vides (uniquement a la racine de l'objet) | |||
* et uniquement si chaine ou tableau. | |||
* | |||
* Supprime les parametres prives | |||
* Supprime les parametres inutiles a markitup/json dans les parametres markupSet | |||
* (id, display, icone) | |||
*/ | |||
function enlever_parametres_inutiles() { | |||
foreach($this as $p=>$v){ | |||
if (!$v) { | |||
if (is_array($v) or is_string($v)) { | |||
unset($this->$p); | |||
} | |||
} elseif ($p == 'functions') { | |||
unset($this->$p); | |||
} | |||
} | |||
foreach($this->markupSet as $p=>$v) { | |||
foreach ($v as $n=>$m) { | |||
if (in_array($n, array('id', 'display', 'icon'))) { | |||
unset($this->markupSet[$p][$n]); | |||
} | |||
} | |||
} | |||
unset ($this->_liste_params_autorises); | |||
} | |||
/** | |||
* Cree la sortie json pour le javascript des parametres de la barre | |||
* et la retourne | |||
* | |||
* @return string : declaration json de la barre | |||
*/ | |||
function creer_json(){ | |||
$barre = $this; | |||
$type = $barre->nameSpace; | |||
$fonctions = $barre->functions; | |||
$barre->enlever_elements_non_affiches($this->markupSet); | |||
$barre->enlever_parametres_inutiles(); | |||
$json = Barre_outils::json_export($barre); | |||
// on lance la transformation des &chose; en veritables caracteres | |||
// sinon markitup restitue « au lieu de ยซ directement | |||
// lorsqu'on clique sur l'icone | |||
include_spip('inc/charsets'); | |||
$json = unicode2charset(html2unicode($json)); | |||
return "\n\nbarre_outils_$type = ".$json . "\n\n $fonctions"; | |||
} | |||
/** | |||
* Transform a variable into its javascript equivalent (recursive) | |||
* (depuis ecrire/inc/json, mais modifie pour que les fonctions | |||
* js ne soient pas mises dans un string | |||
* | |||
* @access private | |||
* @param mixed the variable | |||
* @return string js script | boolean false if error | |||
*/ | |||
function json_export($var) { | |||
$asso = false; | |||
switch (true) { | |||
case is_null($var) : | |||
return 'null'; | |||
case is_string($var) : | |||
if (strtolower(substr(ltrim($var),0,8))=='function') | |||
return $var; | |||
return '"' . addcslashes($var, "\"\\\n\r") . '"'; | |||
case is_bool($var) : | |||
return $var ? 'true' : 'false'; | |||
case is_scalar($var) : | |||
return $var; | |||
case is_object( $var) : | |||
$var = get_object_vars($var); | |||
$asso = true; | |||
case is_array($var) : | |||
$keys = array_keys($var); | |||
$ikey = count($keys); | |||
while (!$asso && $ikey--) { | |||
$asso = $ikey !== $keys[$ikey]; | |||
} | |||
$sep = ''; | |||
if ($asso) { | |||
$ret = '{'; | |||
foreach ($var as $key => $elt) { | |||
$ret .= $sep . '"' . $key . '":' . Barre_outils::json_export($elt); | |||
$sep = ','; | |||
} | |||
return $ret ."}\n"; | |||
} else { | |||
$ret = '['; | |||
foreach ($var as $elt) { | |||
$ret .= $sep . Barre_outils::json_export($elt); | |||
$sep = ','; | |||
} | |||
return $ret ."]\n"; | |||
} | |||
} | |||
return false; | |||
} | |||
} | |||
/** | |||
* Cette fonction cree la css pour les images | |||
* des icones des barres d'outils | |||
* en s'appuyant sur la description des jeux de barres disponibles. | |||
* | |||
* elle cherche une fonction barre_outils_($barre)_icones pour chaque | |||
* barre et l'appelle si existe. | |||
* | |||
* @return string : declaration css des icones | |||
*/ | |||
function barre_outils_css_icones(){ | |||
// recuperer la liste, extraire les icones | |||
$css = ""; | |||
// liste des barres | |||
if (!$barres = barre_outils_liste()) | |||
return null; | |||
// liste des classes css et leur correspondance avec une icone | |||
$classe2icone = array(); | |||
foreach ($barres as $barre) { | |||
include_spip('barre_outils/' . $barre); | |||
if ($f = charger_fonction($barre . '_icones', 'barre_outils', true)) { | |||
if (is_array($icones = $f())) { | |||
$classe2icone = array_merge($classe2icone, $icones); | |||
} | |||
} | |||
} | |||
// passer le tout dans un pipeline pour ceux qui ajoute de simples icones a des barres existantes | |||
$classe2icone = pipeline('porte_plume_lien_classe_vers_icone',$classe2icone); | |||
// passage en css | |||
foreach ($classe2icone as $n=>$i) { | |||
$css .= "\n.markItUp .$n a {\n\tbackground-image:url(".url_absolue(find_in_path("icones_barre/$i")).");\n}"; | |||
} | |||
return $css; | |||
} | |||
/** | |||
* Retourne une instance de Barre_outils | |||
* cree a partir du type de barre demande | |||
* | |||
* @param string $set : type de barre | |||
* @return object/false : objet de type barre_outil | |||
*/ | |||
function barre_outils_initialiser($set){ | |||
if ($f = charger_fonction($set, 'barre_outils')) { | |||
// retourne une instance de l'objet Barre_outils | |||
return $f(); | |||
} | |||
return false; | |||
} | |||
/** | |||
* Retourne la liste des barres d'outils connues | |||
* | |||
* @return array/false : tableau des noms de barres trouvees | |||
*/ | |||
function barre_outils_liste(){ | |||
static $sets = -1; | |||
if ($sets !== -1) | |||
return $sets; | |||
// on recupere l'ensemble des barres d'outils connues | |||
if (!$sets = find_all_in_path('barre_outils/','.*[.]php') | |||
or !is_array($sets)) { | |||
$sets = false; | |||
return $sets; | |||
} | |||
foreach($sets as $fichier=>$adresse) { | |||
$sets[$fichier] = substr($fichier,0,-4); // juste le nom | |||
} | |||
return $sets; | |||
} | |||
?> |
@ -0,0 +1,553 @@ | |||
// ---------------------------------------------------------------------------- | |||
// markItUp! Universal MarkUp Engine, JQuery plugin | |||
// v 1.1.5 | |||
// Dual licensed under the MIT and GPL licenses. | |||
// ---------------------------------------------------------------------------- | |||
// Copyright (C) 2007-2008 Jay Salvat | |||
// http://markitup.jaysalvat.com/ | |||
// ---------------------------------------------------------------------------- | |||
// Permission is hereby granted, free of charge, to any person obtaining a copy | |||
// of this software and associated documentation files (the "Software"), to deal | |||
// in the Software without restriction, including without limitation the rights | |||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
// copies of the Software, and to permit persons to whom the Software is | |||
// furnished to do so, subject to the following conditions: | |||
// | |||
// The above copyright notice and this permission notice shall be included in | |||
// all copies or substantial portions of the Software. | |||
// | |||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
// THE SOFTWARE. | |||
// ---------------------------------------------------------------------------- | |||
(function($) { | |||
$.fn.markItUp = function(settings, extraSettings) { | |||
var options, ctrlKey, shiftKey, altKey; | |||
ctrlKey = shiftKey = altKey = false; | |||
options = { id: '', | |||
nameSpace: '', | |||
root: '', | |||
previewInWindow: '', // 'width=800, height=600, resizable=yes, scrollbars=yes' | |||
previewAutoRefresh: true, | |||
previewPosition: 'after', | |||
previewTemplatePath: '~/templates/preview.html', | |||
previewParserPath: '', | |||
previewParserVar: 'data', | |||
resizeHandle: true, | |||
beforeInsert: '', | |||
afterInsert: '', | |||
onEnter: {}, | |||
onShiftEnter: {}, | |||
onCtrlEnter: {}, | |||
onTab: {}, | |||
markupSet: [ { /* set */ } ] | |||
}; | |||
$.extend(options, settings, extraSettings); | |||
// compute markItUp! path | |||
if (!options.root) { | |||
$('script').each(function(a, tag) { | |||
miuScript = $(tag).get(0).src.match(/(.*)jquery\.markitup(\.pack)?\.js$/); | |||
if (miuScript !== null) { | |||
options.root = miuScript[1]; | |||
} | |||
}); | |||
} | |||
return this.each(function() { | |||
var $$, textarea, levels, scrollPosition, caretPosition, caretOffset, | |||
clicked, hash, header, footer, previewWindow, template, iFrame, abort; | |||
$$ = $(this); | |||
textarea = this; | |||
levels = []; | |||
abort = false; | |||
scrollPosition = caretPosition = 0; | |||
caretOffset = -1; | |||
options.previewParserPath = localize(options.previewParserPath); | |||
options.previewTemplatePath = localize(options.previewTemplatePath); | |||
// apply the computed path to ~/ | |||
function localize(data, inText) { | |||
if (inText) { | |||
return data.replace(/("|')~\//g, "$1"+options.root); | |||
} | |||
return data.replace(/^~\//, options.root); | |||
} | |||
// init and build editor | |||
function init() { | |||
id = ''; nameSpace = ''; | |||
if (options.id) { | |||
id = 'id="'+options.id+'"'; | |||
} else if ($$.attr("id")) { | |||
id = 'id="markItUp'+($$.attr("id").substr(0, 1).toUpperCase())+($$.attr("id").substr(1))+'"'; | |||
} | |||
if (options.nameSpace) { | |||
nameSpace = 'class="'+options.nameSpace+'"'; | |||
} | |||
$$.wrap('<div '+nameSpace+'></div>'); | |||
$$.wrap('<div '+id+' class="markItUp"></div>'); | |||
$$.wrap('<div class="markItUpContainer"></div>'); | |||
$$.addClass("markItUpEditor"); | |||
// add the header before the textarea | |||
header = $('<div class="markItUpHeader"></div>').insertBefore($$); | |||
$(dropMenus(options.markupSet)).appendTo(header); | |||
// add the footer after the textarea | |||
footer = $('<div class="markItUpFooter"></div>').insertAfter($$); | |||
// add the resize handle after textarea | |||
if (options.resizeHandle === true && $.browser.safari !== true) { | |||
resizeHandle = $('<div class="markItUpResizeHandle"></div>') | |||
.insertAfter($$) | |||
.bind("mousedown", function(e) { | |||
var h = $$.height(), y = e.clientY, mouseMove, mouseUp; | |||
mouseMove = function(e) { | |||
$$.css("height", Math.max(20, e.clientY+h-y)+"px"); | |||
return false; | |||
}; | |||
mouseUp = function(e) { | |||
$("html").unbind("mousemove", mouseMove).unbind("mouseup", mouseUp); | |||
return false; | |||
}; | |||
$("html").bind("mousemove", mouseMove).bind("mouseup", mouseUp); | |||
}); | |||
footer.append(resizeHandle); | |||
} | |||
// listen key events | |||
$$.keydown(keyPressed).keyup(keyPressed); | |||
// bind an event to catch external calls | |||
$$.bind("insertion", function(e, settings) { | |||
if (settings.target !== false) { | |||
get(); | |||
} | |||
if (textarea === $.markItUp.focused) { | |||
markup(settings); | |||
} | |||
}); | |||
// remember the last focus | |||
$$.focus(function() { | |||
$.markItUp.focused = this; | |||
}); | |||
} | |||
// recursively build header with dropMenus from markupset | |||
function dropMenus(markupSet) { | |||
var ul = $('<ul></ul>'), i = 0; | |||
$('li:hover > ul', ul).css('display', 'block'); | |||
$.each(markupSet, function() { | |||
var button = this, t = '', title, li, j; | |||
title = (button.key) ? (button.name||'')+' [Ctrl+'+button.key+']' : (button.name||''); | |||
key = (button.key) ? 'accesskey="'+button.key+'"' : ''; | |||
if (button.separator) { | |||
li = $('<li class="markItUpSeparator">'+(button.separator||'')+'</li>').appendTo(ul); | |||
} else { | |||
i++; | |||
for (j = levels.length -1; j >= 0; j--) { | |||
t += levels[j]+"-"; | |||
} | |||
li = $('<li class="markItUpButton markItUpButton'+t+(i)+' '+(button.className||'')+'"><a href="" '+key+' title="'+title+'">'+(button.name||'')+'</a></li>') | |||
.bind("contextmenu", function() { // prevent contextmenu on mac and allow ctrl+click | |||
return false; | |||
}).click(function() { | |||
return false; | |||
}).mouseup(function() { | |||
if (button.call) { | |||
eval(button.call)(); | |||
} | |||
markup(button); | |||
return false; | |||
}).hover(function() { | |||
$('> ul', this).show(); | |||
$(document).one('click', function() { // close dropmenu if click outside | |||
$('ul ul', header).hide(); | |||
} | |||
); | |||
}, function() { | |||
$('> ul', this).hide(); | |||
} | |||
).appendTo(ul); | |||
if (button.dropMenu) { | |||
levels.push(i); | |||
$(li).addClass('markItUpDropMenu').append(dropMenus(button.dropMenu)); | |||
} | |||
} | |||
}); | |||
levels.pop(); | |||
return ul; | |||
} | |||
// markItUp! markups | |||
function magicMarkups(string) { | |||
if (string) { | |||
string = string.toString(); | |||
string = string.replace(/\(\!\(([\s\S]*?)\)\!\)/g, | |||
function(x, a) { | |||
var b = a.split('|!|'); | |||
if (altKey === true) { | |||
return (b[1] !== undefined) ? b[1] : b[0]; | |||
} else { | |||
return (b[1] === undefined) ? "" : b[0]; | |||
} | |||
} | |||
); | |||
// [![prompt]!], [![prompt:!:value]!] | |||
string = string.replace(/\[\!\[([\s\S]*?)\]\!\]/g, | |||
function(x, a) { | |||
var b = a.split(':!:'); | |||
if (abort === true) { | |||
return false; | |||
} | |||
value = prompt(b[0], (b[1]) ? b[1] : ''); | |||
if (value === null) { | |||
abort = true; | |||
} | |||
return value; | |||
} | |||
); | |||
return string; | |||
} | |||
return ""; | |||
} | |||
// prepare action | |||
function prepare(action) { | |||
if ($.isFunction(action)) { | |||
action = action(hash); | |||
} | |||
return magicMarkups(action); | |||
} | |||
// build block to insert | |||
function build(string) { | |||
openWith = prepare(clicked.openWith); | |||
placeHolder = prepare(clicked.placeHolder); | |||
replaceWith = prepare(clicked.replaceWith); | |||
closeWith = prepare(clicked.closeWith); | |||
if (replaceWith !== "") { | |||
block = openWith + replaceWith + closeWith; | |||
} else if (selection === '' && placeHolder !== '') { | |||
block = openWith + placeHolder + closeWith; | |||
} else { | |||
block = openWith + (string||selection) + closeWith; | |||
} | |||
return { block:block, | |||
openWith:openWith, | |||
replaceWith:replaceWith, | |||
placeHolder:placeHolder, | |||
closeWith:closeWith | |||
}; | |||
} | |||
// define markup to insert | |||
function markup(button) { | |||
var len, j, n, i; | |||
hash = clicked = button; | |||
get(); | |||
$.extend(hash, { line:"", | |||
root:options.root, | |||
textarea:textarea, | |||
selection:(selection||''), | |||
caretPosition:caretPosition, | |||
ctrlKey:ctrlKey, | |||
shiftKey:shiftKey, | |||
altKey:altKey | |||
} | |||
); | |||
// callbacks before insertion | |||
prepare(options.beforeInsert); | |||
prepare(clicked.beforeInsert); | |||
if (ctrlKey === true && shiftKey === true) { | |||
prepare(clicked.beforeMultiInsert); | |||
} | |||
$.extend(hash, { line:1 }); | |||
if (ctrlKey === true && shiftKey === true) { | |||
lines = selection.split(/\r?\n/); | |||
for (j = 0, n = lines.length, i = 0; i < n; i++) { | |||
if ($.trim(lines[i]) !== '') { | |||
$.extend(hash, { line:++j, selection:lines[i] } ); | |||
lines[i] = build(lines[i]).block; | |||
} else { | |||
lines[i] = ""; | |||
} | |||
} | |||
string = { block:lines.join('\n')}; | |||
start = caretPosition; | |||
len = string.block.length + (($.browser.opera) ? n : 0); | |||
} else if (ctrlKey === true) { | |||
string = build(selection); | |||
start = caretPosition + string.openWith.length; | |||
len = string.block.length - string.openWith.length - string.closeWith.length; | |||
len -= fixIeBug(string.block); | |||
} else if (shiftKey === true) { | |||
string = build(selection); | |||
start = caretPosition; | |||
len = string.block.length; | |||
len -= fixIeBug(string.block); | |||
} else { | |||
string = build(selection); | |||
start = caretPosition + string.block.length ; | |||
len = 0; | |||
start -= fixIeBug(string.block); | |||
} | |||
if ((selection === '' && string.replaceWith === '')) { | |||
caretOffset += fixOperaBug(string.block); | |||
start = caretPosition + string.openWith.length; | |||
len = string.block.length - string.openWith.length - string.closeWith.length; | |||
caretOffset = $$.val().substring(caretPosition, $$.val().length).length; | |||
caretOffset -= fixOperaBug($$.val().substring(0, caretPosition)); | |||
} | |||
$.extend(hash, { caretPosition:caretPosition, scrollPosition:scrollPosition } ); | |||
if (string.block !== selection && abort === false) { | |||
insert(string.block); | |||
set(start, len); | |||
} else { | |||
caretOffset = -1; | |||
} | |||
get(); | |||
$.extend(hash, { line:'', selection:selection }); | |||
// callbacks after insertion | |||
if (ctrlKey === true && shiftKey === true) { | |||
prepare(clicked.afterMultiInsert); | |||
} | |||
prepare(clicked.afterInsert); | |||
prepare(options.afterInsert); | |||
// refresh preview if opened | |||
if (previewWindow && options.previewAutoRefresh) { | |||
refreshPreview(); | |||
} | |||
// reinit keyevent | |||
shiftKey = altKey = ctrlKey = abort = false; | |||
} | |||
// Substract linefeed in Opera | |||
function fixOperaBug(string) { | |||
if ($.browser.opera) { | |||
return string.length - string.replace(/\n*/g, '').length; | |||
} | |||
return 0; | |||
} | |||
// Substract linefeed in IE | |||
function fixIeBug(string) { | |||
if ($.browser.msie) { | |||
return string.length - string.replace(/\r*/g, '').length; | |||
} | |||
return 0; | |||
} | |||
// add markup | |||
function insert(block) { | |||
if (document.selection) { | |||
var newSelection = document.selection.createRange(); | |||
newSelection.text = block; | |||
} else { | |||
$$.val($$.val().substring(0, caretPosition) + block + $$.val().substring(caretPosition + selection.length, $$.val().length)); | |||
} | |||
} | |||
// set a selection | |||
function set(start, len) { | |||
if (textarea.createTextRange){ | |||
// quick fix to make it work on Opera 9.5 | |||
if ($.browser.opera && $.browser.version >= 9.5 && len == 0) { | |||
return false; | |||
} | |||
range = textarea.createTextRange(); | |||