OpenCCM-Plugin v0.3 für Xinha hinzugefügt

git-svn-id: https://svn.libreccm.org/ccm/trunk@1715 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2012-06-22 13:42:42 +00:00
parent 7d27c686bf
commit 250994a172
8 changed files with 797 additions and 1 deletions

View File

@ -13,7 +13,7 @@ xinha_init=xinha_init?xinha_init:function(){
xinha_editors=xinha_editors?xinha_editors:["myTextArea","anotherOne"];
xinha_plugins=xinha_plugins?xinha_plugins:["CharacterMap","CharCounter",
"ContextMenu","DefinitionList","FindReplace","ListType","QuickTag",
"SmartReplace","Stylist","TableOperations","UnFormat","Equation"];
"SmartReplace","Stylist","TableOperations","UnFormat","Equation","OpenCCM"];
if(!Xinha.loadPlugins(xinha_plugins,xinha_init)){
return;
}

View File

@ -0,0 +1,114 @@
/** xinha editor plugin for OpenCCM **/
OpenCCM._pluginInfo = {
name : "OpenCCM",
version : "0.3",
developer : "Sören Bernstein",
developer_url : "http://",
sponsor : "",
sponsor_url : "",
license : "htmlArea"
}
function OpenCCM(editor)
{
this.editor = editor;
this.dialogs = new Array();
var cfg = editor.config;
var self = this;
var hasLinkButton = false;
var hasImageButton = false;
cfg.registerButton(
{
id : "createlink",
tooltip : this._lc("OpenCCMInsertLink"),
image : ["ed_buttons_main.png", 6, 1],
textMode : false,
action : function(e, objname, obj) { self.showLinkDialog(self._getSelectedAnchor()); }
}
);
cfg.registerButton(
{
id : "insertimage",
tooltip : this._lc("OpenCCMInsertImage"),
image : ["ed_buttons_main.png", 6, 3],
textMode : false,
action : function(e, objname, obj) { self.showImageDialog(); }
}
);
if(this.findButton("createlink"))
{
hasLinkButton = true;
cfg.addToolbarElement("createlink", "createlink", 0);
} else {
cfg.addToolbarElement("createlink", "undo", -1);
}
if(this.findButton("insertimage"))
{
hasImageButton = true;
cfg.addToolbarElement("insertimage", "insertimage", 0);
}
else
{
cfg.addToolbarElement("insertimage", "createlink", 1);
}
if(!hasLinkButton && !hasImageButton)
{
cfg.addToolbarElement(["separator"], "insertimage", 1);
}
// Register double click action
cfg.dblclickList["a"][0] = function(e, target) { self.showLinkDialog(self._getSelectedAnchor()); };
}
OpenCCM.prototype.findButton = function(string) {
var toolbar = this.editor.config.toolbar;
for(i = 0; i < toolbar.length; i++)
{
for(j = 0; j < toolbar[i].length; j++)
{
if(toolbar[i][j] == string)
{
return true;
}
}
}
return false;
}
OpenCCM.prototype._lc = function(string) {
return Xinha._lc(string, 'OpenCCM');
}
OpenCCM.prototype.onGenerateOnce = function ()
{
this.loadAssets();
}
OpenCCM.prototype.loadAssets = function() {
var self = OpenCCM;
if (self.loading)
{
return;
}
self.loading = true;
// Link
Xinha._getback(Xinha.getPluginDir("OpenCCM") + '/links/links.js', function(getback) { eval(getback); self.linksMethodsReady = true; });
Xinha._getback(Xinha.getPluginDir("OpenCCM") + '/links/links.html', function(getback) { OpenCCM.linksHtml = getback; self.linksDialogReady = true; } );
// Image
Xinha._getback(Xinha.getPluginDir("OpenCCM") + '/images/images.js', function(getback) { eval(getback); self.imagesMethodsReady = true; } );
Xinha._getback(Xinha.getPluginDir("OpenCCM") + '/images/images.html', function(getback) { OpenCCM.imagesHtml = getback; self.imagesDialogReady = true; } );
}

View File

