Project

General

Profile

Feature #22308 » rtehtmlarea_feature_13878.patch

Administrator Admin, 2010-03-22 05:40

View differences:

typo3/sysext/rtehtmlarea/extensions/DefaultLink/class.tx_rtehtmlarea_defaultlink.php (copie de travail)
/***************************************************************
* Copyright notice
*
* (c) 2008-2009 Stanislas Rolland <stanislas.rolland(arobas)fructifor.ca>
* (c) 2008-2010 Stanislas Rolland <typo3(arobas)sjbr.ca>
* All rights reserved
*
* This script is part of the Typo3 project. The Typo3 project is
......
/**
* Default Link extension for htmlArea RTE
*
* @author Stanislas Rolland <stanislas.rolland(arobas)fructifor.ca>
* @author Stanislas Rolland <typo3(arobas)sjbr.ca>
*
* TYPO3 SVN ID: $Id$
*
......
protected $toolbar; // Reference to RTE toolbar array
protected $LOCAL_LANG; // Frontend language array
protected $pluginButtons = 'link';
protected $pluginButtons = 'link, unlink';
protected $convertToolbarForHtmlAreaArray = array (
'link' => 'CreateLink',
'link' => 'CreateLink',
'unlink' => 'UnLink',
);
/**
typo3/sysext/rtehtmlarea/htmlarea/plugins/DefaultLink/default-link.js (copie de travail)
/***************************************************************
* Copyright notice
*
* (c) 2008-2009 Stanislas Rolland <typo3(arobas)sjbr.ca>
* (c) 2008-2010 Stanislas Rolland <typo3(arobas)sjbr.ca>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
......
* TYPO3 SVN ID: $Id$
*/
DefaultLink = HTMLArea.Plugin.extend({
constructor : function(editor, pluginName) {
constructor: function(editor, pluginName) {
this.base(editor, pluginName);
},
/*
* This function gets called by the class constructor
*/
configurePlugin : function(editor) {
configurePlugin: function(editor) {
this.baseURL = this.editorConfiguration.baseURL;
this.pageTSConfiguration = this.editorConfiguration.buttons.link;
this.stripBaseUrl = this.pageTSConfiguration && this.pageTSConfiguration.stripBaseUrl && this.pageTSConfiguration.stripBaseUrl;
this.showTarget = !(this.pageTSConfiguration && this.pageTSConfiguration.targetSelector && this.pageTSConfiguration.targetSelector.disabled);
/*
* Registering plugin "About" information
*/
var pluginInformation = {
version : "1.0",
developer : "Stanislas Rolland",
developerUrl : "http://www.sjbr.ca/",
copyrightOwner : "Stanislas Rolland",
sponsor : "SJBR",
sponsorUrl : "http://www.sjbr.ca/",
license : "GPL"
version : '2.0',
developer : 'Stanislas Rolland',
developerUrl : 'http://www.sjbr.ca/',
copyrightOwner : 'Stanislas Rolland',
sponsor : 'SJBR',
sponsorUrl : 'http://www.sjbr.ca/',
license : 'GPL'
};
this.registerPluginInformation(pluginInformation);
/*
* Registering the button
* Registering the buttons
*/
var buttonId = "CreateLink";
var buttonConfiguration = {
id : buttonId,
tooltip : this.localize("createlink"),
action : "onButtonPress",
hotKey : (this.pageTSConfiguration ? this.pageTSConfiguration.hotKey : null),
context : "a",
selection : true,
dialog : true
};
this.registerButton(buttonConfiguration);
var buttonList = this.buttonList, buttonId;
for (var i = 0; i < buttonList.length; ++i) {
var button = buttonList[i];
buttonId = button[0];
var buttonConfiguration = {
id : buttonId,
tooltip : this.localize(buttonId.toLowerCase()),
action : "onButtonPress",
hotKey : (this.pageTSConfiguration ? this.pageTSConfiguration.hotKey : null),
context : button[1],
selection : button[2],
dialog : button[3]
};
this.registerButton(buttonConfiguration);
}
return true;
},
},
/*
* The list of buttons added by this plugin
*/
buttonList: [
['CreateLink', 'a,img', false, true],
['UnLink', 'a', false, false]
],
/*
* Sets of default configuration values for dialogue form fields
*/
configDefaults: {
combo: {
editable: true,
typeAhead: true,
triggerAction: 'all',
forceSelection: true,
mode: 'local',
valueField: 'value',
displayField: 'text',
helpIcon: true,
tpl: '<tpl for="."><div ext:qtip="{value}" style="text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
}
},
/*
* This function gets called when the button was pressed.
*
* @param object editor: the editor instance
......
*
* @return boolean false if action is completed
*/
onButtonPress : function(editor, id, target) {
onButtonPress: function(editor, id, target) {
// Could be a button or its hotkey
var buttonId = this.translateHotKey(id);
buttonId = buttonId ? buttonId : id;
if (buttonId === "UnLink") {
this.unLink();
return false;
this.editor.focus();
this.link = this.editor.getParentElement();
var el = HTMLArea.getElementObject(this.link, 'a');
if (el && /^a$/i.test(el.nodeName)) {
this.link = el;
}
var paramameters = null;
this.editor.focusEditor();
var link = this.editor.getParentElement();
var el = HTMLArea.getElementObject(link, "a");
if (el != null && /^a$/i.test(el.nodeName)) link = el;
if (!link || !/^a$/i.test(link.nodeName)) {
link = null;
var selection = this.editor._getSelection();
if (this.editor._selectionEmpty(selection)) {
alert(this.localize("Select some text"));
return;
}
paramameters = {
f_href : "",
f_title : "",
f_target : ""
};
} else {
paramameters = {
f_href : (HTMLArea.is_ie && this.stripBaseUrl) ? this.stripBaseURL(link.href) : link.getAttribute("href"),
f_title : link.title,
f_target : link.target
};
if (!this.link || !/^a$/i.test(this.link.nodeName)) {
this.link = null;
}
this.link = link;
this.dialog = this.openDialog("CreateLink", this.makeUrlFromPopupName("link"), "createLink", paramameters, {width:570, height:150});
switch (buttonId) {
case 'UnLink':
this.unLink();
break;
case 'CreateLink':
if (!this.link) {
var selection = this.editor._getSelection();
if (this.editor._selectionEmpty(selection)) {
Ext.MessageBox.alert('', this.localize('Select some text'));
break;
}
this.parameters = {
href: 'http://',
title: '',
target: ''
};
} else {
this.parameters = {
href: (Ext.isIE && this.stripBaseUrl) ? this.stripBaseURL(this.link.href) : this.link.getAttribute('href'),
title: this.link.title,
target: this.link.target
};
}
// Open dialogue window
this.openDialogue(
buttonId,
'Insert/Modify Link',
this.getWindowDimensions(
{
width: 470,
height:150
},
buttonId
)
);
break;
}
return false;
},
/*
* Create the link
* Open the dialogue window
*
* @param object param: the returned values
* @param string buttonId: the button id
* @param string title: the window title
* @param integer dimensions: the opening width of the window
*
* @return boolean false
* @return void
*/
createLink : function(param) {
if (typeof(param) != "undefined" && typeof(param.f_href) != "undefined") {
var a = this.link;
if(!a) {
this.editor._doc.execCommand("CreateLink", false, param.f_href);
a = this.editor.getParentElement();
if (HTMLArea.is_gecko && !/^a$/i.test(a.nodeName)) {
var selection = this.editor._getSelection();
var range = this.editor._createRange(selection);
try {
a = range.startContainer.childNodes[range.startOffset];
} catch(e) {}
openDialogue: function (buttonId, title, dimensions) {
this.dialog = new Ext.Window({
title: this.localize(title),
cls: 'htmlarea-window',
border: false,
width: dimensions.width,
height: 'auto',
// As of ExtJS 3.1, JS error with IE when the window is resizable
resizable: !Ext.isIE,
iconCls: buttonId,
listeners: {
afterrender: {
fn: this.onAfterRender,
scope: this
},
close: {
fn: this.onClose,
scope: this
}
},
items: [{
xtype: 'fieldset',
defaultType: 'textfield',
labelWidth: 100,
defaults: {
helpIcon: true,
width: 250,
labelSeparator: ''
},
items: [{
itemId: 'href',
name: 'href',
fieldLabel: this.localize('URL:'),
value: this.parameters.href,
helpTitle: this.localize('link_href_tooltip')
},{
itemId: 'title',
name: 'title',
fieldLabel: this.localize('Title (tooltip):'),
value: this.parameters.title,
helpTitle: this.localize('link_title_tooltip')
}, Ext.apply({
xtype: 'combo',
fieldLabel: this.localize('Target:'),
itemId: 'target',
helpTitle: this.localize('link_target_tooltip'),
store: new Ext.data.ArrayStore({
autoDestroy: true,
fields: [ { name: 'text'}, { name: 'value'}],
data: [
[this.localize('target_none'), ''],
[this.localize('target_blank'), '_blank'],
[this.localize('target_self'), '_self'],
[this.localize('target_top'), '_top'],
[this.localize('target_other'), '_other']
]
}),
listeners: {
select: {
fn: this.onTargetSelect
}
},
hidden: !this.showTarget
}, this.configDefaults['combo'])
,{
itemId: 'frame',
name: 'frame',
fieldLabel: this.localize('frame'),
helpTitle: this.localize('frame_help'),
hideLabel: true,
hidden: true
}
]
}
],
buttons: [
this.buildButtonConfig('OK', this.onOK),
this.buildButtonConfig('Cancel', this.onCancel)
]
});
this.show();
},
/*
* Handler invoked after the dialogue window is rendered
* If the current target is not in the available options, show frame field
*/
onAfterRender: function (dialog) {
var targetCombo = dialog.find('itemId', 'target')[0];
if (!targetCombo.hidden && this.parameters.target) {
var frameField = dialog.find('itemId', 'frame')[0];
var index = targetCombo.getStore().find('value', this.parameters.target);
if (index == -1) {
// The target is a specific frame name
targetCombo.setValue('_other');
frameField.setValue(this.parameters.target);
frameField.show();
frameField.label.show();
} else {
var href = param.f_href.trim();
this.editor.selectNodeContents(a);
if (href == "") {
this.editor._doc.execCommand("Unlink", false, null);
this.dialog.close();
return false;
} else {
a.href = href;
}
targetCombo.setValue(this.parameters.target);
}
if (!(a && /^a$/i.test(a.nodeName))) {
this.dialog.close();
return false;
}
if (typeof(param.f_target) != "undefined") a.target = param.f_target.trim();
if (typeof(param.f_title) != "undefined") a.title = param.f_title.trim();
this.editor.selectNodeContents(a);
this.dialog.close();
}
},
/*
* Handler invoked when a target is selected
*/
onTargetSelect: function (combo, record) {
var frameField = combo.ownerCt.getComponent('frame');
if (record.get('value') == '_other') {
frameField.show();
frameField.label.show();
frameField.focus();
} else if (!frameField.hidden) {
frameField.hide();
frameField.label.hide();
}
},
/*
* Handler invoked when the OK button is clicked
*/
onOK: function () {
var href = this.dialog.find('itemId', 'href')[0].getValue().trim();
if (!href) {
Ext.MessageBox.alert('', this.localize('link_url_required'));
this.dialog.find('itemId', 'href').focus();
return false;
}
var title = this.dialog.find('itemId', 'title')[0].getValue();
var target = this.dialog.find('itemId', 'target')[0].getValue();
if (target == '_other') {
target = this.dialog.find('itemId', 'frame')[0].getValue().trim();
}
this.createLink(href, title, target);
this.close();
return false;
},
/*
* Unlink the selection.
* Create the link
*
* @param object link: the link element to unlink
* @param string href: the value of href attribute
* @param string title: the value of title attribute
* @param string target: the value of target attribute
*
* @return boolean false
* @return void
*/
unLink : function () {
this.editor.focusEditor();
var node = this.editor.getParentElement();
var el = HTMLArea.getElementObject(node, "a");
if (el != null && /^a$/i.test(el.nodeName)) node = el;
if (node != null && /^a$/i.test(node.nodeName)) this.editor.selectNode(node);
this.editor._doc.execCommand("Unlink", false, "");
createLink: function (href, title, target) {
var a = this.link;
if (!a) {
this.editor.focus();
this.restoreSelection();
this.editor.document.execCommand('CreateLink', false, href);
a = this.editor.getParentElement();
if (!Ext.isIE && !/^a$/i.test(a.nodeName)) {
var range = this.editor._createRange(this.editor._getSelection());
if (range.startContainer.nodeType != 3) {
a = range.startContainer.childNodes[range.startOffset];
} else {
a = range.startContainer.nextSibling;
}
this.editor.selectNode(a);
}
var el = HTMLArea.getElementObject(a, 'a');
if (el != null && /^a$/i.test(el.nodeName)) {
a = el;
}
} else {
a.href = href;
}
if (a && /^a$/i.test(a.nodeName)) {
a.title = title;
a.target = target;
if (Ext.isOpera) {
this.editor.selectNodeContents(a, false);
} else {
this.editor.selectNodeContents(a);
}
}
},
/*
* Unlink the selection
*/
unLink: function () {
this.editor.focus();
this.restoreSelection();
if (this.link) {
this.editor.selectNode(this.link);
}
this.editor.document.execCommand('Unlink', false, '');
},
/*
* IE makes relative links absolute. This function reverts this conversion.
*
* @param string url: the url
*
* @return string the url stripped out of the baseurl
*/
stripBaseURL : function(url) {
stripBaseURL: function (url) {
var baseurl = this.baseURL;
// strip to last directory in case baseurl points to a file
baseurl = baseurl.replace(/[^\/]+$/, '');
var basere = new RegExp(baseurl);
url = url.replace(basere, "");
url = url.replace(basere, '');
// strip host-part of URL which is added by MSIE to links relative to server root
baseurl = baseurl.replace(/^(https?:\/\/[^\/]+)(.*)$/, '$1');
baseurl = baseurl.replace(/^(https?:\/\/[^\/]+)(.*)$/, "$1");
basere = new RegExp(baseurl);
return url.replace(basere, "");
return url.replace(basere, '');
},
/*
* This function gets called when the toolbar is updated
*/
onUpdateToolbar: function (button, mode, selectionEmpty, ancestors) {
if (mode === 'wysiwyg' && this.editor.isEditable() && button.itemId === 'CreateLink') {
button.setDisabled(selectionEmpty && !button.isInContext(mode, selectionEmpty, ancestors));
}
}
});
typo3/sysext/rtehtmlarea/htmlarea/plugins/DefaultLink/locallang.xml (copie de travail)
<data type="array">
<languageKey index="default" type="array">
<label index="Select some text">You need to select some text before creating a link</label>
<label index="frame">Frame name:</label>
<label index="frame_help">Enter the name of the frame to be used as target</label>
</languageKey>
</data>
<orig_hash type="array">
typo3/sysext/rtehtmlarea/htmlarea/plugins/DefaultLink/popups/link.html (copie de travail)
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
/***************************************************************
* Copyright notice
*
* (c) 2002-2004 interactivetools.com, inc.
* (c) 2003-2004 dynarch.com
* (c) 2004-2008 Stanislas Rolland <typo3(arobas)sjbr.ca>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This script is a modified version of a script published under the htmlArea License.
* A copy of the htmlArea License may be found in the textfile HTMLAREA_LICENSE.txt.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/*
* Insert Link window for TYPO3 htmlArea RTE
*
* TYPO3 SVN ID: $Id$
*/
-->
<html>
<head>
<title>Insert Image</title>
<meta http-equiv="Content-Style-Type" content="text/css" />
<script type="text/javascript">
/*<![CDATA[*/
<!--
var dialog = window.opener.HTMLArea.Dialog.DefaultLink;
function onTargetChanged() {
var f = document.getElementById("f_other_target");
if (this.value == "_other") {
f.style.visibility = "visible";
f.select();
f.focus();
} else {
f.style.visibility = "hidden";
}
};
function Init() {
dialog.initialize(false, true);
var param = dialog.arguments;
var target_select = document.getElementById("f_target");
if (param) {
document.getElementById("f_href").value = param["f_href"];
document.getElementById("f_title").value = param["f_title"];
if (dialog.plugin.showTarget) {
HTMLArea.selectValue(target_select, param["f_target"]);
if (target_select.value != param.f_target) {
var opt = document.createElement("option");
opt.value = param.f_target;
opt.innerHTML = opt.value;
target_select.appendChild(opt);
opt.selected = true;
}
var opt = document.createElement("option");
opt.value = "_other";
opt.innerHTML = dialog.plugin.localize("target_other");
target_select.appendChild(opt);
target_select.onchange = onTargetChanged;
} else {
document.getElementById("target").style.display = "none";
}
}
document.getElementById("f_href").focus();
document.getElementById("f_href").select();
dialog.resize();
return false;
};
function onOK() {
var required = { "f_href" : "link_url_required" };
for (var i in required) {
var el = document.getElementById(i);
if (!el.value) {
alert(dialog.plugin.localize(required[i]));
el.focus();
return false;
}
}
// pass data back to the calling window
var fields = ["f_href", "f_title", "f_target" ];
var param = new Object();
for (var i in fields) {
var id = fields[i];
var el = document.getElementById(id);
param[id] = el.value;
}
if (param.f_target == "_other") param.f_target = document.getElementById("f_other_target").value;
dialog.performAction(param);
return false;
};
function onCancel() {
dialog.close();
return false;
};
// -->
/*]]>*/
</script>
</head>
<body class="popupwin hrmlarea-default-link" onload="Init()">
<div id="content">
<div class="title">Insert/Modify Link</div>
<form action="" method="get">
<div id="url">
<label for="f_href" class="field">URL:</label>
<input type="text" id="f_href" size="65" title="link_href_tooltip" />
</div>
<div class="space"></div>
<div id="title">
<label for="f_title" class="field">Title (tooltip):</label>
<input type="text" id="f_title" size="65" title="link_title_tooltip" />
</div>
<div class="space"></div>
<div id="target">
<label for="f_target" class="field">Target:</label>
<select id="f_target" title="link_target_tooltip">
<option value="">target_none</option>
<option value="_blank">target_blank</option>
<option value="_self">target_self</option>
<option value="_top">target_top</option>
</select>
<input type="text" name="f_other_target" id="f_other_target" size="10" style="visibility: hidden" />
</div>
<div class="buttons">
<button type="button" name="ok" onclick="return onOK();">OK</button>
<button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
</div>
<br />
</form>
</div>
</body>
</html>
typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css (copie de travail)
width:300px;height:200px;
border:1px solid gray;margin:5px 0px;
}
/* Selectors for the Default Link dialogue */
.htmlarea-default-link #url, .htmlarea-default-link #title {
white-space:nowrap;
}
/* Selectors for the InsertSmiley plugin */
.htmlarea-window .emoticon-array {
padding: 10px;
typo3/sysext/t3skin/rtehtmlarea/htmlarea.css (copie de travail)
width:300px;height:200px;
border:1px solid gray;margin:5px 0px;
}
/* Selectors for the Default Link dialogue */
.htmlarea-default-link #url, .htmlarea-default-link #title {
white-space:nowrap;
}
/* Selectors for the InsertSmiley plugin */
.htmlarea-window .emoticon-array {
padding: 10px;
(1-1/2)