Browse Source

_plugins_/_core_ vers _core_/plugins

svn/root/tags/plugins/porte_plume/1.2.6 v1.2.6
ben.spip@gmail.com 13 years ago
commit
3fdad57c33
  1. 38
      .gitattributes
  2. 408
      barre_outils/edition.php
  3. 33
      barre_outils/forum.php
  4. 7
      barre_outils_icones.css.html
  5. 141
      css/barre_outils.css
  6. BIN
      css/images/handle.png
  7. BIN
      css/images/menu.png
  8. BIN
      css/images/submenu.png
  9. BIN
      icones_barre/clean.png
  10. BIN
      icones_barre/eye.png
  11. BIN
      icones_barre/keyboard.png
  12. BIN
      icones_barre/text_bold.png
  13. BIN
      icones_barre/text_indent.png
  14. BIN
      icones_barre/text_indent_remove.png
  15. BIN
      icones_barre/text_italic.png
  16. BIN
      icones_barre/text_list_bullets.png
  17. BIN
      icones_barre/text_list_numbers.png
  18. BIN
      icones_barre/text_strikethrough.png
  19. 42
      inc/barre.php
  20. 546
      inc/barre_outils.php
  21. 553
      javascript/jquery.markitup.js
  22. 776
      javascript/jquery.markitup_pour_spip.js
  23. 77
      javascript/jquery.previsu_spip.js
  24. 89
      lang/barre_outils_ar.php
  25. 89
      lang/barre_outils_en.php
  26. 90
      lang/barre_outils_fr.php
  27. 55
      markitup/readme.txt
  28. 5
      markitup/templates/preview.css
  29. 11
      markitup/templates/preview.html
  30. 29
      plugin.xml
  31. 4
      porte_plume.js.html
  32. 61
      porte_plume.js_fonctions.php
  33. 20
      porte_plume_options.php
  34. 55
      porte_plume_pipelines.php
  35. 6
      preview.html
  36. 12
      tests/all_tests.php
  37. 359
      tests/barre_outil_markitup.php
  38. 36
      tests/lanceur_spip.php

38
.gitattributes

@ -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

408
barre_outils/edition.php

@ -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" => "&laquo;",
"closeWith" => "&raquo;",
"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" => "&ldquo;",
"closeWith" => "&rdquo;",
"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" => "&bdquo;",
"closeWith" => "&ldquo;",
"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" => "&sbquo;",
"closeWith" => "&lsquo;",
"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" => "&ldquo;",
"closeWith" => "&rdquo;",
"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" => "&lsquo;",
"closeWith" => "&rsquo;",
"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" => "&Agrave;",
"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" => "&Eacute;",
"display" => true,
"lang" => array('fr','eo','cpf'),
),
// oe
array(
"id" => 'oe',
"name" => _T('barre_outils:barre_eo'),
"className" => "outil_oe",
"replaceWith" => "&oelig;",
"display" => true,
"lang" => array('fr'),
),
// OE
array(
"id" => 'OE',
"name" => _T('barre_outils:barre_eo_maj'),
"className" => "outil_oe_maj",
"replaceWith" => "&OElig;",
"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',
);
}
?>

33
barre_outils/forum.php

@ -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;
}
?>

7
barre_outils_icones.css.html

@ -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;}

141
css/barre_outils.css

@ -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;}

BIN
css/images/handle.png

After

Width: 21  |  Height: 6  |  Size: 258 B

BIN
css/images/menu.png

After

Width: 11  |  Height: 11  |  Size: 26 KiB

BIN
css/images/submenu.png

After

Width: 11  |  Height: 11  |  Size: 240 B

BIN
icones_barre/clean.png

After

Width: 16  |  Height: 16  |  Size: 667 B

BIN
icones_barre/eye.png

After

Width: 16  |  Height: 16  |  Size: 750 B

BIN
icones_barre/keyboard.png

After

Width: 16  |  Height: 16  |  Size: 570 B

BIN
icones_barre/text_bold.png

After

Width: 16  |  Height: 16  |  Size: 304 B

BIN
icones_barre/text_indent.png

After

Width: 16  |  Height: 16  |  Size: 353 B

BIN
icones_barre/text_indent_remove.png

After

Width: 16  |  Height: 16  |  Size: 351 B

BIN
icones_barre/text_italic.png

After

Width: 16  |  Height: 16  |  Size: 223 B

BIN
icones_barre/text_list_bullets.png

After

Width: 16  |  Height: 16  |  Size: 344 B

BIN
icones_barre/text_list_numbers.png

After

Width: 16  |  Height: 16  |  Size: 357 B

BIN
icones_barre/text_strikethrough.png

After

Width: 16  |  Height: 16  |  Size: 269 B

42
inc/barre.php

@ -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";
}
?>

546
inc/barre_outils.php

@ -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 &laquo; 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;
}
?>

553
javascript/jquery.markitup.js

@ -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