@ -0,0 +1,83 @@
<h1 id="[h1]"><l10n>Insert Image</l10n></h1>
<!--- new stuff --->
<form action="" method="get" style="padding-top:10px" id="[inputs]">
<table border="0" width="95%" style="padding: 0px; margin: 0px">
<tbody>
<tr>
<td style="width: 7em; text-align: right"><l10n>Image URL:</l10n></td>
<td><input type="text" name="[f_url]" id="[f_url]" style="width:75%"
title="_(Enter the image URL here)" />
<button id="[preview]" title="_(Preview the image in a new window)"><l10n>Preview</l10n></button>
</td>
</tr>
<tr>
<td style="width: 7em; text-align: right"><l10n>Alternate text:</l10n></td>
<td><input type="text" name="[f_alt]" id="[f_alt]" style="width:100%"
title="_(For browsers that don't support images)" /></td>
</tr>
</tbody>
</table>
<br />
<fieldset style="float: left; margin-left: 5px;">
<legend><l10n>Layout</l10n></legend>
<div class="space"></div>
<div class="fl"><l10n>Alignment:</l10n></div>
<select size="1" name="[f_align]" id="[f_align]"
title="_(Positioning of this image)">
<option value="" ><l10n>Not set</l10n></option>
<option value="left" ><l10n>Left</l10n></option>
<option value="right" ><l10n>Right</l10n></option>
<option value="texttop" ><l10n>Texttop</l10n></option>
<option value="absmiddle" ><l10n>Absmiddle</l10n></option>
<option value="baseline" ><l10n>Baseline</l10n></option>
<option value="absbottom" ><l10n>Absbottom</l10n></option>
<option value="bottom" ><l10n>Bottom</l10n></option>
<option value="middle" ><l10n>Middle</l10n></option>
<option value="top" ><l10n>Top</l10n></option>
</select>
<br />
<div class="fl"><l10n>Border thickness:</l10n></div>
<input type="text" name="[f_border]" id="[f_border]" size="5"
title="_(Leave empty for no border)" />
<div class="space"></div>
</fieldset>
<fieldset>
<legend><l10n>Spacing</l10n></legend>
<div class="space"></div>
<div class="fr"><l10n>Horizontal:</l10n></div>
<input type="text" name="[f_horiz]" id="[f_horiz]" size="5"
title="_(Horizontal padding)" />
<br />
<div class="fr"><l10n>Vertical:</l10n></div>
<input type="text" name="[f_vert]" id="[f_vert]" size="5"
title="_(Vertical padding)" />
<div class="space"></div>
</fieldset>
</form>
<div>
<l10n>Image Preview:</l10n><br />
<iframe id="[ipreview]" frameborder="0" style="border : 1px solid gray;"
height="200" width="100%" src="about:blank"></iframe>
</div>
<div class="buttons" id="[buttons]">
<input type="button" id="[ok]" value="_(OK)" />
<input type="button" id="[cancel]" value="_(Cancel)" />
</div>

View File

