Commit d65d2475 authored by Fabian Galinski's avatar Fabian Galinski

Merge branch 'typo3v8compatibility' into 'master'

Typo3v8compatibility

See merge request !11
parents 8bcff201 f25ae9fa
......@@ -5,7 +5,7 @@ namespace SGalinski\Tinymce;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (http://www.sgalinski.de)
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
......@@ -31,6 +31,7 @@ use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Lang\LanguageService;
use TYPO3\CMS\Core\Localization\Locales;
/**
* tinyMCE initialisation class
......@@ -88,7 +89,9 @@ class Loader {
/**
* @param string $configuration file reference or configuration string (defaults to basic configuration)
* @param boolean $forceLanguage set this to true if you want to force your language set by the configuration
*
* @return void
* @throws \InvalidArgumentException
*/
public function loadConfiguration($configuration = '', $forceLanguage = FALSE) {
self::$init = FALSE;
......@@ -102,6 +105,7 @@ class Loader {
* Calculates and sets the current language
*
* @return void
* @throws \InvalidArgumentException
*/
protected function setLanguage() {
/** @var $languageInstance LanguageService */
......@@ -116,9 +120,8 @@ class Loader {
}
// language conversion from TLD to iso631
/** @var $locales \TYPO3\CMS\Core\Localization\Locales */
$locales = GeneralUtility::makeInstance('TYPO3\CMS\Core\Localization\Locales');
$locales->initialize();
$locales = GeneralUtility::makeInstance(Locales::class);
Locales::initialize();
$isoArray = (array) $locales->getIsoMapping();
if (array_key_exists($languageKey, $isoArray)) {
......@@ -146,8 +149,9 @@ class Loader {
* issue.
*
* @return string
* @throws \UnexpectedValueException
*/
protected function getConfiguration() {
protected function getConfiguration(): string {
$configuration = $this->tinymceConfiguration['preJS'];
$configuration .= '
var SG = SG || {};
......@@ -224,7 +228,7 @@ class Loader {
*
* @return string
*/
public function getJS() {
public function getJS(): string {
$output = '';
if (!self::$init) {
self::$init = TRUE;
......@@ -284,9 +288,11 @@ class Loader {
* Loads the required javascript via the require.js
*
* @return array
* @throws \BadFunctionCallException
* @throws \UnexpectedValueException
* @see \SGalinski\Tinymce4Rte\Form\Element\RichTextElement->loadRequireModulesForRTE
*/
public function loadJsViaRequireJS() {
public function loadJsViaRequireJS(): array {
if (self::$init) {
return [];
}
......@@ -306,6 +312,7 @@ class Loader {
' . $this->replaceTypo3Paths($this->tinymceConfiguration['configurationData']) . ',
selector: \'.tinymce4_rte#RTEarea' . strtr($this->tinymceConfiguration['configurationDataArray']['editornumber'], array('.' => '\\\\.', '\'' => '')) . '\'
});
$(\'#t3js-ui-block\').remove();
});
';
$configuration .= $this->tinymceConfiguration['postJS'];
......@@ -326,7 +333,7 @@ class Loader {
* @param string $configuration file reference or configuration string
* @return array
*/
protected function prepareTinyMCEConfiguration($configuration) {
protected function prepareTinyMCEConfiguration($configuration): array {
$configurationArray = [];
// try to resolve a potential TYPO3 file path
......@@ -386,7 +393,7 @@ class Loader {
* @param string $configuration
* @return string
*/
protected function replaceTypo3Paths($configuration) {
protected function replaceTypo3Paths($configuration): string {
$replacementFunction = function ($value) {
// getPath should be used, but this causes a php exception with PHP 5.3 as $this isn't set there
return '\'' . GeneralUtility::getIndpEnv('TYPO3_SITE_URL') .
......@@ -402,9 +409,11 @@ class Loader {
*
* @param string $relativePath
* @param bool $returnWithDomain
*
* @return string
* @throws \UnexpectedValueException
*/
protected function getPath($relativePath, $returnWithDomain = FALSE) {
protected function getPath($relativePath, $returnWithDomain = FALSE): string {
$finalPath = $absolutePath = GeneralUtility::getFileAbsFileName($relativePath);
if ($returnWithDomain) {
$finalPath = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . str_replace(PATH_site, '', $absolutePath);
......@@ -412,5 +421,3 @@ class Loader {
return $finalPath;
}
}
?>
......@@ -182,7 +182,11 @@ SG.TinyMceLoader.prototype = {
if (hasMatches) {
this.tinyMceOptions.selector = this.tinyMceOptions.selector.slice(1);
this.originalInit.call(tinymce, this.getTinyMceOptionsAsNewObject());
document.getElementById('pleasewait' + this.tinyMceOptions.editornumber).style.display = 'none';
var $pleaseWaitElement = document.getElementById('pleasewait' + this.tinyMceOptions.editornumber);
if ($pleaseWaitElement !== null) {
$pleaseWaitElement.style.display = 'none';
}
}
},
......@@ -200,4 +204,4 @@ SG.TinyMceLoader.prototype = {
return newObject;
}
};
\ No newline at end of file
};
......@@ -4,12 +4,12 @@
"description": "TinyMCE sources including a small PHP API",
"homepage": "https://www.sgalinski.de",
"license": "GPL-2.0+",
"version": "4.4.3",
"version": "5.0.0",
"support": {
"issues": "https://forge.typo3.org/projects/extension-tinymce"
},
"require": {
"typo3/cms-core": "^7.6"
"typo3/cms-core": "7.6.0 - 8.7.99"
},
"replace": {
"tinymce": "self.version",
......
......@@ -4,7 +4,7 @@ $EM_CONF[$_EXTKEY] = [
'title' => 'tinyMCE',
'description' => 'TinyMCE sources including a small PHP API',
'category' => 'misc',
'version' => '4.4.3',
'version' => '5.0.0',
'state' => 'stable',
'uploadfolder' => FALSE,
'createDirs' => '',
......@@ -20,8 +20,8 @@ $EM_CONF[$_EXTKEY] = [
[
'depends' =>
[
'php' => '5.5.0-0.0.0',
'typo3' => '6.2.0-7.6.99',
'php' => '7.0.0-7.1.99',
'typo3' => '7.6.0-8.7.99',
],
'conflicts' => [],
'suggests' => [],
......
......@@ -2,6 +2,6 @@
"name": "sg_tinymce",
"description": "",
"dependencies": {
"tinymce": "^4.4.1"
"tinymce": "^4.6.5"
}
}
This diff is collapsed.
{
"name": "tinymce/tinymce",
"version": "4.4.1",
"version": "4.6.6",
"description": "Web based JavaScript HTML WYSIWYG editor control.",
"license": [
"LGPL-2.1"
......
/**
* jquery.tinymce.js
*
* Released under LGPL License.
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/*global tinymce:true, jQuery */
(function($) {
var undef,
lazyLoading,
patchApplied,
delayedInits = [],
win = window;
$.fn.tinymce = function(settings) {
var self = this, url, base, lang, suffix = "";
// No match then just ignore the call
if (!self.length) {
return self;
}
// Get editor instance
if (!settings) {
return window.tinymce ? tinymce.get(self[0].id) : null;
}
self.css('visibility', 'hidden'); // Hide textarea to avoid flicker
function init() {
var editors = [], initCount = 0;
// Apply patches to the jQuery object, only once
if (!patchApplied) {
applyPatch();
patchApplied = true;
}
// Create an editor instance for each matched node
self.each(function(i, node) {
var ed, id = node.id, oninit = settings.oninit;
// Generate unique id for target element if needed
if (!id) {
node.id = id = tinymce.DOM.uniqueId();
}
// Only init the editor once
if (tinymce.get(id)) {
return;
}
// Create editor instance and render it
ed = new tinymce.Editor(id, settings, tinymce.EditorManager);
editors.push(ed);
ed.on('init', function() {
var scope, func = oninit;
self.css('visibility', '');
// Run this if the oninit setting is defined
// this logic will fire the oninit callback ones each
// matched editor instance is initialized
if (oninit) {
// Fire the oninit event ones each editor instance is initialized
if (++initCount == editors.length) {
if (typeof func === "string") {
scope = (func.indexOf(".") === -1) ? null : tinymce.resolve(func.replace(/\.\w+$/, ""));
func = tinymce.resolve(func);
}
// Call the oninit function with the object
func.apply(scope || tinymce, editors);
}
}
});
});
// Render the editor instances in a separate loop since we
// need to have the full editors array used in the onInit calls
$.each(editors, function(i, ed) {
ed.render();
});
}
// Load TinyMCE on demand, if we need to
if (!win.tinymce && !lazyLoading && (url = settings.script_url)) {
lazyLoading = 1;
base = url.substring(0, url.lastIndexOf("/"));
// Check if it's a dev/src version they want to load then
// make sure that all plugins, themes etc are loaded in source mode as well
if (url.indexOf('.min') != -1) {
suffix = ".min";
}
// Setup tinyMCEPreInit object this will later be used by the TinyMCE
// core script to locate other resources like CSS files, dialogs etc
// You can also predefined a tinyMCEPreInit object and then it will use that instead
win.tinymce = win.tinyMCEPreInit || {
base: base,
suffix: suffix
};
// url contains gzip then we assume it's a compressor
if (url.indexOf('gzip') != -1) {
lang = settings.language || "en";
url = url + (/\?/.test(url) ? '&' : '?') + "js=true&core=true&suffix=" + escape(suffix) +
"&themes=" + escape(settings.theme || 'modern') + "&plugins=" +
escape(settings.plugins || '') + "&languages=" + (lang || '');
// Check if compressor script is already loaded otherwise setup a basic one
if (!win.tinyMCE_GZ) {
win.tinyMCE_GZ = {
start: function() {
function load(url) {
tinymce.ScriptLoader.markDone(tinymce.baseURI.toAbsolute(url));
}
// Add core languages
load("langs/" + lang + ".js");
// Add themes with languages
load("themes/" + settings.theme + "/theme" + suffix + ".js");
load("themes/" + settings.theme + "/langs/" + lang + ".js");
// Add plugins with languages
$.each(settings.plugins.split(","), function(i, name) {
if (name) {
load("plugins/" + name + "/plugin" + suffix + ".js");
load("plugins/" + name + "/langs/" + lang + ".js");
}
});
},
end: function() {
}
};
}
}
var script = document.createElement('script');
script.type = 'text/javascript';
script.onload = script.onreadystatechange = function(e) {
e = e || window.event;
if (lazyLoading !== 2 && (e.type == 'load' || /complete|loaded/.test(script.readyState))) {
tinymce.dom.Event.domLoaded = 1;
lazyLoading = 2;
// Execute callback after mainscript has been loaded and before the initialization occurs
if (settings.script_loaded) {
settings.script_loaded();
}
init();
$.each(delayedInits, function(i, init) {
init();
});
}
};
script.src = url;
document.body.appendChild(script);
} else {
// Delay the init call until tinymce is loaded
if (lazyLoading === 1) {
delayedInits.push(init);
} else {
init();
}
}
return self;
};
// Add :tinymce pseudo selector this will select elements that has been converted into editor instances
// it's now possible to use things like $('*:tinymce') to get all TinyMCE bound elements.
$.extend($.expr[":"], {
tinymce: function(e) {
var editor;
if (e.id && "tinymce" in window) {
editor = tinymce.get(e.id);
if (editor && editor.editorManager === tinymce) {
return true;
}
}
return false;
}
});
// This function patches internal jQuery functions so that if
// you for example remove an div element containing an editor it's
// automatically destroyed by the TinyMCE API
function applyPatch() {
// Removes any child editor instances by looking for editor wrapper elements
function removeEditors(name) {
// If the function is remove
if (name === "remove") {
this.each(function(i, node) {
var ed = tinyMCEInstance(node);
if (ed) {
ed.remove();
}
});
}
this.find("span.mceEditor,div.mceEditor").each(function(i, node) {
var ed = tinymce.get(node.id.replace(/_parent$/, ""));
if (ed) {
ed.remove();
}
});
}
// Loads or saves contents from/to textarea if the value
// argument is defined it will set the TinyMCE internal contents
function loadOrSave(value) {
var self = this, ed;
// Handle set value
/*jshint eqnull:true */
if (value != null) {
removeEditors.call(self);
// Saves the contents before get/set value of textarea/div
self.each(function(i, node) {
var ed;
if ((ed = tinymce.get(node.id))) {
ed.setContent(value);
}
});
} else if (self.length > 0) {
// Handle get value
if ((ed = tinymce.get(self[0].id))) {
return ed.getContent();
}
}
}
// Returns tinymce instance for the specified element or null if it wasn't found
function tinyMCEInstance(element) {
var ed = null;
if (element && element.id && win.tinymce) {
ed = tinymce.get(element.id);
}
return ed;
}
// Checks if the specified set contains tinymce instances
function containsTinyMCE(matchedSet) {
return !!((matchedSet) && (matchedSet.length) && (win.tinymce) && (matchedSet.is(":tinymce")));
}
// Patch various jQuery functions
var jQueryFn = {};
// Patch some setter/getter functions these will
// now be able to set/get the contents of editor instances for
// example $('#editorid').html('Content'); will update the TinyMCE iframe instance
$.each(["text", "html", "val"], function(i, name) {
var origFn = jQueryFn[name] = $.fn[name],
textProc = (name === "text");
$.fn[name] = function(value) {
var self = this;
if (!containsTinyMCE(self)) {
return origFn.apply(self, arguments);
}
if (value !== undef) {
loadOrSave.call(self.filter(":tinymce"), value);
origFn.apply(self.not(":tinymce"), arguments);
return self; // return original set for chaining
}
var ret = "";
var args = arguments;
(textProc ? self : self.eq(0)).each(function(i, node) {
var ed = tinyMCEInstance(node);
if (ed) {
ret += textProc ? ed.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g, "") : ed.getContent({save: true});
} else {
ret += origFn.apply($(node), args);
}
});
return ret;
};
});
// Makes it possible to use $('#id').append("content"); to append contents to the TinyMCE editor iframe
$.each(["append", "prepend"], function(i, name) {
var origFn = jQueryFn[name] = $.fn[name],
prepend = (name === "prepend");
$.fn[name] = function(value) {
var self = this;
if (!containsTinyMCE(self)) {
return origFn.apply(self, arguments);
}
if (value !== undef) {
if (typeof value === "string") {
self.filter(":tinymce").each(function(i, node) {
var ed = tinyMCEInstance(node);
if (ed) {
ed.setContent(prepend ? value + ed.getContent() : ed.getContent() + value);
}
});
}
origFn.apply(self.not(":tinymce"), arguments);
return self; // return original set for chaining
}
};
});
// Makes sure that the editor instance gets properly destroyed when the parent element is removed
$.each(["remove", "replaceWith", "replaceAll", "empty"], function(i, name) {
var origFn = jQueryFn[name] = $.fn[name];
$.fn[name] = function() {
removeEditors.call(this, name);
return origFn.apply(this, arguments);
};
});
jQueryFn.attr = $.fn.attr;
// Makes sure that $('#tinymce_id').attr('value') gets the editors current HTML contents
$.fn.attr = function(name, value) {
var self = this, args = arguments;
if ((!name) || (name !== "value") || (!containsTinyMCE(self))) {
if (value !== undef) {
return jQueryFn.attr.apply(self, args);
}
return jQueryFn.attr.apply(self, args);
}
if (value !== undef) {
loadOrSave.call(self.filter(":tinymce"), value);
jQueryFn.attr.apply(self.not(":tinymce"), args);
return self; // return original set for chaining
}
var node = self[0], ed = tinyMCEInstance(node);