@ -0,0 +1,196 @@
OpenCCM.prototype.showImageDialog = function(image)
{
if (!this.dialogs["images"]) this.prepareImageDialog();
var editor = this.editor;
if ( typeof image == "undefined" )
{
image = editor.getParentElement();
if ( image && image.tagName.toLowerCase() != 'img' )
{
image = null;
}
}
if ( image )
{
function getSpecifiedAttribute(element,attribute)
{
var a = element.attributes;
for (var i=0;i<a.length;i++)
{
if (a[i].nodeName == attribute && a[i].specified)
{
return a[i].value;
}
}
return '';
}
outparam =
{
f_url : editor.stripBaseURL(image.getAttribute('src',2)), // the second parameter makes IE return the value as it is set, as opposed to an "interpolated" (as MSDN calls it) value
f_alt : image.alt,
f_border : image.border,
f_align : image.align,
f_vert : getSpecifiedAttribute(image,'vspace'),
f_horiz : getSpecifiedAttribute(image,'hspace'),
f_width : image.width,
f_height : image.height
};
}
else{
{
outparam =
{
f_url : '',
f_alt : '',
f_border : '',
f_align : '',
f_vert : '',
f_horiz : '',
f_width : '',
f_height : ''
};
}
}
this.image = image;
// now calling the show method of the Xinha.Dialog object to set the values and show the actual dialog
this.dialogs["images"].show(outparam);
};
OpenCCM.prototype.prepareImageDialog = function()
{
var self = this;
var editor = this.editor;
var dialog = this.dialogs["images"] = new Xinha.Dialog(editor, OpenCCM.imagesHtml, 'Xinha',{width:410})
// Connect the OK and Cancel buttons
dialog.getElementById('ok').onclick = function() {self.imageApply();}
dialog.getElementById('cancel').onclick = function() { self.dialogs["images"].hide()};
/*
dialog.getElementById('preview').onclick = function() {
var f_url = dialog.getElementById("f_url");
var url = f_url.value;
if (!url) {
alert(dialog._lc("You must enter the URL"));
f_url.focus();
return false;
}
dialog.getElementById('ipreview').src = url;
return false;
}
dialog.onresize = function ()
{
var newHeightForPreview =
parseInt(this.height,10)
- this.getElementById('h1').offsetHeight
- this.getElementById('buttons').offsetHeight
- this.getElementById('inputs').offsetHeight
- parseInt(this.rootElem.style.paddingBottom,10); // we have a padding at the bottom, gotta take this into acount
this.getElementById("ipreview").style.height = ((newHeightForPreview > 0) ? newHeightForPreview : 0) + "px"; // no-go beyond 0
this.getElementById("ipreview").style.width = this.width - 2 + 'px'; // and the width
}
*/
this.imageDialogReady = true;
};
// and finally ... take some action
OpenCCM.prototype.imageApply = function()
{
var param = this.dialogs["images"].hide();
if (!param.f_url)
{
return;
}
var editor = this.editor;
var img = this.image;
if ( !img )
{
if ( Xinha.is_ie )
{
var sel = editor.getSelection();
var range = editor.createRange(sel);
editor._doc.execCommand("insertimage", false, param.f_url);
img = range.parentElement();
// wonder if this works...
if ( img.tagName.toLowerCase() != "img" )
{
img = img.previousSibling;
}
}
else
{
img = document.createElement('img');
img.src = param.f_url;
editor.insertNodeAtSelection(img);
if ( !img.tagName )
{
// if the cursor is at the beginning of the document
img = range.startContainer.firstChild;
}
}
}
else
{
img.src = param.f_url;
}
for ( var field in param )
{
var value = param[field];
switch (field)
{
case "f_alt":
if (value)
img.alt = value;
else
img.removeAttribute("alt");
break;
case "f_border":
if (value)
img.border = parseInt(value || "0");
else
img.removeAttribute("border");
break;
case "f_align":
if (value.value)
img.align = value.value;
else
img.removeAttribute("align");
break;
case "f_vert":
if (value != "")
img.vspace = parseInt(value || "0");
else
img.removeAttribute("vspace");
break;
case "f_horiz":
if (value != "")
img.hspace = parseInt(value || "0");
else
img.removeAttribute("hspace");
break;
case "f_width":
if (value)
img.width = parseInt(value || "0");
else
img.removeAttribute("width");
break;
case "f_height":
if (value)
img.height = parseInt(value || "0");
else
img.removeAttribute("height");
break;
}
}
};

View File

@ -0,0 +1,6 @@
// I18N constants
// LANG: "de", ENCODING: UTF-8
{
"OpenCCMInsertLink" : "Link einfügen / bearbeiten",
"OpenCCMInsertImage" : "Bild einfügen / bearbeiten",
}

View File

@ -0,0 +1,6 @@
// I18N constants
// LANG: "de", ENCODING: UTF-8
{
"OpenCCMInsertLink" : "Create / modify link",
"OpenCCMInsertImage" : "Insert / modify image",
}

View File

@ -0,0 +1,154 @@
<style>
.common {
margin: 0.4em;
}
fieldset {
margin: 0.6em 0.3em;
}
label.key {
float: left;
width: 5em;
padding: 0.25em 0.2em;
}
.value {
margin-left: 5.5em;
margin-right: 1em;
}
.withButton {
margin: 0em 0.2em 0em 12em;
}
.withButton input[type="text"] {
float: left;
margin-left: -6em;
}
.withButton input[type="button"] {
position: relative;
width: 5em !important;
}
input {
width: auto !important;
}
input[type="text"] {
width: 100% !important;
}
.itemname {
margin: 0.1em;
border: none;
border-radius: 0.3em;
padding: 0.2em;
font-style: italic;
color: #4a4a4a;
background-color: #dddddd;
}
.buttons {
text-align: center;
}
</style>
<h1 id="[h1]">
<l10n>Insert/Modify Link</l10n>
</h1>
<div style="position:relative">
<div id="[options]">
<div class="common">
<label class="key" for="[title]">
<l10n>Title:</l10n>
</label>
<div class="value">
<input type="text" name="[title]" id="[title]"/>
</div>
</div>
<fieldset id="[fieldset_internal]">
<legend>
<label>
<input type="radio" name="[type]" id="[type_internal]" value="internal" checked="checked"/>
<l10n>Internal Link</l10n>
</label>
</legend>
<label class="key" for="[ci_name]">
<l10n>Item:</l10n>
</label>
<div class="value withButton">
<!-- Ausgeblendet, bis es eine spezielle JSP / Java-Klasse gibt.
<input class="itemname" type="text" name="[ci_name]" id="[ci_name]" disabled="disabled" value="_(No item selected)"/>
-->
<!-- Die folgende Zeile muß entfernt werden, wenn eine bessere JSP / Java-Klasse vorhanden ist -->
<input type="text" disabled="disabled" name="[ci_href]" id="[ci_href]" value=""/>
<input type="button" name="[ci_browse]" id="[ci_browse]" value="_(Browse)"/>
</div>
<!-- Ausblenden, bis es eine spezielle JSP / Java-Klasse gibt, die besser mit externen Parametern arbeitet
<div class="value withButton">
<input type="text" name="[ci_searchfield]" id="[ci_searchfield]" value=""/>
<input type="button" name="[ci_search]" id="[ci_search]" value="_(Search)"/>
</div>
<input type="hidden" name="[ci_href]" id="[ci_href]" value=""/>
-->
</fieldset>
<fieldset id="[fieldset_external]">
<legend>
<label>
<input type="radio" name="[type]" id="[type_external]" value="external"/>
<l10n>External Link</l10n>
</label>
</legend>
<label class="key" for="[href]">
<l10n>URL:</l10n>
</label>
<div class="value">
<input type="text" name="[href]" id="[href]" value=""/>
</div>
</fieldset>
<!-- Evt. für spätere Erweiteung, aber eigentlich sollten Links auf Contact-Items verwendet werden -->
<!--
<fieldset id="[fieldset_mailto]">
<legend>
<label>
<input type="radio" name="[type]" id="[type_mailto]" value="mailto"/>
<l10n>Email Link</l10n>
</label>
</legend>
<label class="key" for="[to]">
<l10n>Email Address:</l10n>
</label>
<div class="value">
<input "type="text" name="[to]" id="[to]" value=""/>
</div>
</fieldset>
-->
<!-- Für spätere Erweiterung. Scanne nach Anchor und trage sie ein -->
<!--
<fieldset id="[fieldset_anchor]">
<legend>
<label>
<input type="radio" name="[type]" id="[type_anchor]" value="anchor"/>
<l10n>Anchor Link</l10n>
</label>
</legend>
<label class="key" "for="[anchor]">
<l10n>Anchor:</l10n>
</label>
<div class="value">
<select name="[anchor]" id="[anchor]">
</select>
</div>
</fieldset>
-->
<div class="buttons">
<input type="button" id="[ok]" value="_(OK)" />
<input type="button" id="[clear]" value="_(Remove Link)" />
<input type="button" id="[cancel]" value="_(Cancel)" />
</div>
</div>
</div>

View File

@ -0,0 +1,237 @@
OpenCCM.prototype.showLinkDialog = function(link)
{
if (!this.dialogs["links"])
{
this.prepareLinkDialog();
}
var editor = this.editor;
this.link = link;
if(!link && this.editor.selectionEmpty(this.editor.getSelection()))
{
alert(this._lc("You need to select some text before creating a link"));
return false;
}
var data =
{
title : '',
type : 'internal',
ci_name : '',
ci_href : '',
href : ''
};
if(link && link.tagName.toLowerCase() == 'a')
{
var href =this.editor.fixRelativeLinks(link.getAttribute('href'));
var internal = href.match(/^(\/.*)$/);
var external = href.match(/^http(.*)$/);
/*
var mailto = href.match(/^mailto:(.*@[^?&]*)(\?(.*))?$/);
var anchor = href.match(/^#(.*)$/);
*/
data.title = link.title;
if(internal)
{
data.type = 'internal';
data.ci_name = link.alt;
data.ci_href = href;
}
if(external)
{
data.type = 'external';
data.href = href;
}
}
// now calling the show method of the Xinha.Dialog object to set the values and show the actual dialog
this.dialogs["links"].show(data);
};
// Prepare the link dialog
OpenCCM.prototype.prepareLinkDialog = function()
{
var self = this;
var editor = this.editor;
var dialog = this.dialogs["links"] = new Xinha.Dialog(editor, OpenCCM.linksHtml, 'Xinha',{width:400})
// Connect the OK and Cancel buttons
dialog.getElementById('ok').onclick = function() { self.linkApply(); };
dialog.getElementById('clear').onclick = function() { self.linkRemove(); };
dialog.getElementById('cancel').onclick = function() { self.dialogs["links"].hide()};
// Connect the Browse and Search button
dialog.getElementById('ci_browse').onclick = function() { self.linkBrowse(window); };
/* Suche deaktivert, bis eine bessere JSP / Java-Klasse vorhanden ist
dialog.getElementById('ci_search').onclick = function() { alert("Das geht auch noch nicht.");};
*/
this.linkDialogReady = true;
};
//
OpenCCM.prototype.linkApply = function()
{
var values = this.dialogs["links"].hide();
var link = this.link;
var editor = this.editor;
var linkAttr =
{
href : '',
alt : '',
title : '',
class : ''
};
// Read needed form values
switch(values.type)
{
case "internal": //alert("Internal");
linkAttr.href = values.ci_href;
/* Deaktiviert bis es eine bessere JSP / Java-Klasse gibt
linkAttr.alt = values.ci_name;
*/
linkAttr.title = values.title;
linkAttr.class = "linkInternal";
break;
case "external": //alert("External");
linkAttr.href = values.href;
linkAttr.title = values.title;
linkAttr.class = "linkExternal";
// Make absolute url
break;
default: //alert("Mist");
return false;
}
// If not all mandatory informations are set
if(linkAttr.href == "" || linkAttr.title == "")
{
// don't do anything at all
return false;
}
// Modify Link
if(link && link.tagName.toLowerCase() == "a")
{
for(var i in linkAttr)
{
link.setAttribute(i, linkAttr[i]);
}
/* from Linker-Plugin
// If we change a mailto link in IE for some hitherto unknown
// reason it sets the innerHTML of the link to be the
// href of the link. Stupid IE.
if(Xinha.is_ie)
{
if(/mailto:([^?<>]*)(\?[^<]*)?$/i.test(link.innerHTML))
{
link.innerHTML = RegExp.$1;
}
}
*/
}
// Add Link
else
{
// Insert a link, we let the editor do this, we figure it knows best
var tmp = Xinha.uniq("http://www.example.com/Link");
editor._doc.execCommand("createlink", false, tmp);
// Fix it up
var anchors = editor._doc.getElementsByTagName('a');
for(var i = 0; i < anchors.length; i++)
{
var anchor = anchors[i];
if(anchor.href == tmp)
{
// Found one.
if (!link) link = anchor;
for(var j in linkAttr)
{
anchor.setAttribute(j, linkAttr[j]);
}
}
}
}
editor.selectNodeContents(link);
editor.updateToolbar();
};
// Remove a link
OpenCCM.prototype.linkRemove = function()
{
var values = this.dialogs["links"].hide();
var link = this.link;
var editor = this.editor;
if(link && link.tagName.toLowerCase() == 'a')
{
if(confirm(this._lc('Are you sure you wish to remove this link?')))
{
var parent = link.parentNode;
while(link.hasChildNodes())
{
parent.insertBefore(link.removeChild(link.childNodes[0]), link);
}
parent.removeChild(link);
editor.updateToolbar();
return true;
}
}
};
OpenCCM.prototype.linkBrowse = function(window)
{
baseURL = window.location.href;//.pathname;
offset = baseURL.lastIndexOf("/");
destURL = baseURL.slice(0, offset+1) + "search.jsp?useURL=true&widget=getElementById('" + this.dialogs["links"].id["ci_href"] + "')";
// var searchDialog = new Xinha.Dialog(this.editor, destURL, '');//,{width:800, height:600}, {'closable':true});
// searchDialog.show();
window.open(destURL, "_blank", "directories=no,toolbar=no,width=600,height=400,status=no,menubar=no");
return false;
}
// Get selected anchor
OpenCCM.prototype._getSelectedAnchor = function()
{
var sel = this.editor.getSelection();
var rng = this.editor.createRange(sel);
var link = this.editor.activeElement(sel);
if(link != null && link.tagName.toLowerCase() == 'a')
{
return link;
}
else
{
link = this.editor._getFirstAncestor(sel, 'a');
if(link != null)
{
return link;
}
}
return null;
};