1
0
Fork 0

Merge branch 'master', remote-tracking branch 'remotes/upstream/master'

* remotes/upstream/master:
  update tinymce to 3.5.0.1
  rev update
  DE strings
  slackr drop shadows extended
  Allow plugins to modify the contact photo menu
  rev update

* master:
This commit is contained in:
Simon L'nu 2012-05-15 23:40:35 -04:00
commit a3137eec11
32 changed files with 6389 additions and 5370 deletions

View file

@ -9,7 +9,7 @@ require_once('include/nav.php');
require_once('include/cache.php'); require_once('include/cache.php');
define ( 'FRIENDICA_PLATFORM', 'Friendica'); define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_VERSION', '3.0.1341' ); define ( 'FRIENDICA_VERSION', '3.0.1343' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1143 ); define ( 'DB_UPDATE_VERSION', 1143 );

View file

@ -209,7 +209,7 @@ function contact_photo_menu($contact) {
); );
$args = array('contact' => $contact, 'menu' => $menu); $args = array('contact' => $contact, 'menu' => &$menu);
call_hooks('contact_photo_menu', $args); call_hooks('contact_photo_menu', $args);

View file

@ -1,3 +1,46 @@
Version 3.5.0.1 (2012-05-10)
Fixed bug where selection normalization logic would break the selections of parent elements using the element path.
Fixed bug where the autolink plugin would include trailing dots in domain names in the link creation.
Fixed bug where the autolink plugin would produce an error on older IE versions when pressing enter.
Fixed bug where old IE versions would throw an error during initialization when the editor was placed in an size restricted div.
Version 3.5 (2012-05-03)
Fixed menu rendering issue if the document was in rtl mode.
Fixed bug where the hide function would throw an error about a missing variable.
Fixed bug where autolink wouldn't convert URLs when hitting enter on IE due to the new enter key logic.
Fixed bug where formatting using shortcuts like ctrl+b wouldn't work properly the first time.
Fixed bug where selection.setContent after a formatter call wouldn't generate formatted contents.
Fixed bug where whitespace would be removed before/after invalid_elements when they where removed.
Fixed bug where updating styles using the theme image dialog in non inline mode on IE9 would produce errors.
Fixed bug where IE 8 would produce an error when using the contextmenu plugin.
Fixed bug where delete/backspace could remove contents of noneditable elements.
Fixed so background color in style preview gets computed from body element if the current style element is transparent.
Version 3.5b3 (2012-03-29)
Added cancel button to colour picker dialog.
Added figure and figcaption to the html5 visualblocks plugin.
Added default alignment options for the figure element.
Fixed bug where empty inline elements within block elements would sometimes produce a br child element.
Fixed bug where urls pointing to the same domain as the current one would cause undefined errors. Patch contributed by Paul Giberson.
Fixed bug where enter inside an editable element inside an non editable element would split the element.
Fixed bug where cut/copy/paste of noneditable elements didn't work.
Fixed bug where backspace would sometimes produce font elements on WebKit.
Fixed bug where WebKit would produce spans out of various inline elements when using backspace.
Fixed bug where IE9 wouldn't properly update image styles when images where resized.
Fixed bug where drag/drop of noneditable elements didn't work correctly.
Fixed bug where applying formatting to all contents wouldn't work correctly when an end point was inside an empty bock. Patch contributed by Jose Luiz.
Fixed bug where IE10 removed the scopeName from the DOM element interface and there for it produced an undefined string in element path.
Fixed bug where the caret would be placed at an incorrect location if you applied block formatting while having the caret at the end of the block.
Fixed bug where applying column changes using the cell dialog would only update the first column. Patch contributed by krzyko.
Fixed bug where the visualblocks plugin would force editor focus if it was turned on by default.
Fixed bug where the tabfocus plugin would tab to iframes these are now ignored.
Fixed bug where format drop down list wouldn't show the currently active format for a parent element.
Fixed bug where paste of plain text in IE 9 would remove the new line characters from text.
Fixed bug where the menu buttons/split button menus wouldn't be opened at the right location on older IE versions.
Fixed bug where Gecko browsers wouldn't properly display the right format when having the selection as specific places.
Fixed bug where shift+enter inside the body when having forced_root_blocks set to false would throw an error.
Fixed bug where the jQuery plugin would break the attr method of jQuery 1.7.2. Patch contributed by Markus Kemmerling.
Fixed so options like content_css accepts and array as well as a comma separated string as input.
Restructured the internal logic to make it more separate from Editor.js.
Updated the Sizzle engine to the latest version.
Version 3.5b2 (2012-03-15) Version 3.5b2 (2012-03-15)
Rewrote the enter key logic to normalize browser behavior. Rewrote the enter key logic to normalize browser behavior.
Fixed so enter within PRE elements produces a BR and shift+enter breaks/end the PRE. Can be disabled using the br_in_pre option. Fixed so enter within PRE elements produces a BR and shift+enter breaks/end the PRE. Can be disabled using the br_in_pre option.
@ -19,15 +62,6 @@ Version 3.5b1 (2012-03-08)
Fixed bug where the advlink dialog would produce an error about the addSelectAccessibility function not being defined. Fixed bug where the advlink dialog would produce an error about the addSelectAccessibility function not being defined.
Fixed bug where the caret would be placed at an incorrect position if span was removed by the invalid_elements setting. Fixed bug where the caret would be placed at an incorrect position if span was removed by the invalid_elements setting.
Fixed bug where elements inside a white space preserve element like pre didn't inherit the behavior while parsing. Fixed bug where elements inside a white space preserve element like pre didn't inherit the behavior while parsing.
Version 3.4.9.x (2012-02-xx)
Improved behaviour of backspacing into a table to be consistant across browsers and disable backspace when cursor immediately follows a table.
Improved edit CSS style plugin for single and multiple block selection and provide option to apply style to only selected text.
Fixed bug in Chrome where moving caret down in table and pasting throws errors.
Corrected reference to TinyMCE trim function.
Fixed bug where Ignore All in IE did not remove the underline from the selected word.
Fixed bug in html source editor word wrap option not wrapping text in Webkit browsers.
Fixed bug where it was possible to insert an invalid colour in the color pop-up dialog.
Fixed bug in Webkit where if anchor is on last line by itself caret can not be placed after it.
Version 3.4.9 (2012-02-23) Version 3.4.9 (2012-02-23)
Added settings to wordcount plugin to configure update rate and checking wordcount on backspace and delete using wordcount_update_rate and wordcount_update_on_delete. Added settings to wordcount plugin to configure update rate and checking wordcount on backspace and delete using wordcount_update_rate and wordcount_update_on_delete.
Fixed bug in Webkit and IE where deleting empty paragraphs would remove entire editor contents. Fixed bug in Webkit and IE where deleting empty paragraphs would remove entire editor contents.

View file

@ -1 +1 @@
(function(){tinymce.create("tinymce.plugins.AutolinkPlugin",{init:function(a,b){var c=this;if(tinyMCE.isIE){return}a.onKeyDown.add(function(d,f){if(f.keyCode==13){return c.handleEnter(d)}});a.onKeyPress.add(function(d,f){if(f.which==41){return c.handleEclipse(d)}});a.onKeyUp.add(function(d,f){if(f.keyCode==32){return c.handleSpacebar(d)}})},handleEclipse:function(a){this.parseCurrentLine(a,-1,"(",true)},handleSpacebar:function(a){this.parseCurrentLine(a,0,"",true)},handleEnter:function(a){this.parseCurrentLine(a,-1,"",false)},parseCurrentLine:function(i,d,b,g){var a,f,c,n,k,m,h,e,j;a=i.selection.getRng().cloneRange();if(a.startOffset<5){e=a.endContainer.previousSibling;if(e==null){if(a.endContainer.firstChild==null||a.endContainer.firstChild.nextSibling==null){return}e=a.endContainer.firstChild.nextSibling}j=e.length;a.setStart(e,j);a.setEnd(e,j);if(a.endOffset<5){return}f=a.endOffset;n=e}else{n=a.endContainer;if(n.nodeType!=3&&n.firstChild){while(n.nodeType!=3&&n.firstChild){n=n.firstChild}a.setStart(n,0);a.setEnd(n,n.nodeValue.length)}if(a.endOffset==1){f=2}else{f=a.endOffset-1-d}}c=f;do{a.setStart(n,f-2);a.setEnd(n,f-1);f-=1}while(a.toString()!=" "&&a.toString()!=""&&a.toString().charCodeAt(0)!=160&&(f-2)>=0&&a.toString()!=b);if(a.toString()==b||a.toString().charCodeAt(0)==160){a.setStart(n,f);a.setEnd(n,c);f+=1}else{if(a.startOffset==0){a.setStart(n,0);a.setEnd(n,c)}else{a.setStart(n,f);a.setEnd(n,c)}}m=a.toString();h=m.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])){h[1]="mailto:"+h[1]}}k=i.selection.getBookmark();i.selection.setRng(a);tinyMCE.execCommand("createlink",false,h[1]+h[2]);i.selection.moveToBookmark(k);if(tinyMCE.isWebKit){i.selection.collapse(false);var l=Math.min(n.length,c+1);a.setStart(n,l);a.setEnd(n,l);i.selection.setRng(a)}}},getInfo:function(){return{longname:"Autolink",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autolink",tinymce.plugins.AutolinkPlugin)})(); (function(){tinymce.create("tinymce.plugins.AutolinkPlugin",{init:function(a,b){var c=this;a.onKeyDown.addToTop(function(d,f){if(f.keyCode==13){return c.handleEnter(d)}});if(tinyMCE.isIE){return}a.onKeyPress.add(function(d,f){if(f.which==41){return c.handleEclipse(d)}});a.onKeyUp.add(function(d,f){if(f.keyCode==32){return c.handleSpacebar(d)}})},handleEclipse:function(a){this.parseCurrentLine(a,-1,"(",true)},handleSpacebar:function(a){this.parseCurrentLine(a,0,"",true)},handleEnter:function(a){this.parseCurrentLine(a,-1,"",false)},parseCurrentLine:function(i,d,b,g){var a,f,c,n,k,m,h,e,j;a=i.selection.getRng(true).cloneRange();if(a.startOffset<5){e=a.endContainer.previousSibling;if(e==null){if(a.endContainer.firstChild==null||a.endContainer.firstChild.nextSibling==null){return}e=a.endContainer.firstChild.nextSibling}j=e.length;a.setStart(e,j);a.setEnd(e,j);if(a.endOffset<5){return}f=a.endOffset;n=e}else{n=a.endContainer;if(n.nodeType!=3&&n.firstChild){while(n.nodeType!=3&&n.firstChild){n=n.firstChild}a.setStart(n,0);a.setEnd(n,n.nodeValue.length)}if(a.endOffset==1){f=2}else{f=a.endOffset-1-d}}c=f;do{a.setStart(n,f-2);a.setEnd(n,f-1);f-=1}while(a.toString()!=" "&&a.toString()!=""&&a.toString().charCodeAt(0)!=160&&(f-2)>=0&&a.toString()!=b);if(a.toString()==b||a.toString().charCodeAt(0)==160){a.setStart(n,f);a.setEnd(n,c);f+=1}else{if(a.startOffset==0){a.setStart(n,0);a.setEnd(n,c)}else{a.setStart(n,f);a.setEnd(n,c)}}var m=a.toString();if(m.charAt(m.length-1)=="."){a.setEnd(n,c-1)}m=a.toString();h=m.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])){h[1]="mailto:"+h[1]}}k=i.selection.getBookmark();i.selection.setRng(a);tinyMCE.execCommand("createlink",false,h[1]+h[2]);i.selection.moveToBookmark(k);if(tinyMCE.isWebKit){i.selection.collapse(false);var l=Math.min(n.length,c+1);a.setStart(n,l);a.setEnd(n,l);i.selection.setRng(a)}}},getInfo:function(){return{longname:"Autolink",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autolink",tinymce.plugins.AutolinkPlugin)})();

View file

@ -22,16 +22,16 @@
init : function(ed, url) { init : function(ed, url) {
var t = this; var t = this;
// Internet Explorer has built-in automatic linking
if (tinyMCE.isIE)
return;
// Add a key down handler // Add a key down handler
ed.onKeyDown.add(function(ed, e) { ed.onKeyDown.addToTop(function(ed, e) {
if (e.keyCode == 13) if (e.keyCode == 13)
return t.handleEnter(ed); return t.handleEnter(ed);
}); });
// Internet Explorer has built-in automatic linking for most cases
if (tinyMCE.isIE)
return;
ed.onKeyPress.add(function(ed, e) { ed.onKeyPress.add(function(ed, e) {
if (e.which == 41) if (e.which == 41)
return t.handleEclipse(ed); return t.handleEclipse(ed);
@ -61,7 +61,7 @@
// We need at least five characters to form a URL, // We need at least five characters to form a URL,
// hence, at minimum, five characters from the beginning of the line. // hence, at minimum, five characters from the beginning of the line.
r = ed.selection.getRng().cloneRange(); r = ed.selection.getRng(true).cloneRange();
if (r.startOffset < 5) { if (r.startOffset < 5) {
// During testing, the caret is placed inbetween two text nodes. // During testing, the caret is placed inbetween two text nodes.
// The previous text node contains the URL. // The previous text node contains the URL.
@ -124,6 +124,12 @@
r.setEnd(endContainer, start); r.setEnd(endContainer, start);
} }
// Exclude last . from word like "www.site.com."
var text = r.toString();
if (text.charAt(text.length - 1) == '.') {
r.setEnd(endContainer, start - 1);
}
text = r.toString(); text = r.toString();
matches = text.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i); matches = text.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);

View file

@ -1 +1 @@
(function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.FullScreenPlugin",{init:function(d,e){var f=this,g={},c,b;f.editor=d;d.addCommand("mceFullScreen",function(){var i,j=a.doc.documentElement;if(d.getParam("fullscreen_is_enabled")){if(d.getParam("fullscreen_new_window")){closeFullscreen()}else{a.win.setTimeout(function(){tinymce.dom.Event.remove(a.win,"resize",f.resizeFunc);tinyMCE.get(d.getParam("fullscreen_editor_id")).setContent(d.getContent());tinyMCE.remove(d);a.remove("mce_fullscreen_container");j.style.overflow=d.getParam("fullscreen_html_overflow");a.setStyle(a.doc.body,"overflow",d.getParam("fullscreen_overflow"));a.win.scrollTo(d.getParam("fullscreen_scrollx"),d.getParam("fullscreen_scrolly"));tinyMCE.settings=tinyMCE.oldSettings},10)}return}if(d.getParam("fullscreen_new_window")){i=a.win.open(e+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{i.resizeTo(screen.availWidth,screen.availHeight)}catch(h){}}else{tinyMCE.oldSettings=tinyMCE.settings;g.fullscreen_overflow=a.getStyle(a.doc.body,"overflow",1)||"auto";g.fullscreen_html_overflow=a.getStyle(j,"overflow",1);c=a.getViewPort();g.fullscreen_scrollx=c.x;g.fullscreen_scrolly=c.y;if(tinymce.isOpera&&g.fullscreen_overflow=="visible"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&g.fullscreen_overflow=="scroll"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&(g.fullscreen_html_overflow=="visible"||g.fullscreen_html_overflow=="scroll")){g.fullscreen_html_overflow="auto"}if(g.fullscreen_overflow=="0px"){g.fullscreen_overflow=""}a.setStyle(a.doc.body,"overflow","hidden");j.style.overflow="hidden";c=a.getViewPort();a.win.scrollTo(0,0);if(tinymce.isIE){c.h-=1}if(tinymce.isIE6){b="absolute;top:"+c.y}else{b="fixed;top:0"}n=a.add(a.doc.body,"div",{id:"mce_fullscreen_container",style:"position:"+b+";left:0;width:"+c.w+"px;height:"+c.h+"px;z-index:200000;"});a.add(n,"div",{id:"mce_fullscreen"});tinymce.each(d.settings,function(k,l){g[l]=k});g.id="mce_fullscreen";g.width=n.clientWidth;g.height=n.clientHeight-15;g.fullscreen_is_enabled=true;g.fullscreen_editor_id=d.id;g.theme_advanced_resizing=false;g.save_onsavecallback=function(){d.setContent(tinyMCE.get(g.id).getContent());d.execCommand("mceSave")};tinymce.each(d.getParam("fullscreen_settings"),function(m,l){g[l]=m});if(g.theme_advanced_toolbar_location==="external"){g.theme_advanced_toolbar_location="top"}f.fullscreenEditor=new tinymce.Editor("mce_fullscreen",g);f.fullscreenEditor.onInit.add(function(){f.fullscreenEditor.setContent(d.getContent());f.fullscreenEditor.focus()});f.fullscreenEditor.render();f.fullscreenElement=new tinymce.dom.Element("mce_fullscreen_container");f.fullscreenElement.update();f.resizeFunc=tinymce.dom.Event.add(a.win,"resize",function(){var o=tinymce.DOM.getViewPort(),l=f.fullscreenEditor,k,m;k=l.dom.getSize(l.getContainer().firstChild);m=l.dom.getSize(l.getContainer().getElementsByTagName("iframe")[0]);l.theme.resizeTo(o.w-k.w+m.w,o.h-k.h+m.h)})}});d.addButton("fullscreen",{title:"fullscreen.desc",cmd:"mceFullScreen"});d.onNodeChange.add(function(i,h){h.setActive("fullscreen",i.getParam("fullscreen_is_enabled"))})},getInfo:function(){return{longname:"Fullscreen",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("fullscreen",tinymce.plugins.FullScreenPlugin)})(); (function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.FullScreenPlugin",{init:function(d,e){var f=this,g={},c,b;f.editor=d;d.addCommand("mceFullScreen",function(){var i,j=a.doc.documentElement;if(d.getParam("fullscreen_is_enabled")){if(d.getParam("fullscreen_new_window")){closeFullscreen()}else{a.win.setTimeout(function(){tinymce.dom.Event.remove(a.win,"resize",f.resizeFunc);tinyMCE.get(d.getParam("fullscreen_editor_id")).setContent(d.getContent());tinyMCE.remove(d);a.remove("mce_fullscreen_container");j.style.overflow=d.getParam("fullscreen_html_overflow");a.setStyle(a.doc.body,"overflow",d.getParam("fullscreen_overflow"));a.win.scrollTo(d.getParam("fullscreen_scrollx"),d.getParam("fullscreen_scrolly"));tinyMCE.settings=tinyMCE.oldSettings},10)}return}if(d.getParam("fullscreen_new_window")){i=a.win.open(e+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{i.resizeTo(screen.availWidth,screen.availHeight)}catch(h){}}else{tinyMCE.oldSettings=tinyMCE.settings;g.fullscreen_overflow=a.getStyle(a.doc.body,"overflow",1)||"auto";g.fullscreen_html_overflow=a.getStyle(j,"overflow",1);c=a.getViewPort();g.fullscreen_scrollx=c.x;g.fullscreen_scrolly=c.y;if(tinymce.isOpera&&g.fullscreen_overflow=="visible"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&g.fullscreen_overflow=="scroll"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&(g.fullscreen_html_overflow=="visible"||g.fullscreen_html_overflow=="scroll")){g.fullscreen_html_overflow="auto"}if(g.fullscreen_overflow=="0px"){g.fullscreen_overflow=""}a.setStyle(a.doc.body,"overflow","hidden");j.style.overflow="hidden";c=a.getViewPort();a.win.scrollTo(0,0);if(tinymce.isIE){c.h-=1}if(tinymce.isIE6||document.compatMode=="BackCompat"){b="absolute;top:"+c.y}else{b="fixed;top:0"}n=a.add(a.doc.body,"div",{id:"mce_fullscreen_container",style:"position:"+b+";left:0;width:"+c.w+"px;height:"+c.h+"px;z-index:200000;"});a.add(n,"div",{id:"mce_fullscreen"});tinymce.each(d.settings,function(k,l){g[l]=k});g.id="mce_fullscreen";g.width=n.clientWidth;g.height=n.clientHeight-15;g.fullscreen_is_enabled=true;g.fullscreen_editor_id=d.id;g.theme_advanced_resizing=false;g.save_onsavecallback=function(){d.setContent(tinyMCE.get(g.id).getContent());d.execCommand("mceSave")};tinymce.each(d.getParam("fullscreen_settings"),function(m,l){g[l]=m});if(g.theme_advanced_toolbar_location==="external"){g.theme_advanced_toolbar_location="top"}f.fullscreenEditor=new tinymce.Editor("mce_fullscreen",g);f.fullscreenEditor.onInit.add(function(){f.fullscreenEditor.setContent(d.getContent());f.fullscreenEditor.focus()});f.fullscreenEditor.render();f.fullscreenElement=new tinymce.dom.Element("mce_fullscreen_container");f.fullscreenElement.update();f.resizeFunc=tinymce.dom.Event.add(a.win,"resize",function(){var o=tinymce.DOM.getViewPort(),l=f.fullscreenEditor,k,m;k=l.dom.getSize(l.getContainer().firstChild);m=l.dom.getSize(l.getContainer().getElementsByTagName("iframe")[0]);l.theme.resizeTo(o.w-k.w+m.w,o.h-k.h+m.h)})}});d.addButton("fullscreen",{title:"fullscreen.desc",cmd:"mceFullScreen"});d.onNodeChange.add(function(i,h){h.setActive("fullscreen",i.getParam("fullscreen_is_enabled"))})},getInfo:function(){return{longname:"Fullscreen",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("fullscreen",tinymce.plugins.FullScreenPlugin)})();

View file

@ -79,7 +79,7 @@
vp.h -= 1; vp.h -= 1;
// Use fixed position if it exists // Use fixed position if it exists
if (tinymce.isIE6) if (tinymce.isIE6 || document.compatMode == 'BackCompat')
posCss = 'absolute;top:' + vp.y; posCss = 'absolute;top:' + vp.y;
else else
posCss = 'fixed;top:0'; posCss = 'fixed;top:0';

File diff suppressed because one or more lines are too long

View file

@ -261,12 +261,96 @@
selection.collapse(start); selection.collapse(start);
} }
function canDelete(backspace) {
var rng, container, offset, nonEditableParent;
function removeNodeIfNotParent(node) {
var parent = container;
while (parent) {
if (parent === node) {
return;
}
parent = parent.parentNode;
}
dom.remove(node);
moveSelection();
}
function isNextPrevTreeNodeNonEditable() {
var node, walker, nonEmptyElements = ed.schema.getNonEmptyElements();
walker = new tinymce.dom.TreeWalker(container, ed.getBody());
while (node = (backspace ? walker.prev() : walker.next())) {
// Found IMG/INPUT etc
if (nonEmptyElements[node.nodeName.toLowerCase()]) {
break;
}
// Found text node with contents
if (node.nodeType === 3 && tinymce.trim(node.nodeValue).length > 0) {
break;
}
// Found non editable node
if (getContentEditable(node) === "false") {
removeNodeIfNotParent(node);
return true;
}
}
// Check if the content node is within a non editable parent
if (getNonEditableParent(node)) {
return true;
}
return false;
}
if (selection.isCollapsed()) {
rng = selection.getRng(true);
container = rng.startContainer;
offset = rng.startOffset;
container = getParentCaretContainer(container) || container;
// Is in noneditable parent
if (nonEditableParent = getNonEditableParent(container)) {
removeNodeIfNotParent(nonEditableParent);
return false;
}
// Check if the caret is in the middle of a text node
if (container.nodeType == 3 && (backspace ? offset > 0 : offset < container.nodeValue.length)) {
return true;
}
// Resolve container index
if (container.nodeType == 1) {
container = container.childNodes[offset] || container;
}
// Check if previous or next tree node is non editable then block the event
if (isNextPrevTreeNodeNonEditable()) {
return false;
}
}
return true;
}
startElement = selection.getStart() startElement = selection.getStart()
endElement = selection.getEnd(); endElement = selection.getEnd();
// Disable all key presses in contentEditable=false except delete or backspace // Disable all key presses in contentEditable=false except delete or backspace
nonEditableParent = getNonEditableParent(startElement) || getNonEditableParent(endElement); nonEditableParent = getNonEditableParent(startElement) || getNonEditableParent(endElement);
if (nonEditableParent && (keyCode < 112 || keyCode > 124) && keyCode != VK.DELETE && keyCode != VK.BACKSPACE) { if (nonEditableParent && (keyCode < 112 || keyCode > 124) && keyCode != VK.DELETE && keyCode != VK.BACKSPACE) {
// Is Ctrl+c, Ctrl+v or Ctrl+x then use default browser behavior
if ((tinymce.isMac ? e.metaKey : e.ctrlKey) && (keyCode == 67 || keyCode == 88 || keyCode == 86)) {
return;
}
e.preventDefault(); e.preventDefault();
// Arrow left/right select the element and collapse left/right // Arrow left/right select the element and collapse left/right
@ -298,6 +382,7 @@
positionCaretOnElement(nonEditableParent, true); positionCaretOnElement(nonEditableParent, true);
} else { } else {
dom.remove(nonEditableParent); dom.remove(nonEditableParent);
return;
} }
} else { } else {
removeCaretContainer(caretContainer); removeCaretContainer(caretContainer);
@ -315,23 +400,31 @@
positionCaretOnElement(nonEditableParent, false); positionCaretOnElement(nonEditableParent, false);
} else { } else {
dom.remove(nonEditableParent); dom.remove(nonEditableParent);
return;
} }
} else { } else {
removeCaretContainer(caretContainer); removeCaretContainer(caretContainer);
} }
} }
} }
if ((keyCode == VK.BACKSPACE || keyCode == VK.DELETE) && !canDelete(keyCode == VK.BACKSPACE)) {
e.preventDefault();
return false;
}
} }
} }
}; };
ed.onMouseDown.addToTop(function(ed, e){ ed.onMouseDown.addToTop(function(ed, e) {
// prevent collapsing selection to caret when clicking in a non-editable section
var node = ed.selection.getNode(); var node = ed.selection.getNode();
if (getContentEditable(node) === "false" && node == e.target) { if (getContentEditable(node) === "false" && node == e.target) {
e.preventDefault(); // Expand selection on mouse down we can't block the default event since it's used for drag/drop
moveSelection();
} }
}); });
ed.onMouseUp.addToTop(moveSelection); ed.onMouseUp.addToTop(moveSelection);
ed.onKeyDown.addToTop(handleKey); ed.onKeyDown.addToTop(handleKey);
ed.onKeyUp.addToTop(moveSelection); ed.onKeyUp.addToTop(moveSelection);
@ -341,6 +434,31 @@
init : function(ed, url) { init : function(ed, url) {
var editClass, nonEditClass, nonEditableRegExps; var editClass, nonEditClass, nonEditableRegExps;
// Converts configured regexps to noneditable span items
function convertRegExpsToNonEditable(ed, args) {
var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass);
// Don't replace the variables when raw is used for example on undo/redo
if (args.format == "raw") {
return;
}
while (i--) {
content = content.replace(nonEditableRegExps[i], function(match) {
var args = arguments, index = args[args.length - 2];
// Is value inside an attribute then don't replace
if (index > 0 && content.charAt(index - 1) == '"') {
return match;
}
return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>';
});
}
args.content = content;
};
editClass = " " + tinymce.trim(ed.getParam("noneditable_editable_class", "mceEditable")) + " "; editClass = " " + tinymce.trim(ed.getParam("noneditable_editable_class", "mceEditable")) + " ";
nonEditClass = " " + tinymce.trim(ed.getParam("noneditable_noneditable_class", "mceNonEditable")) + " "; nonEditClass = " " + tinymce.trim(ed.getParam("noneditable_noneditable_class", "mceNonEditable")) + " ";
@ -354,24 +472,8 @@
handleContentEditableSelection(ed); handleContentEditableSelection(ed);
if (nonEditableRegExps) { if (nonEditableRegExps) {
ed.onBeforeSetContent.add(function(ed, args) { ed.selection.onBeforeSetContent.add(convertRegExpsToNonEditable);
var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass); ed.onBeforeSetContent.add(convertRegExpsToNonEditable);
// Don't replace the variables when raw is used for example on undo/redo
if (args.format == "raw") {
return;
}
while (i--) {
content = content.replace(nonEditableRegExps[i], function() {
var args = arguments;
return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>';
});
}
args.content = content;
});
} }
// Apply contentEditable true/false on elements with the noneditable/editable classes // Apply contentEditable true/false on elements with the noneditable/editable classes

File diff suppressed because one or more lines are too long

View file

@ -359,7 +359,7 @@
} }
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser // IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
if (tinymce.isIE && document.documentMode >= 9) { if (tinymce.isIE && document.documentMode >= 9 && /<(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)/.test(o.content)) {
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser // IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
process([[/(?:<br>&nbsp;[\s\r\n]+|<br>)*(<\/?(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)[^>]*>)(?:<br>&nbsp;[\s\r\n]+|<br>)*/g, '$1']]); process([[/(?:<br>&nbsp;[\s\r\n]+|<br>)*(<\/?(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)[^>]*>)(?:<br>&nbsp;[\s\r\n]+|<br>)*/g, '$1']]);

View file

@ -1 +1 @@
(function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.explode;tinymce.create("tinymce.plugins.TabFocusPlugin",{init:function(f,g){function e(i,j){if(j.keyCode===9){return a.cancel(j)}}function h(l,p){var j,m,o,n,k;function q(t){n=c.select(":input:enabled,*[tabindex]");function s(v){return v.nodeName==="BODY"||(v.type!="hidden"&&!(v.style.display=="none")&&!(v.style.visibility=="hidden")&&s(v.parentNode))}function i(v){return v.attributes.tabIndex.specified||v.nodeName=="INPUT"||v.nodeName=="TEXTAREA"}function u(){return tinymce.isIE6||tinymce.isIE7}function r(v){return((!u()||i(v)))&&v.getAttribute("tabindex")!="-1"&&s(v)}d(n,function(w,v){if(w.id==l.id){j=v;return false}});if(t>0){for(m=j+1;m<n.length;m++){if(r(n[m])){return n[m]}}}else{for(m=j-1;m>=0;m--){if(r(n[m])){return n[m]}}}return null}if(p.keyCode===9){k=b(l.getParam("tab_focus",l.getParam("tabfocus_elements",":prev,:next")));if(k.length==1){k[1]=k[0];k[0]=":prev"}if(p.shiftKey){if(k[0]==":prev"){n=q(-1)}else{n=c.get(k[0])}}else{if(k[1]==":next"){n=q(1)}else{n=c.get(k[1])}}if(n){if(n.id&&(l=tinymce.get(n.id||n.name))){l.focus()}else{window.setTimeout(function(){if(!tinymce.isWebKit){window.focus()}n.focus()},10)}return a.cancel(p)}}}f.onKeyUp.add(e);if(tinymce.isGecko){f.onKeyPress.add(h);f.onKeyDown.add(e)}else{f.onKeyDown.add(h)}},getInfo:function(){return{longname:"Tabfocus",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("tabfocus",tinymce.plugins.TabFocusPlugin)})(); (function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.explode;tinymce.create("tinymce.plugins.TabFocusPlugin",{init:function(f,g){function e(i,j){if(j.keyCode===9){return a.cancel(j)}}function h(l,p){var j,m,o,n,k;function q(t){n=c.select(":input:enabled,*[tabindex]:not(iframe)");function s(v){return v.nodeName==="BODY"||(v.type!="hidden"&&!(v.style.display=="none")&&!(v.style.visibility=="hidden")&&s(v.parentNode))}function i(v){return v.attributes.tabIndex.specified||v.nodeName=="INPUT"||v.nodeName=="TEXTAREA"}function u(){return tinymce.isIE6||tinymce.isIE7}function r(v){return((!u()||i(v)))&&v.getAttribute("tabindex")!="-1"&&s(v)}d(n,function(w,v){if(w.id==l.id){j=v;return false}});if(t>0){for(m=j+1;m<n.length;m++){if(r(n[m])){return n[m]}}}else{for(m=j-1;m>=0;m--){if(r(n[m])){return n[m]}}}return null}if(p.keyCode===9){k=b(l.getParam("tab_focus",l.getParam("tabfocus_elements",":prev,:next")));if(k.length==1){k[1]=k[0];k[0]=":prev"}if(p.shiftKey){if(k[0]==":prev"){n=q(-1)}else{n=c.get(k[0])}}else{if(k[1]==":next"){n=q(1)}else{n=c.get(k[1])}}if(n){if(n.id&&(l=tinymce.get(n.id||n.name))){l.focus()}else{window.setTimeout(function(){if(!tinymce.isWebKit){window.focus()}n.focus()},10)}return a.cancel(p)}}}f.onKeyUp.add(e);if(tinymce.isGecko){f.onKeyPress.add(h);f.onKeyDown.add(e)}else{f.onKeyDown.add(h)}},getInfo:function(){return{longname:"Tabfocus",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("tabfocus",tinymce.plugins.TabFocusPlugin)})();

View file

@ -22,7 +22,7 @@
var x, i, f, el, v; var x, i, f, el, v;
function find(d) { function find(d) {
el = DOM.select(':input:enabled,*[tabindex]'); el = DOM.select(':input:enabled,*[tabindex]:not(iframe)');
function canSelectRecursive(e) { function canSelectRecursive(e) {
return e.nodeName==="BODY" || (e.type != 'hidden' && return e.nodeName==="BODY" || (e.type != 'hidden' &&

View file

@ -137,7 +137,7 @@ function updateAction() {
do { do {
if (cell == tdElm) if (cell == tdElm)
break; break;
col += cell.getAttribute("colspan"); col += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
} while ((cell = nextCell(cell)) != null); } while ((cell = nextCell(cell)) != null);
for (var i=0; i<rows.length; i++) { for (var i=0; i<rows.length; i++) {
@ -152,7 +152,7 @@ function updateAction() {
cell = updateCell(cell, true); cell = updateCell(cell, true);
break; break;
} }
curr += cell.getAttribute("colspan"); curr += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
} while ((cell = nextCell(cell)) != null); } while ((cell = nextCell(cell)) != null);
} }

View file

@ -1,6 +1,6 @@
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, blockquote, address, pre {display: block; padding-top: 10px; border: 1px dashed #BBB; background: transparent no-repeat} p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, blockquote, address, pre, figure {display: block; padding-top: 10px; border: 1px dashed #BBB; background: transparent no-repeat}
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, address, pre {margin-left: 3px} p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, address, pre, figure {margin-left: 3px}
section, article, address, hgroup, aside {margin: 1em 0 0 3px} section, article, address, hgroup, aside, figure {margin: 0 0 1em 3px}
p {background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7)} p {background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7)}
h1 {background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==)} h1 {background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==)}
@ -17,3 +17,5 @@ address {background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH
pre {background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==)} pre {background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==)}
hgroup {background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7)} hgroup {background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7)}
aside {background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=)} aside {background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=)}
figure {background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7)}
figcaption {border: 1px dashed #BBB}

View file

@ -1 +1 @@
(function(){tinymce.create("tinymce.plugins.VisualBlocks",{init:function(a,b){var c;if(!window.NodeList){return}a.addCommand("mceVisualBlocks",function(){var e=a.dom,d;if(!c){c=e.uniqueId();d=e.create("link",{id:c,rel:"stylesheet",href:b+"/css/visualblocks.css"});a.getDoc().getElementsByTagName("head")[0].appendChild(d)}else{d=e.get(c);d.disabled=!d.disabled}a.controlManager.setActive("visualblocks",!d.disabled)});a.addButton("visualblocks",{title:"visualblocks.desc",cmd:"mceVisualBlocks"});a.onInit.add(function(){if(a.settings.visualblocks_default_state){a.execCommand("mceVisualBlocks")}})},getInfo:function(){return{longname:"Visual blocks",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualblocks",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("visualblocks",tinymce.plugins.VisualBlocks)})(); (function(){tinymce.create("tinymce.plugins.VisualBlocks",{init:function(a,b){var c;if(!window.NodeList){return}a.addCommand("mceVisualBlocks",function(){var e=a.dom,d;if(!c){c=e.uniqueId();d=e.create("link",{id:c,rel:"stylesheet",href:b+"/css/visualblocks.css"});a.getDoc().getElementsByTagName("head")[0].appendChild(d)}else{d=e.get(c);d.disabled=!d.disabled}a.controlManager.setActive("visualblocks",!d.disabled)});a.addButton("visualblocks",{title:"visualblocks.desc",cmd:"mceVisualBlocks"});a.onInit.add(function(){if(a.settings.visualblocks_default_state){a.execCommand("mceVisualBlocks",false,null,{skip_focus:true})}})},getInfo:function(){return{longname:"Visual blocks",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualblocks",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("visualblocks",tinymce.plugins.VisualBlocks)})();

View file

@ -42,7 +42,7 @@
ed.onInit.add(function() { ed.onInit.add(function() {
if (ed.settings.visualblocks_default_state) { if (ed.settings.visualblocks_default_state) {
ed.execCommand('mceVisualBlocks'); ed.execCommand('mceVisualBlocks', false, null, {skip_focus : true});
} }
}); });
}, },

View file

@ -62,12 +62,8 @@
<div class="mceActionPanel"> <div class="mceActionPanel">
<input type="submit" id="insert" name="insert" value="{#apply}" /> <input type="submit" id="insert" name="insert" value="{#apply}" />
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();"/>
<div id="preview"></div> <div id="preview_wrapper"><div id="previewblock"><label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" class="text mceFocus" aria-required="true" /></div><span id="preview"></span></div>
<div id="previewblock">
<label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" class="text mceFocus" aria-required="true" />
</div>
</div> </div>
</form> </form>
</body> </body>

File diff suppressed because one or more lines are too long

View file

@ -69,6 +69,16 @@
each(previewStyles.split(' '), function(name) { each(previewStyles.split(' '), function(name) {
var value = dom.getStyle(previewElm, name, true); var value = dom.getStyle(previewElm, name, true);
// If background is transparent then check if the body has a background color we can use
if (name == 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) {
value = dom.getStyle(ed.getBody(), name, true);
// Ignore white since it's the default color, not the nicest fix
if (dom.toHex(value).toLowerCase() == '#ffffff') {
return;
}
}
// Old IE won't calculate the font size so we need to do that manually // Old IE won't calculate the font size so we need to do that manually
if (name == 'font-size') { if (name == 'font-size') {
if (/em|%$/.test(value)) { if (/em|%$/.test(value)) {
@ -608,7 +618,7 @@
// TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for. // TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for.
// Maybe actually inherit it from the original textara? // Maybe actually inherit it from the original textara?
n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '')}); n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '') + (ed.settings.directionality == "rtl" ? ' mceRtl' : '')});
DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label); DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label);
if (!DOM.boxModel) if (!DOM.boxModel)
@ -925,7 +935,7 @@
}, },
_addToolbars : function(c, o) { _addToolbars : function(c, o) {
var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup; var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup, toolbarsExist = false;
toolbarGroup = cf.createToolbarGroup('toolbargroup', { toolbarGroup = cf.createToolbarGroup('toolbargroup', {
'name': ed.getLang('advanced.toolbar'), 'name': ed.getLang('advanced.toolbar'),
@ -941,6 +951,7 @@
// Create toolbar and add the controls // Create toolbar and add the controls
for (i=1; (v = s['theme_advanced_buttons' + i]); i++) { for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {
toolbarsExist = true;
tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i}); tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i});
if (s['theme_advanced_buttons' + i + '_add']) if (s['theme_advanced_buttons' + i + '_add'])
@ -954,6 +965,9 @@
o.deltaHeight -= s.theme_advanced_row_height; o.deltaHeight -= s.theme_advanced_row_height;
} }
// Handle case when there are no toolbar buttons and ensure editor height is adjusted accordingly
if (!toolbarsExist)
o.deltaHeight -= s.theme_advanced_row_height;
h.push(toolbarGroup.renderHTML()); h.push(toolbarGroup.renderHTML());
h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->')); h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));
DOM.setHTML(n, h.join('')); DOM.setHTML(n, h.join(''));
@ -1112,7 +1126,7 @@
} }
if (c = cm.get('formatselect')) { if (c = cm.get('formatselect')) {
p = getParent(DOM.isBlock); p = getParent(ed.dom.isBlock);
if (p) if (p)
c.select(p.nodeName.toLowerCase()); c.select(p.nodeName.toLowerCase());
@ -1210,7 +1224,7 @@
return; return;
// Handle prefix // Handle prefix
if (tinymce.isIE && n.scopeName !== 'HTML') if (tinymce.isIE && n.scopeName !== 'HTML' && n.scopeName)
na = n.scopeName + ':' + na; na = n.scopeName + ':' + na;
// Remove internal prefix // Remove internal prefix
@ -1271,7 +1285,7 @@
if (v) { if (v) {
ti += 'class: ' + v + ' '; ti += 'class: ' + v + ' ';
if (DOM.isBlock(n) || na == 'img' || na == 'span') if (ed.dom.isBlock(n) || na == 'img' || na == 'span')
na += '.' + v; na += '.' + v;
} }
} }

View file

@ -104,10 +104,12 @@ var ImageDialog = {
}, },
updateStyle : function() { updateStyle : function() {
var dom = tinyMCEPopup.dom, st, v, f = document.forms[0]; var dom = tinyMCEPopup.dom, st = {}, v, f = document.forms[0];
if (tinyMCEPopup.editor.settings.inline_styles) { if (tinyMCEPopup.editor.settings.inline_styles) {
st = tinyMCEPopup.dom.parseStyle(this.styleVal); tinymce.each(tinyMCEPopup.dom.parseStyle(this.styleVal), function(value, key) {
st[key] = value;
});
// Handle align // Handle align
v = getSelectValue(f, 'align'); v = getSelectValue(f, 'align');

View file

@ -94,11 +94,12 @@ h3 {font-size:14px;}
#plugintable, #about #plugintable td {border:1px solid #919B9C;} #plugintable, #about #plugintable td {border:1px solid #919B9C;}
#plugintable {width:96%; margin-top:10px;} #plugintable {width:96%; margin-top:10px;}
#pluginscontainer {height:290px; overflow:auto;} #pluginscontainer {height:290px; overflow:auto;}
#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;} #colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px}
#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline}
#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap}
#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} #colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;}
#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} #colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
#colorpicker #light div {overflow:hidden;} #colorpicker #light div {overflow:hidden;}
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
#colorpicker .panel_wrapper div.current {height:175px;} #colorpicker .panel_wrapper div.current {height:175px;}
#colorpicker #namedcolors {width:150px;} #colorpicker #namedcolors {width:150px;}
#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} #colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}

View file

@ -58,7 +58,7 @@
/* Menu */ /* Menu */
.highcontrastSkin .mceNoIcons span.mceIcon {width:0;} .highcontrastSkin .mceNoIcons span.mceIcon {width:0;}
.highcontrastSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid; } .highcontrastSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid; direction:ltr}
.highcontrastSkin .mceMenu table {background:white; color: black} .highcontrastSkin .mceMenu table {background:white; color: black}
.highcontrastSkin .mceNoIcons a .mceText {padding-left:10px} .highcontrastSkin .mceNoIcons a .mceText {padding-left:10px}
.highcontrastSkin .mceMenu a, .highcontrastSkin .mceMenu span, .highcontrastSkin .mceMenu {display:block;background:white; color: black} .highcontrastSkin .mceMenu a, .highcontrastSkin .mceMenu span, .highcontrastSkin .mceMenu {display:block;background:white; color: black}
@ -90,6 +90,10 @@
.highcontrastSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF} .highcontrastSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF}
.highcontrastSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} .highcontrastSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}
/* Rtl */
.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0}
.mceRtl .mceMenuItem .mceText {text-align: right}
/* Formats */ /* Formats */
.highcontrastSkin .mce_p span.mceText {} .highcontrastSkin .mce_p span.mceText {}
.highcontrastSkin .mce_address span.mceText {font-style:italic} .highcontrastSkin .mce_address span.mceText {font-style:italic}

View file

@ -105,11 +105,12 @@ h3 {font-size:14px;}
#plugintable, #about #plugintable td {border:1px solid #919B9C;} #plugintable, #about #plugintable td {border:1px solid #919B9C;}
#plugintable {width:96%; margin-top:10px;} #plugintable {width:96%; margin-top:10px;}
#pluginscontainer {height:290px; overflow:auto;} #pluginscontainer {height:290px; overflow:auto;}
#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;} #colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px}
#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline}
#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap}
#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} #colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;}
#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} #colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
#colorpicker #light div {overflow:hidden;} #colorpicker #light div {overflow:hidden;}
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
#colorpicker .panel_wrapper div.current {height:175px;} #colorpicker .panel_wrapper div.current {height:175px;}
#colorpicker #namedcolors {width:150px;} #colorpicker #namedcolors {width:150px;}
#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} #colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}

View file

@ -86,7 +86,7 @@
.o2k7Skin .mce_forecolor span.mceAction, .o2k7Skin .mce_backcolor span.mceAction {height:15px;overflow:hidden} .o2k7Skin .mce_forecolor span.mceAction, .o2k7Skin .mce_backcolor span.mceAction {height:15px;overflow:hidden}
/* Menu */ /* Menu */
.o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD} .o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD; direction:ltr}
.o2k7Skin .mceNoIcons span.mceIcon {width:0;} .o2k7Skin .mceNoIcons span.mceIcon {width:0;}
.o2k7Skin .mceNoIcons a .mceText {padding-left:10px} .o2k7Skin .mceNoIcons a .mceText {padding-left:10px}
.o2k7Skin .mceMenu table {background:#FFF} .o2k7Skin .mceMenu table {background:#FFF}
@ -112,6 +112,10 @@
.o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF} .o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF}
.o2k7Skin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} .o2k7Skin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}
/* Rtl */
.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0}
.mceRtl .mceMenuItem .mceText {text-align: right}
/* Formats */ /* Formats */
.o2k7Skin .mce_formatPreview a {font-size:10px} .o2k7Skin .mce_formatPreview a {font-size:10px}
.o2k7Skin .mce_p span.mceText {} .o2k7Skin .mce_p span.mceText {}

File diff suppressed because one or more lines are too long

View file

@ -1,13 +1,14 @@
// FILE IS GENERATED BY COMBINING THE SOURCES IN THE "classes" DIRECTORY SO DON'T MODIFY THIS FILE DIRECTLY
(function(win) { (function(win) {
var whiteSpaceRe = /^\s*|\s*$/g, var whiteSpaceRe = /^\s*|\s*$/g,
undefined, isRegExpBroken = 'B'.replace(/A(.)|B/, '$1') === '$1'; undef, isRegExpBroken = 'B'.replace(/A(.)|B/, '$1') === '$1';
var tinymce = { var tinymce = {
majorVersion : '3', majorVersion : '3',
minorVersion : '5b2', minorVersion : '5.0.1',
releaseDate : '2012-03-15', releaseDate : '2012-05-10',
_init : function() { _init : function() {
var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v; var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
@ -50,7 +51,8 @@
// If base element found, add that infront of baseURL // If base element found, add that infront of baseURL
nl = d.getElementsByTagName('base'); nl = d.getElementsByTagName('base');
for (i=0; i<nl.length; i++) { for (i=0; i<nl.length; i++) {
if (v = nl[i].href) { v = nl[i].href;
if (v) {
// Host only value like http://site.com or http://site.com:8008 // Host only value like http://site.com or http://site.com:8008
if (/^https?:\/\/[^\/]+$/.test(v)) if (/^https?:\/\/[^\/]+$/.test(v))
v += '/'; v += '/';
@ -103,7 +105,7 @@
is : function(o, t) { is : function(o, t) {
if (!t) if (!t)
return o !== undefined; return o !== undef;
if (t == 'array' && (o.hasOwnProperty && o instanceof Array)) if (t == 'array' && (o.hasOwnProperty && o instanceof Array))
return true; return true;
@ -137,7 +139,7 @@
s = s || o; s = s || o;
if (o.length !== undefined) { if (o.length !== undef) {
// Indexed arrays, needed for Safari // Indexed arrays, needed for Safari
for (n=0, l = o.length; n < l; n++) { for (n=0, l = o.length; n < l; n++) {
if (cb.call(s, o[n], n, o) === false) if (cb.call(s, o[n], n, o) === false)
@ -191,19 +193,23 @@
return -1; return -1;
}, },
extend : function(o, e) { extend : function(obj, ext) {
var i, l, a = arguments; var i, l, name, args = arguments, value;
for (i = 1, l = a.length; i < l; i++) { for (i = 1, l = args.length; i < l; i++) {
e = a[i]; ext = args[i];
for (name in ext) {
if (ext.hasOwnProperty(name)) {
value = ext[name];
tinymce.each(e, function(v, n) { if (value !== undef) {
if (v !== undefined) obj[name] = value;
o[n] = v; }
}); }
}
} }
return o; return obj;
}, },
@ -346,12 +352,9 @@
}, },
addUnload : function(f, s) { addUnload : function(f, s) {
var t = this; var t = this, unload;
f = {func : f, scope : s || this}; unload = function() {
if (!t.unloads) {
function unload() {
var li = t.unloads, o, n; var li = t.unloads, o, n;
if (li) { if (li) {
@ -382,8 +385,6 @@
function fakeUnload() { function fakeUnload() {
var d = document; var d = document;
// Is there things still loading, then do some magic
if (d.readyState == 'interactive') {
function stop() { function stop() {
// Prevent memory leak // Prevent memory leak
d.detachEvent('onstop', stop); d.detachEvent('onstop', stop);
@ -395,6 +396,8 @@
d = 0; d = 0;
}; };
// Is there things still loading, then do some magic
if (d.readyState == 'interactive') {
// Fire unload when the currently loading page is stopped // Fire unload when the currently loading page is stopped
if (d) if (d)
d.attachEvent('onstop', stop); d.attachEvent('onstop', stop);
@ -409,6 +412,9 @@
} }
}; };
f = {func : f, scope : s || this};
if (!t.unloads) {
// Attach unload handler // Attach unload handler
if (win.attachEvent) { if (win.attachEvent) {
win.attachEvent('onunload', unload); win.attachEvent('onunload', unload);
@ -439,7 +445,11 @@
}, },
explode : function(s, d) { explode : function(s, d) {
return s ? tinymce.map(s.split(d || ','), tinymce.trim) : s; if (!s || tinymce.is(s, 'array')) {
return s;
}
return tinymce.map(s.split(d || ','), tinymce.trim);
}, },
_addVer : function(u) { _addVer : function(u) {
@ -465,7 +475,7 @@
var val = replace, args = arguments, i; var val = replace, args = arguments, i;
for (i = 0; i < args.length - 2; i++) { for (i = 0; i < args.length - 2; i++) {
if (args[i] === undefined) { if (args[i] === undef) {
val = val.replace(new RegExp('\\$' + i, 'g'), ''); val = val.replace(new RegExp('\\$' + i, 'g'), '');
} else { } else {
val = val.replace(new RegExp('\\$' + i, 'g'), args[i]); val = val.replace(new RegExp('\\$' + i, 'g'), args[i]);
@ -496,52 +506,64 @@
tinymce.create('tinymce.util.Dispatcher', { tinymce.create('tinymce.util.Dispatcher', {
scope : null, scope : null,
listeners : null, listeners : null,
inDispatch: false,
Dispatcher : function(s) { Dispatcher : function(scope) {
this.scope = s || this; this.scope = scope || this;
this.listeners = []; this.listeners = [];
}, },
add : function(cb, s) { add : function(callback, scope) {
this.listeners.push({cb : cb, scope : s || this.scope}); this.listeners.push({cb : callback, scope : scope || this.scope});
return cb; return callback;
}, },
addToTop : function(cb, s) { addToTop : function(callback, scope) {
this.listeners.unshift({cb : cb, scope : s || this.scope}); var self = this, listener = {cb : callback, scope : scope || self.scope};
return cb; // Create new listeners if addToTop is executed in a dispatch loop
if (self.inDispatch) {
self.listeners = [listener].concat(self.listeners);
} else {
self.listeners.unshift(listener);
}
return callback;
}, },
remove : function(cb) { remove : function(callback) {
var l = this.listeners, o = null; var listeners = this.listeners, output = null;
tinymce.each(l, function(c, i) { tinymce.each(listeners, function(listener, i) {
if (cb == c.cb) { if (callback == listener.cb) {
o = cb; output = listener;
l.splice(i, 1); listeners.splice(i, 1);
return false; return false;
} }
}); });
return o; return output;
}, },
dispatch : function() { dispatch : function() {
var s, a = arguments, i, li = this.listeners, c; var self = this, returnValue, args = arguments, i, listeners = self.listeners, listener;
self.inDispatch = true;
// Needs to be a real loop since the listener count might change while looping // Needs to be a real loop since the listener count might change while looping
// And this is also more efficient // And this is also more efficient
for (i = 0; i<li.length; i++) { for (i = 0; i < listeners.length; i++) {
c = li[i]; listener = listeners[i];
s = c.cb.apply(c.scope, a.length > 0 ? a : [c.scope]); returnValue = listener.cb.apply(listener.scope, args.length > 0 ? args : [listener.scope]);
if (s === false) if (returnValue === false)
break; break;
} }
return s; self.inDispatch = false;
return returnValue;
} }
}); });
@ -571,7 +593,7 @@ tinymce.create('tinymce.util.Dispatcher', {
u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u; u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;
// Relative path http:// or protocol relative //path // Relative path http:// or protocol relative //path
if (!/^[\w-]*:?\/\//.test(u)) { if (!/^[\w\-]*:?\/\//.test(u)) {
base_url = s.base_uri ? s.base_uri.path : new tinymce.util.URI(location.href).directory; base_url = s.base_uri ? s.base_uri.path : new tinymce.util.URI(location.href).directory;
u = ((s.base_uri && s.base_uri.protocol) || 'http') + '://mce_host' + t.toAbsPath(base_url, u); u = ((s.base_uri && s.base_uri.protocol) || 'http') + '://mce_host' + t.toAbsPath(base_url, u);
} }
@ -589,17 +611,18 @@ tinymce.create('tinymce.util.Dispatcher', {
t[v] = s; t[v] = s;
}); });
if (b = s.base_uri) { b = s.base_uri;
if (b) {
if (!t.protocol) if (!t.protocol)
t.protocol = b.protocol; t.protocol = b.protocol;
if (!t.userInfo) if (!t.userInfo)
t.userInfo = b.userInfo; t.userInfo = b.userInfo;
if (!t.port && t.host == 'mce_host') if (!t.port && t.host === 'mce_host')
t.port = b.port; t.port = b.port;
if (!t.host || t.host == 'mce_host') if (!t.host || t.host === 'mce_host')
t.host = b.host; t.host = b.host;
t.source = ''; t.source = '';
@ -635,6 +658,12 @@ tinymce.create('tinymce.util.Dispatcher', {
if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol) if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol)
return u.getURI(); return u.getURI();
var tu = t.getURI(), uu = u.getURI();
// Allow usage of the base_uri when relative_urls = true
if(tu == uu || (tu.charAt(tu.length - 1) == "/" && tu.substr(0, tu.length - 1) == uu))
return tu;
o = t.toRelPath(t.path, u.path); o = t.toRelPath(t.path, u.path);
// Add query // Add query
@ -649,7 +678,7 @@ tinymce.create('tinymce.util.Dispatcher', {
}, },
toAbsolute : function(u, nh) { toAbsolute : function(u, nh) {
var u = new tinymce.util.URI(u, {base_uri : this}); u = new tinymce.util.URI(u, {base_uri : this});
return u.getURI(this.host == u.host && this.protocol == u.protocol ? nh : 0); return u.getURI(this.host == u.host && this.protocol == u.protocol ? nh : 0);
}, },
@ -680,7 +709,7 @@ tinymce.create('tinymce.util.Dispatcher', {
} }
} }
if (bp == 1) if (bp === 1)
return path; return path;
for (i = 0, l = base.length - (bp - 1); i < l; i++) for (i = 0, l = base.length - (bp - 1); i < l; i++)
@ -715,11 +744,11 @@ tinymce.create('tinymce.util.Dispatcher', {
// Merge relURLParts chunks // Merge relURLParts chunks
for (i = path.length - 1, o = []; i >= 0; i--) { for (i = path.length - 1, o = []; i >= 0; i--) {
// Ignore empty or . // Ignore empty or .
if (path[i].length == 0 || path[i] == ".") if (path[i].length === 0 || path[i] === ".")
continue; continue;
// Is parent // Is parent
if (path[i] == '..') { if (path[i] === '..') {
nb++; nb++;
continue; continue;
} }
@ -830,7 +859,7 @@ tinymce.create('tinymce.util.Dispatcher', {
if (b == -1) { if (b == -1) {
b = c.indexOf(p); b = c.indexOf(p);
if (b != 0) if (b !== 0)
return null; return null;
} else } else
b += 2; b += 2;
@ -863,7 +892,7 @@ tinymce.create('tinymce.util.Dispatcher', {
(function() { (function() {
function serialize(o, quote) { function serialize(o, quote) {
var i, v, t; var i, v, t, name;
quote = quote || '"'; quote = quote || '"';
@ -901,9 +930,9 @@ tinymce.create('tinymce.util.Dispatcher', {
v = '{'; v = '{';
for (i in o) { for (name in o) {
if (o.hasOwnProperty(i)) { if (o.hasOwnProperty(name)) {
v += typeof o[i] != 'function' ? (v.length > 1 ? ',' + quote : quote) + i + quote +':' + serialize(o[i], quote) : ''; v += typeof o[name] != 'function' ? (v.length > 1 ? ',' + quote : quote) + name + quote +':' + serialize(o[name], quote) : '';
} }
} }
@ -931,6 +960,18 @@ tinymce.create('static tinymce.util.XHR', {
send : function(o) { send : function(o) {
var x, t, w = window, c = 0; var x, t, w = window, c = 0;
function ready() {
if (!o.async || x.readyState == 4 || c++ > 10000) {
if (o.success && c < 10000 && x.status == 200)
o.success.call(o.success_scope, '' + x.responseText, x, o);
else if (o.error)
o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);
x = null;
} else
w.setTimeout(ready, 10);
};
// Default settings // Default settings
o.scope = o.scope || this; o.scope = o.scope || this;
o.success_scope = o.success_scope || o.scope; o.success_scope = o.success_scope || o.scope;
@ -964,18 +1005,6 @@ tinymce.create('static tinymce.util.XHR', {
x.send(o.data); x.send(o.data);
function ready() {
if (!o.async || x.readyState == 4 || c++ > 10000) {
if (o.success && c < 10000 && x.status == 200)
o.success.call(o.success_scope, '' + x.responseText, x, o);
else if (o.error)
o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);
x = null;
} else
w.setTimeout(ready, 10);
};
// Syncronous request // Syncronous request
if (!o.async) if (!o.async)
return ready(); return ready();
@ -1055,13 +1084,13 @@ tinymce.create('static tinymce.util.XHR', {
modifierPressed: function (e) { modifierPressed: function (e) {
return e.shiftKey || e.ctrlKey || e.altKey; return e.shiftKey || e.ctrlKey || e.altKey;
} }
} };
})(tinymce); })(tinymce);
(function(tinymce) { tinymce.util.Quirks = function(editor) {
var VK = tinymce.VK, BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE; var VK = tinymce.VK, BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, settings = editor.settings;
function setEditorCommandState(editor, cmd, state) { function setEditorCommandState(cmd, state) {
try { try {
editor.getDoc().execCommand(cmd, false, state); editor.getDoc().execCommand(cmd, false, state);
} catch (ex) { } catch (ex) {
@ -1069,19 +1098,10 @@ tinymce.create('static tinymce.util.XHR', {
} }
} }
function cleanupStylesWhenDeleting(ed) { function cleanupStylesWhenDeleting() {
var dom = ed.dom, selection = ed.selection; function removeMergedFormatSpans(isDelete) {
var rng, blockElm, node, clonedSpan;
ed.onKeyDown.add(function(ed, e) {
var rng, blockElm, node, clonedSpan, isDelete;
if (e.isDefaultPrevented()) {
return;
}
isDelete = e.keyCode == DELETE;
if ((isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
e.preventDefault();
rng = selection.getRng(); rng = selection.getRng();
// Find root block // Find root block
@ -1096,7 +1116,7 @@ tinymce.create('static tinymce.util.XHR', {
node = blockElm.firstChild; node = blockElm.firstChild;
// Ignore empty text nodes // Ignore empty text nodes
while (node && node.nodeType == 3 && node.nodeValue.length == 0) while (node && node.nodeType == 3 && node.nodeValue.length === 0)
node = node.nextSibling; node = node.nextSibling;
if (node && node.nodeName === 'SPAN') { if (node && node.nodeName === 'SPAN') {
@ -1105,7 +1125,7 @@ tinymce.create('static tinymce.util.XHR', {
} }
// Do the backspace/delete action // Do the backspace/delete action
ed.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null); editor.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null);
// Find all odd apple-style-spans // Find all odd apple-style-spans
blockElm = dom.getParent(rng.startContainer, dom.isBlock); blockElm = dom.getParent(rng.startContainer, dom.isBlock);
@ -1121,55 +1141,120 @@ tinymce.create('static tinymce.util.XHR', {
// Restore the selection // Restore the selection
selection.moveToBookmark(bm); selection.moveToBookmark(bm);
}); });
}
});
}; };
function emptyEditorWhenDeleting(ed) { editor.onKeyDown.add(function(editor, e) {
function serializeRng(rng) { var isDelete;
var body = ed.dom.create("body");
var contents = rng.cloneContents(); isDelete = e.keyCode == DELETE;
body.appendChild(contents); if (!e.isDefaultPrevented() && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
return ed.selection.serializer.serialize(body, {format: 'html'}); e.preventDefault();
removeMergedFormatSpans(isDelete);
}
});
editor.addCommand('Delete', function() {removeMergedFormatSpans();});
};
function emptyEditorWhenDeleting() {
function getEndPointNode(rng, start) {
var container, offset, prefix = start ? 'start' : 'end';
container = rng[prefix + 'Container'];
offset = rng[prefix + 'Offset'];
// Resolve indexed container
if (container.nodeType == 1 && container.hasChildNodes()) {
container = container.childNodes[Math.min(start ? offset : (offset > 0 ? offset - 1 : 0), container.childNodes.length - 1)]
} }
function allContentsSelected(rng) { return container;
var selection = serializeRng(rng); };
var allRng = ed.dom.createRng(); function isAtStartEndOfBody(rng, start) {
allRng.selectNode(ed.getBody()); var container, offset, root, childNode, prefix = start ? 'start' : 'end', isAfter;
var allSelection = serializeRng(allRng); container = rng[prefix + 'Container'];
return selection === allSelection; offset = rng[prefix + 'Offset'];
root = dom.getRoot();
// Resolve indexed container
if (container.nodeType == 1) {
isAfter = offset >= container.childNodes.length;
container = getEndPointNode(rng, start);
if (container.nodeType == 3) {
offset = start && !isAfter ? 0 : container.nodeValue.length;
}
} }
ed.onKeyDown.addToTop(function(ed, e) { // Check if start/end is in the middle of text
var keyCode = e.keyCode; if (container.nodeType == 3 && ((start && offset > 0) || (!start && offset < container.nodeValue.length))) {
if (keyCode == DELETE || keyCode == BACKSPACE) { return false;
var rng = ed.selection.getRng(true); }
if (!rng.collapsed && allContentsSelected(rng)) {
ed.setContent('', {format : 'raw'}); // Walk up the DOM tree to see if the endpoint is at the beginning/end of body
ed.nodeChanged(); while (container !== root) {
childNode = container.parentNode[start ? 'firstChild' : 'lastChild'];
// If first/last element is a BR then jump to it's sibling in case: <p>x<br></p>
if (childNode.nodeName == "BR") {
childNode = childNode[start ? 'nextSibling' : 'previousSibling'] || childNode;
}
// If the childNode isn't the container node then break in case <p><span>A</span>[X]</p>
if (childNode !== container) {
return false;
}
container = container.parentNode;
}
return true;
};
editor.onKeyDown.addToTop(function(editor, e) {
var rng, keyCode = e.keyCode;
if (!e.isDefaultPrevented() && (keyCode == DELETE || keyCode == BACKSPACE)) {
rng = selection.getRng(true);
if (isAtStartEndOfBody(rng, true) && isAtStartEndOfBody(rng, false) &&
(rng.collapsed || dom.findCommonAncestor(getEndPointNode(rng, true), getEndPointNode(rng)) === dom.getRoot())) {
editor.setContent('');
editor.nodeChanged();
e.preventDefault(); e.preventDefault();
} }
} }
}); });
}; };
function inputMethodFocus(ed) { function inputMethodFocus() {
ed.dom.bind(ed.getDoc(), 'focusin', function() { if (!editor.settings.content_editable) {
ed.selection.setRng(ed.selection.getRng()); // Case 1 IME doesn't initialize if you focus the document
dom.bind(editor.getDoc(), 'focusin', function(e) {
selection.setRng(selection.getRng());
}); });
// Case 2 IME doesn't initialize if you click the documentElement it also doesn't properly fire the focusin event
dom.bind(editor.getDoc(), 'mousedown', function(e) {
if (e.target == editor.getDoc().documentElement) {
editor.getWin().focus();
selection.setRng(selection.getRng());
}
});
}
}; };
function removeHrOnBackspace(ed) { function removeHrOnBackspace() {
ed.onKeyDown.add(function(ed, e) { editor.onKeyDown.add(function(editor, e) {
if (e.keyCode === BACKSPACE) { if (!e.isDefaultPrevented() && e.keyCode === BACKSPACE) {
if (ed.selection.isCollapsed() && ed.selection.getRng(true).startOffset === 0) { if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
var node = ed.selection.getNode(); var node = selection.getNode();
var previousSibling = node.previousSibling; var previousSibling = node.previousSibling;
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "hr") { if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "hr") {
ed.dom.remove(previousSibling); dom.remove(previousSibling);
tinymce.dom.Event.cancel(e); tinymce.dom.Event.cancel(e);
} }
} }
@ -1177,13 +1262,13 @@ tinymce.create('static tinymce.util.XHR', {
}) })
} }
function focusBody(ed) { function focusBody() {
// Fix for a focus bug in FF 3.x where the body element // Fix for a focus bug in FF 3.x where the body element
// wouldn't get proper focus if the user clicked on the HTML element // wouldn't get proper focus if the user clicked on the HTML element
if (!Range.prototype.getClientRects) { // Detect getClientRects got introduced in FF 4 if (!Range.prototype.getClientRects) { // Detect getClientRects got introduced in FF 4
ed.onMouseDown.add(function(ed, e) { editor.onMouseDown.add(function(editor, e) {
if (e.target.nodeName === "HTML") { if (e.target.nodeName === "HTML") {
var body = ed.getBody(); var body = editor.getBody();
// Blur the body it's focused but not correctly focused // Blur the body it's focused but not correctly focused
body.blur(); body.blur();
@ -1197,33 +1282,33 @@ tinymce.create('static tinymce.util.XHR', {
} }
}; };
function selectControlElements(ed) { function selectControlElements() {
ed.onClick.add(function(ed, e) { editor.onClick.add(function(editor, e) {
e = e.target; e = e.target;
// Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250 // Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250
// WebKit can't even do simple things like selecting an image // WebKit can't even do simple things like selecting an image
// Needs tobe the setBaseAndExtend or it will fail to select floated images // Needs tobe the setBaseAndExtend or it will fail to select floated images
if (/^(IMG|HR)$/.test(e.nodeName)) if (/^(IMG|HR)$/.test(e.nodeName)) {
ed.selection.getSel().setBaseAndExtent(e, 0, e, 1); selection.getSel().setBaseAndExtent(e, 0, e, 1);
}
if (e.nodeName == 'A' && ed.dom.hasClass(e, 'mceItemAnchor')) if (e.nodeName == 'A' && dom.hasClass(e, 'mceItemAnchor')) {
ed.selection.select(e); selection.select(e);
}
ed.nodeChanged(); editor.nodeChanged();
}); });
}; };
function removeStylesWhenDeletingAccrossBlockElements(ed) { function removeStylesWhenDeletingAccrossBlockElements() {
var selection = ed.selection, dom = ed.dom;
function getAttributeApplyFunction() { function getAttributeApplyFunction() {
var template = dom.getAttribs(selection.getStart().cloneNode(false)); var template = dom.getAttribs(selection.getStart().cloneNode(false));
return function() { return function() {
var target = selection.getStart(); var target = selection.getStart();
if (target !== ed.getBody()) { if (target !== editor.getBody()) {
dom.setAttrib(target, "style", null); dom.setAttrib(target, "style", null);
tinymce.each(template, function(attr) { tinymce.each(template, function(attr) {
@ -1237,91 +1322,68 @@ tinymce.create('static tinymce.util.XHR', {
return !selection.isCollapsed() && selection.getStart() != selection.getEnd(); return !selection.isCollapsed() && selection.getStart() != selection.getEnd();
} }
function blockEvent(ed, e) { function blockEvent(editor, e) {
e.preventDefault(); e.preventDefault();
return false; return false;
} }
ed.onKeyPress.add(function(ed, e) { editor.onKeyPress.add(function(editor, e) {
var applyAttributes; var applyAttributes;
if ((e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) { if ((e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) {
applyAttributes = getAttributeApplyFunction(); applyAttributes = getAttributeApplyFunction();
ed.getDoc().execCommand('delete', false, null); editor.getDoc().execCommand('delete', false, null);
applyAttributes(); applyAttributes();
e.preventDefault(); e.preventDefault();
return false; return false;
} }
}); });
dom.bind(ed.getDoc(), 'cut', function(e) { dom.bind(editor.getDoc(), 'cut', function(e) {
var applyAttributes; var applyAttributes;
if (isSelectionAcrossElements()) { if (isSelectionAcrossElements()) {
applyAttributes = getAttributeApplyFunction(); applyAttributes = getAttributeApplyFunction();
ed.onKeyUp.addToTop(blockEvent); editor.onKeyUp.addToTop(blockEvent);
setTimeout(function() { setTimeout(function() {
applyAttributes(); applyAttributes();
ed.onKeyUp.remove(blockEvent); editor.onKeyUp.remove(blockEvent);
}, 0); }, 0);
} }
}); });
} }
/* function selectionChangeNodeChanged() {
function removeStylesOnPTagsInheritedFromHeadingTag(ed) {
ed.onKeyDown.add(function(ed, event) {
function checkInHeadingTag(ed) {
var currentNode = ed.selection.getNode();
var headingTags = 'h1,h2,h3,h4,h5,h6';
return ed.dom.is(currentNode, headingTags) || ed.dom.getParent(currentNode, headingTags) !== null;
}
if (event.keyCode === VK.ENTER && !VK.modifierPressed(event) && checkInHeadingTag(ed)) {
setTimeout(function() {
var currentNode = ed.selection.getNode();
if (ed.dom.is(currentNode, 'p')) {
ed.dom.setAttrib(currentNode, 'style', null);
// While tiny's content is correct after this method call, the content shown is not representative of it and needs to be 'repainted'
ed.execCommand('mceCleanup');
}
}, 0);
}
});
}
*/
function selectionChangeNodeChanged(ed) {
var lastRng, selectionTimer; var lastRng, selectionTimer;
ed.dom.bind(ed.getDoc(), 'selectionchange', function() { dom.bind(editor.getDoc(), 'selectionchange', function() {
if (selectionTimer) { if (selectionTimer) {
clearTimeout(selectionTimer); clearTimeout(selectionTimer);
selectionTimer = 0; selectionTimer = 0;
} }
selectionTimer = window.setTimeout(function() { selectionTimer = window.setTimeout(function() {
var rng = ed.selection.getRng(); var rng = selection.getRng();
// Compare the ranges to see if it was a real change or not // Compare the ranges to see if it was a real change or not
if (!lastRng || !tinymce.dom.RangeUtils.compareRanges(rng, lastRng)) { if (!lastRng || !tinymce.dom.RangeUtils.compareRanges(rng, lastRng)) {
ed.nodeChanged(); editor.nodeChanged();
lastRng = rng; lastRng = rng;
} }
}, 50); }, 50);
}); });
} }
function ensureBodyHasRoleApplication(ed) { function ensureBodyHasRoleApplication() {
document.body.setAttribute("role", "application"); document.body.setAttribute("role", "application");
} }
function disableBackspaceIntoATable(ed) { function disableBackspaceIntoATable() {
ed.onKeyDown.add(function(ed, e) { editor.onKeyDown.add(function(editor, e) {
if (e.keyCode === BACKSPACE) { if (!e.isDefaultPrevented() && e.keyCode === BACKSPACE) {
if (ed.selection.isCollapsed() && ed.selection.getRng(true).startOffset === 0) { if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
var previousSibling = ed.selection.getNode().previousSibling; var previousSibling = selection.getNode().previousSibling;
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "table") { if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "table") {
return tinymce.dom.Event.cancel(e); return tinymce.dom.Event.cancel(e);
} }
@ -1330,7 +1392,7 @@ tinymce.create('static tinymce.util.XHR', {
}) })
} }
function addNewLinesBeforeBrInPre(editor) { function addNewLinesBeforeBrInPre() {
var documentMode = editor.getDoc().documentMode; var documentMode = editor.getDoc().documentMode;
// IE8+ rendering mode does the right thing with BR in PRE // IE8+ rendering mode does the right thing with BR in PRE
@ -1340,8 +1402,8 @@ tinymce.create('static tinymce.util.XHR', {
// Enable display: none in area and add a specific class that hides all BR elements in PRE to // Enable display: none in area and add a specific class that hides all BR elements in PRE to
// avoid the caret from getting stuck at the BR elements while pressing the right arrow key // avoid the caret from getting stuck at the BR elements while pressing the right arrow key
setEditorCommandState(editor, 'RespectVisibilityInDesign', true); setEditorCommandState('RespectVisibilityInDesign', true);
editor.dom.addClass(editor.getBody(), 'mceHideBrInPre'); dom.addClass(editor.getBody(), 'mceHideBrInPre');
// Adds a \n before all BR elements in PRE to get them visual // Adds a \n before all BR elements in PRE to get them visual
editor.parser.addNodeFilter('pre', function(nodes, name) { editor.parser.addNodeFilter('pre', function(nodes, name) {
@ -1382,43 +1444,210 @@ tinymce.create('static tinymce.util.XHR', {
}); });
} }
tinymce.create('tinymce.util.Quirks', { function removePreSerializedStylesWhenSelectingControls() {
Quirks: function(ed) { dom.bind(editor.getBody(), 'mouseup', function(e) {
var value, node = selection.getNode();
// Moved styles to attributes on IMG eements
if (node.nodeName == 'IMG') {
// Convert style width to width attribute
if (value = dom.getStyle(node, 'width')) {
dom.setAttrib(node, 'width', value.replace(/[^0-9%]+/g, ''));
dom.setStyle(node, 'width', '');
}
// Convert style height to height attribute
if (value = dom.getStyle(node, 'height')) {
dom.setAttrib(node, 'height', value.replace(/[^0-9%]+/g, ''));
dom.setStyle(node, 'height', '');
}
}
});
}
function keepInlineElementOnDeleteBackspace() {
editor.onKeyDown.add(function(editor, e) {
var isDelete, rng, container, offset, brElm, sibling, collapsed;
isDelete = e.keyCode == DELETE;
if (!e.isDefaultPrevented() && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
rng = selection.getRng();
container = rng.startContainer;
offset = rng.startOffset;
collapsed = rng.collapsed;
// Override delete if the start container is a text node and is at the beginning of text or
// just before/after the last character to be deleted in collapsed mode
if (container.nodeType == 3 && container.nodeValue.length > 0 && ((offset === 0 && !collapsed) || (collapsed && offset === (isDelete ? 0 : 1)))) {
nonEmptyElements = editor.schema.getNonEmptyElements();
// Prevent default logic since it's broken
e.preventDefault();
// Insert a BR before the text node this will prevent the containing element from being deleted/converted
brElm = dom.create('br', {id: '__tmp'});
container.parentNode.insertBefore(brElm, container);
// Do the browser delete
editor.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null);
// Check if the previous sibling is empty after deleting for example: <p><b></b>|</p>
container = selection.getRng().startContainer;
sibling = container.previousSibling;
if (sibling && sibling.nodeType == 1 && !dom.isBlock(sibling) && dom.isEmpty(sibling) && !nonEmptyElements[sibling.nodeName.toLowerCase()]) {
dom.remove(sibling);
}
// Remove the temp element we inserted
dom.remove('__tmp');
}
}
});
}
function removeBlockQuoteOnBackSpace() {
// Add block quote deletion handler
editor.onKeyDown.add(function(editor, e) {
var rng, container, offset, root, parent;
if (e.isDefaultPrevented() || e.keyCode != VK.BACKSPACE) {
return;
}
rng = selection.getRng();
container = rng.startContainer;
offset = rng.startOffset;
root = dom.getRoot();
parent = container;
if (!rng.collapsed || offset !== 0) {
return;
}
while (parent && parent.parentNode && parent.parentNode.firstChild == parent && parent.parentNode != root) {
parent = parent.parentNode;
}
// Is the cursor at the beginning of a blockquote?
if (parent.tagName === 'BLOCKQUOTE') {
// Remove the blockquote
editor.formatter.toggle('blockquote', null, parent);
// Move the caret to the beginning of container
rng.setStart(container, 0);
rng.setEnd(container, 0);
selection.setRng(rng);
selection.collapse(false);
}
});
};
function setGeckoEditingOptions() {
function setOpts() {
editor._refreshContentEditable();
setEditorCommandState("StyleWithCSS", false);
setEditorCommandState("enableInlineTableEditing", false);
if (!settings.object_resizing) {
setEditorCommandState("enableObjectResizing", false);
}
};
if (!settings.readonly) {
editor.onBeforeExecCommand.add(setOpts);
editor.onMouseDown.add(setOpts);
}
};
function addBrAfterLastLinks() {
function fixLinks(editor, o) {
tinymce.each(dom.select('a'), function(node) {
var parentNode = node.parentNode, root = dom.getRoot();
if (parentNode.lastChild === node) {
while (parentNode && !dom.isBlock(parentNode)) {
if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) {
return;
}
parentNode = parentNode.parentNode;
}
dom.add(parentNode, 'br', {'data-mce-bogus' : 1});
}
});
};
editor.onExecCommand.add(function(editor, cmd) {
if (cmd === 'CreateLink') {
fixLinks(editor);
}
});
editor.onSetContent.add(selection.onSetContent.add(fixLinks));
};
function removeGhostSelection() {
function repaint(sender, args) {
if (!sender || !args.initial) {
editor.execCommand('mceRepaint');
}
};
editor.onUndo.add(repaint);
editor.onRedo.add(repaint);
editor.onSetContent.add(repaint);
};
function deleteImageOnBackSpace() {
editor.onKeyDown.add(function(editor, e) {
if (!e.isDefaultPrevented() && e.keyCode == 8 && selection.getNode().nodeName == 'IMG') {
e.preventDefault();
editor.undoManager.beforeChange();
dom.remove(selection.getNode());
editor.undoManager.add();
}
});
};
// All browsers // All browsers
disableBackspaceIntoATable(ed); disableBackspaceIntoATable();
removeBlockQuoteOnBackSpace();
emptyEditorWhenDeleting();
// WebKit // WebKit
if (tinymce.isWebKit) { if (tinymce.isWebKit) {
cleanupStylesWhenDeleting(ed); keepInlineElementOnDeleteBackspace();
emptyEditorWhenDeleting(ed); cleanupStylesWhenDeleting();
inputMethodFocus(ed); inputMethodFocus();
selectControlElements(ed); selectControlElements();
// iOS // iOS
if (tinymce.isIDevice) { if (tinymce.isIDevice) {
selectionChangeNodeChanged(ed); selectionChangeNodeChanged();
} }
} }
// IE // IE
if (tinymce.isIE) { if (tinymce.isIE) {
removeHrOnBackspace(ed); removeHrOnBackspace();
emptyEditorWhenDeleting(ed); ensureBodyHasRoleApplication();
ensureBodyHasRoleApplication(ed); addNewLinesBeforeBrInPre();
//removeStylesOnPTagsInheritedFromHeadingTag(ed) removePreSerializedStylesWhenSelectingControls();
addNewLinesBeforeBrInPre(ed); deleteImageOnBackSpace();
} }
// Gecko // Gecko
if (tinymce.isGecko) { if (tinymce.isGecko) {
removeHrOnBackspace(ed); removeHrOnBackspace();
focusBody(ed); focusBody();
removeStylesWhenDeletingAccrossBlockElements(ed); removeStylesWhenDeletingAccrossBlockElements();
setGeckoEditingOptions();
addBrAfterLastLinks();
removeGhostSelection();
} }
} };
});
})(tinymce);
(function(tinymce) { (function(tinymce) {
var namedEntities, baseEntities, reverseEntities, var namedEntities, baseEntities, reverseEntities,
attrsCharsRegExp = /[&<>\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, attrsCharsRegExp = /[&<>\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
@ -1511,8 +1740,7 @@ tinymce.create('static tinymce.util.XHR', {
'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' +
'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' +
'80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' +
'811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro' '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);
, 32);
tinymce.html = tinymce.html || {}; tinymce.html = tinymce.html || {};
@ -1723,8 +1951,28 @@ tinymce.html.Styles = function(settings, schema) {
str = str.replace(/\\([\'\";:])/g, "$1"); str = str.replace(/\\([\'\";:])/g, "$1");
return str; return str;
};
function processUrl(match, url, url2, url3, str, str2) {
str = str || str2;
if (str) {
str = decode(str);
// Force strings into single quote format
return "'" + str.replace(/\'/g, "\\'") + "'";
} }
url = decode(url || url2 || url3);
// Convert the URL to relative/absolute depending on config
if (urlConverter)
url = urlConverter.call(urlConverterScope, url, 'style');
// Output new URL format
return "url('" + url.replace(/\'/g, "\\'") + "')";
};
if (css) { if (css) {
// Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing // Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing
css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(str) { css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(str) {
@ -1747,26 +1995,7 @@ tinymce.html.Styles = function(settings, schema) {
value = value.replace(rgbRegExp, toHex); value = value.replace(rgbRegExp, toHex);
// Convert URLs and force them into url('value') format // Convert URLs and force them into url('value') format
value = value.replace(urlOrStrRegExp, function(match, url, url2, url3, str, str2) { value = value.replace(urlOrStrRegExp, processUrl);
str = str || str2;
if (str) {
str = decode(str);
// Force strings into single quote format
return "'" + str.replace(/\'/g, "\\'") + "'";
}
url = decode(url || url2 || url3);
// Convert the URL to relative/absolute depending on config
if (urlConverter)
url = urlConverter.call(urlConverterScope, url, 'style');
// Output new URL format
return "url('" + url.replace(/\'/g, "\\'") + "')";
});
styles[name] = isEncoded ? decode(value, true) : value; styles[name] = isEncoded ? decode(value, true) : value;
} }
@ -1934,7 +2163,8 @@ tinymce.html.Styles = function(settings, schema) {
'span[A][B]' + 'span[A][B]' +
'ins[A|cite|datetime][B]' + 'ins[A|cite|datetime][B]' +
'del[A|cite|datetime][B]' + 'del[A|cite|datetime][B]' +
'figure[A][C|legend]' + 'figure[A][C|legend|figcaption]' +
'figcaption[A][C]' +
'img[A|alt|src|height|width|usemap|ismap][]' + 'img[A|alt|src|height|width|usemap|ismap][]' +
'iframe[A|name|src|height|width|sandbox|seamless][]' + 'iframe[A|name|src|height|width|sandbox|seamless][]' +
'embed[A|src|height|width|type][]' + 'embed[A|src|height|width|type][]' +
@ -2161,7 +2391,7 @@ tinymce.html.Styles = function(settings, schema) {
nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object', shortEndedElementsMap); nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object', shortEndedElementsMap);
blockElementsMap = createLookupTable('block_elements', 'h1 h2 h3 h4 h5 h6 hr p div address pre form table tbody thead tfoot ' + blockElementsMap = createLookupTable('block_elements', 'h1 h2 h3 h4 h5 h6 hr p div address pre form table tbody thead tfoot ' +
'th tr td li ol ul caption blockquote center dl dt dd dir fieldset ' + 'th tr td li ol ul caption blockquote center dl dt dd dir fieldset ' +
'noscript menu isindex samp header footer article section hgroup aside nav'); 'noscript menu isindex samp header footer article section hgroup aside nav figure');
// Converts a wildcard expression string to a regexp for example *a will become /.*a/. // Converts a wildcard expression string to a regexp for example *a will become /.*a/.
function patternToRegExp(str) { function patternToRegExp(str) {
@ -2173,7 +2403,7 @@ tinymce.html.Styles = function(settings, schema) {
function addValidElements(valid_elements) { function addValidElements(valid_elements) {
var ei, el, ai, al, yl, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder, var ei, el, ai, al, yl, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder,
prefix, outputName, globalAttributes, globalAttributesOrder, transElement, key, childKey, value, prefix, outputName, globalAttributes, globalAttributesOrder, transElement, key, childKey, value,
elementRuleRegExp = /^([#+-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/, elementRuleRegExp = /^([#+\-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/,
attrRuleRegExp = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/, attrRuleRegExp = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,
hasPatternsRegExp = /[*?+]/; hasPatternsRegExp = /[*?+]/;
@ -2546,6 +2776,47 @@ tinymce.html.Styles = function(settings, schema) {
} }
}; };
function parseAttribute(match, name, value, val2, val3) {
var attrRule, i;
name = name.toLowerCase();
value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute
// Validate name and value
if (validate && !isInternalElement && name.indexOf('data-') !== 0) {
attrRule = validAttributesMap[name];
// Find rule by pattern matching
if (!attrRule && validAttributePatterns) {
i = validAttributePatterns.length;
while (i--) {
attrRule = validAttributePatterns[i];
if (attrRule.pattern.test(name))
break;
}
// No rule matched
if (i === -1)
attrRule = null;
}
// No attribute rule found
if (!attrRule)
return;
// Validate value
if (attrRule.validValues && !(value in attrRule.validValues))
return;
}
// Add attribute to list and map
attrList.map[name] = value;
attrList.push({
name: name,
value: value
});
};
// Precompile RegExps and map objects // Precompile RegExps and map objects
tokenRegExp = new RegExp('<(?:' + tokenRegExp = new RegExp('<(?:' +
'(?:!--([\\w\\W]*?)-->)|' + // Comment '(?:!--([\\w\\W]*?)-->)|' + // Comment
@ -2553,7 +2824,7 @@ tinymce.html.Styles = function(settings, schema) {
'(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE '(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE
'(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI '(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI
'(?:\\/([^>]+)>)|' + // End element '(?:\\/([^>]+)>)|' + // End element
'(?:([A-Za-z0-9\-\:]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element '(?:([A-Za-z0-9\\-\\:]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element
')', 'g'); ')', 'g');
attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g; attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g;
@ -2620,46 +2891,7 @@ tinymce.html.Styles = function(settings, schema) {
attrList = []; attrList = [];
attrList.map = {}; attrList.map = {};
attribsValue.replace(attrRegExp, function(match, name, value, val2, val3) { attribsValue.replace(attrRegExp, parseAttribute);
var attrRule, i;
name = name.toLowerCase();
value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute
// Validate name and value
if (validate && !isInternalElement && name.indexOf('data-') !== 0) {
attrRule = validAttributesMap[name];
// Find rule by pattern matching
if (!attrRule && validAttributePatterns) {
i = validAttributePatterns.length;
while (i--) {
attrRule = validAttributePatterns[i];
if (attrRule.pattern.test(name))
break;
}
// No rule matched
if (i === -1)
attrRule = null;
}
// No attribute rule found
if (!attrRule)
return;
// Validate value
if (attrRule.validValues && !(value in attrRule.validValues))
return;
}
// Add attribute to list and map
attrList.map[name] = value;
attrList.push({
name: name,
value: value
});
});
} else { } else {
attrList = []; attrList = [];
attrList.map = {}; attrList.map = {};
@ -3281,7 +3513,7 @@ tinymce.html.Styles = function(settings, schema) {
self.parse = function(html, args) { self.parse = function(html, args) {
var parser, rootNode, node, nodes, i, l, fi, fl, list, name, validate, var parser, rootNode, node, nodes, i, l, fi, fl, list, name, validate,
blockElements, startWhiteSpaceRegExp, invalidChildren = [], isInWhiteSpacePreservedElement, blockElements, startWhiteSpaceRegExp, invalidChildren = [], isInWhiteSpacePreservedElement,
endWhiteSpaceRegExp, allWhiteSpaceRegExp, whiteSpaceElements, children, nonEmptyElements, rootBlockName; endWhiteSpaceRegExp, allWhiteSpaceRegExp, isAllWhiteSpaceRegExp, whiteSpaceElements, children, nonEmptyElements, rootBlockName;
args = args || {}; args = args || {};
matchedNodes = {}; matchedNodes = {};
@ -3296,6 +3528,7 @@ tinymce.html.Styles = function(settings, schema) {
startWhiteSpaceRegExp = /^[ \t\r\n]+/; startWhiteSpaceRegExp = /^[ \t\r\n]+/;
endWhiteSpaceRegExp = /[ \t\r\n]+$/; endWhiteSpaceRegExp = /[ \t\r\n]+$/;
allWhiteSpaceRegExp = /[ \t\r\n]+/g; allWhiteSpaceRegExp = /[ \t\r\n]+/g;
isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/;
function addRootBlocks() { function addRootBlocks() {
var node = rootNode.firstChild, next, rootBlockNode; var node = rootNode.firstChild, next, rootBlockNode;
@ -3448,10 +3681,12 @@ tinymce.html.Styles = function(settings, schema) {
if (elementRule) { if (elementRule) {
if (blockElements[name]) { if (blockElements[name]) {
if (!isInWhiteSpacePreservedElement) { if (!isInWhiteSpacePreservedElement) {
// Trim whitespace at beginning of block // Trim whitespace of the first node in a block
for (textNode = node.firstChild; textNode && textNode.type === 3; ) { textNode = node.firstChild;
if (textNode && textNode.type === 3) {
text = textNode.value.replace(startWhiteSpaceRegExp, ''); text = textNode.value.replace(startWhiteSpaceRegExp, '');
// Any characters left after trim or should we remove it
if (text.length > 0) { if (text.length > 0) {
textNode.value = text; textNode.value = text;
textNode = textNode.next; textNode = textNode.next;
@ -3460,12 +3695,27 @@ tinymce.html.Styles = function(settings, schema) {
textNode.remove(); textNode.remove();
textNode = sibling; textNode = sibling;
} }
// Remove any pure whitespace siblings
while (textNode && textNode.type === 3) {
text = textNode.value;
sibling = textNode.next;
if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
textNode.remove();
textNode = sibling;
} }
// Trim whitespace at end of block textNode = sibling;
for (textNode = node.lastChild; textNode && textNode.type === 3; ) { }
}
// Trim whitespace of the last node in a block
textNode = node.lastChild;
if (textNode && textNode.type === 3) {
text = textNode.value.replace(endWhiteSpaceRegExp, ''); text = textNode.value.replace(endWhiteSpaceRegExp, '');
// Any characters left after trim or should we remove it
if (text.length > 0) { if (text.length > 0) {
textNode.value = text; textNode.value = text;
textNode = textNode.prev; textNode = textNode.prev;
@ -3474,6 +3724,19 @@ tinymce.html.Styles = function(settings, schema) {
textNode.remove(); textNode.remove();
textNode = sibling; textNode = sibling;
} }
// Remove any pure whitespace siblings
while (textNode && textNode.type === 3) {
text = textNode.value;
sibling = textNode.prev;
if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
textNode.remove();
textNode = sibling;
}
textNode = sibling;
}
} }
} }
@ -3578,8 +3841,8 @@ tinymce.html.Styles = function(settings, schema) {
// these elements and keep br elements that where intended to be there intact // these elements and keep br elements that where intended to be there intact
if (settings.remove_trailing_brs) { if (settings.remove_trailing_brs) {
self.addNodeFilter('br', function(nodes, name) { self.addNodeFilter('br', function(nodes, name) {
var i, l = nodes.length, node, blockElements = schema.getBlockElements(), var i, l = nodes.length, node, blockElements = tinymce.extend({}, schema.getBlockElements()),
nonEmptyElements = schema.getNonEmptyElements(), parent, prev, prevName; nonEmptyElements = schema.getNonEmptyElements(), parent, lastParent, prev, prevName;
// Remove brs from body element as well // Remove brs from body element as well
blockElements.body = 1; blockElements.body = 1;
@ -3590,7 +3853,7 @@ tinymce.html.Styles = function(settings, schema) {
parent = node.parent; parent = node.parent;
if (blockElements[node.parent.name] && node === parent.lastChild) { if (blockElements[node.parent.name] && node === parent.lastChild) {
// Loop all nodes to the right of the current node and check for other BR elements // Loop all nodes to the left of the current node and check for other BR elements
// excluding bookmarks since they are invisible // excluding bookmarks since they are invisible
prev = node.prev; prev = node.prev;
while (prev) { while (prev) {
@ -3628,6 +3891,46 @@ tinymce.html.Styles = function(settings, schema) {
} }
} }
} }
} else {
// Replaces BR elements inside inline elements like <p><b><i><br></i></b></p> so they become <p><b><i>&nbsp;</i></b></p>
lastParent = node;
while (parent.firstChild === lastParent && parent.lastChild === lastParent) {
lastParent = parent;
if (blockElements[parent.name]) {
break;
}
parent = parent.parent;
}
if (lastParent === parent) {
textNode = new tinymce.html.Node('#text', 3);
textNode.value = '\u00a0';
node.replace(textNode);
}
}
}
});
}
// Force anchor names closed, unless the setting "allow_html_in_named_anchor" is explicitly included.
if (!settings.allow_html_in_named_anchor) {
self.addAttributeFilter('name', function(nodes, name) {
var i = nodes.length, sibling, prevSibling, parent, node;
while (i--) {
node = nodes[i];
if (node.name === 'a' && node.firstChild) {
parent = node.parent;
// Move children after current node
sibling = node.lastChild;
do {
prevSibling = sibling.prev;
parent.insert(sibling, node);
sibling = prevSibling;
} while (sibling);
} }
} }
}); });
@ -4314,7 +4617,11 @@ tinymce.dom = {};
return self.bind(target, events instanceof Array ? events.join(' ') : events, func, scope); return self.bind(target, events instanceof Array ? events.join(' ') : events, func, scope);
}; };
self.remove = function(target, events, func) { self.remove = function(target, events, func, scope) {
if (!target) {
return self;
}
// Old API supported direct ID assignment // Old API supported direct ID assignment
if (typeof(target) === "string") { if (typeof(target) === "string") {
target = document.getElementById(target); target = document.getElementById(target);
@ -4322,7 +4629,7 @@ tinymce.dom = {};
// Old API supported multiple targets // Old API supported multiple targets
if (target instanceof Array) { if (target instanceof Array) {
var i = target; var i = target.length;
while (i--) { while (i--) {
self.remove(target[i], events, func, scope); self.remove(target[i], events, func, scope);
@ -4379,6 +4686,46 @@ tinymce.dom = {};
namespace = 0; namespace = 0;
})(tinymce.dom, 'data-mce-expando'); // Namespace and expando })(tinymce.dom, 'data-mce-expando'); // Namespace and expando
tinymce.dom.TreeWalker = function(start_node, root_node) {
var node = start_node;
function findSibling(node, start_name, sibling_name, shallow) {
var sibling, parent;
if (node) {
// Walk into nodes if it has a start
if (!shallow && node[start_name])
return node[start_name];
// Return the sibling if it has one
if (node != root_node) {
sibling = node[sibling_name];
if (sibling)
return sibling;
// Walk up the parents to look for siblings
for (parent = node.parentNode; parent && parent != root_node; parent = parent.parentNode) {
sibling = parent[sibling_name];
if (sibling)
return sibling;
}
}
}
};
this.current = function() {
return node;
};
this.next = function(shallow) {
return (node = findSibling(node, 'firstChild', 'nextSibling', shallow));
};
this.prev = function(shallow) {
return (node = findSibling(node, 'lastChild', 'previousSibling', shallow));
};
};
(function(tinymce) { (function(tinymce) {
// Shorten names // Shorten names
var each = tinymce.each, var each = tinymce.each,
@ -4568,8 +4915,8 @@ tinymce.dom = {};
h = 0; h = 0;
return { return {
w : parseInt(w) || e.offsetWidth || e.clientWidth, w : parseInt(w, 10) || e.offsetWidth || e.clientWidth,
h : parseInt(h) || e.offsetHeight || e.clientHeight h : parseInt(h, 10) || e.offsetHeight || e.clientHeight
}; };
}, },
@ -5093,7 +5440,7 @@ tinymce.dom = {};
if (!u) if (!u)
u = ''; u = '';
head = t.select('head')[0]; head = d.getElementsByTagName('head')[0];
each(u.split(','), function(u) { each(u.split(','), function(u) {
var link; var link;
@ -5369,7 +5716,7 @@ tinymce.dom = {};
var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s); var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);
function hex(s) { function hex(s) {
s = parseInt(s).toString(16); s = parseInt(s, 10).toString(16);
return s.length > 1 ? s : '0' + s; // 0 -> 00 return s.length > 1 ? s : '0' + s; // 0 -> 00
}; };
@ -5622,7 +5969,7 @@ tinymce.dom = {};
// Also keep text nodes with only spaces if surrounded by spans. // Also keep text nodes with only spaces if surrounded by spans.
// eg. "<p><span>a</span> <span>b</span></p>" should keep space between a and b // eg. "<p><span>a</span> <span>b</span></p>" should keep space between a and b
var trimmedLength = tinymce.trim(node.nodeValue).length; var trimmedLength = tinymce.trim(node.nodeValue).length;
if (!t.isBlock(node.parentNode) || trimmedLength > 0 || trimmedLength == 0 && surroundedBySpans(node)) if (!t.isBlock(node.parentNode) || trimmedLength > 0 || trimmedLength === 0 && surroundedBySpans(node))
return; return;
} else if (type == 1) { } else if (type == 1) {
// If the only child is a bookmark then move it up // If the only child is a bookmark then move it up
@ -5683,6 +6030,25 @@ tinymce.dom = {};
return this.events.fire(target, name, evt); return this.events.fire(target, name, evt);
}, },
// Returns the content editable state of a node
getContentEditable: function(node) {
var contentEditable;
// Check type
if (node.nodeType != 1) {
return null;
}
// Check for fake content editable
contentEditable = node.getAttribute("data-mce-contenteditable");
if (contentEditable && contentEditable !== "inherit") {
return contentEditable;
}
// Check for real content editable
return node.contentEditable !== "inherit" ? node.contentEditable : null;
},
_findSib : function(node, selector, name) { _findSib : function(node, selector, name) {
var t = this, f = selector; var t = this, f = selector;
@ -6502,7 +6868,7 @@ tinymce.dom = {};
// We need to walk char by char since rng.text or rng.htmlText will trim line endings // We need to walk char by char since rng.text or rng.htmlText will trim line endings
offset = 0; offset = 0;
while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) { while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) {
if (checkRng.move('character', 1) == 0 || parent != checkRng.parentElement()) { if (checkRng.move('character', 1) === 0 || parent != checkRng.parentElement()) {
break; break;
} }
@ -6515,7 +6881,7 @@ tinymce.dom = {};
// Walk character by character in text node until we hit the selected range endpoint, hit the end of document or parent isn't the right one // Walk character by character in text node until we hit the selected range endpoint, hit the end of document or parent isn't the right one
offset = 0; offset = 0;
while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) { while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) {
if (checkRng.move('character', -1) == 0 || parent != checkRng.parentElement()) { if (checkRng.move('character', -1) === 0 || parent != checkRng.parentElement()) {
break; break;
} }
@ -6681,7 +7047,7 @@ tinymce.dom = {};
var rng = selection.getRng(), start, end, bookmark = {}; var rng = selection.getRng(), start, end, bookmark = {};
function getIndexes(node) { function getIndexes(node) {
var node, parent, root, children, i, indexes = []; var parent, root, children, i, indexes = [];
parent = node.parentNode; parent = node.parentNode;
root = dom.getRoot().parentNode; root = dom.getRoot().parentNode;
@ -6846,13 +7212,18 @@ tinymce.dom = {};
// If single element selection then try making a control selection out of it // If single element selection then try making a control selection out of it
if (startContainer == endContainer && startContainer.nodeType == 1) { if (startContainer == endContainer && startContainer.nodeType == 1) {
// Trick to place the caret inside an empty block element like <p></p> // Trick to place the caret inside an empty block element like <p></p>
if (!startContainer.hasChildNodes()) { if (startOffset == endOffset && !startContainer.hasChildNodes()) {
if (startContainer.canHaveHTML) {
startContainer.innerHTML = '<span>\uFEFF</span><span>\uFEFF</span>'; startContainer.innerHTML = '<span>\uFEFF</span><span>\uFEFF</span>';
ieRng.moveToElementText(startContainer.lastChild); ieRng.moveToElementText(startContainer.lastChild);
ieRng.select(); ieRng.select();
dom.doc.selection.clear(); dom.doc.selection.clear();
startContainer.innerHTML = ''; startContainer.innerHTML = '';
return; return;
} else {
startOffset = dom.nodeIndex(startContainer);
startContainer = startContainer.parentNode;
}
} }
if (startOffset == endOffset - 1) { if (startOffset == endOffset - 1) {
@ -6885,29 +7256,33 @@ tinymce.dom = {};
/* /*
* Sizzle CSS Selector Engine - v1.0 * Sizzle CSS Selector Engine
* Copyright 2009, The Dojo Foundation * Copyright, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses. * Released under the MIT, BSD, and GPL Licenses.
* More information: http://sizzlejs.com/ * More information: http://sizzlejs.com/
*/ */
(function(){ (function(){
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
expando = "sizcache",
done = 0, done = 0,
toString = Object.prototype.toString, toString = Object.prototype.toString,
hasDuplicate = false, hasDuplicate = false,
baseHasDuplicate = true; baseHasDuplicate = true,
rBackslash = /\\/g,
rReturn = /\r\n/g,
rNonWord = /\W/;
// Here we check if the JavaScript engine is using some sort of // Here we check if the JavaScript engine is using some sort of
// optimization where it does not always call our comparision // optimization where it does not always call our comparision
// function. If that is the case, discard the hasDuplicate value. // function. If that is the case, discard the hasDuplicate value.
// Thus far that includes Google Chrome. // Thus far that includes Google Chrome.
[0, 0].sort(function(){ [0, 0].sort(function() {
baseHasDuplicate = false; baseHasDuplicate = false;
return 0; return 0;
}); });
var Sizzle = function(selector, context, results, seed) { var Sizzle = function( selector, context, results, seed ) {
results = results || []; results = results || [];
context = context || document; context = context || document;
@ -6921,13 +7296,16 @@ var Sizzle = function(selector, context, results, seed) {
return results; return results;
} }
var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context), var m, set, checkSet, extra, ret, cur, pop, i,
soFar = selector, ret, cur, pop, i; prune = true,
contextXML = Sizzle.isXML( context ),
parts = [],
soFar = selector;
// Reset the position of the chunker regexp (start from head) // Reset the position of the chunker regexp (start from head)
do { do {
chunker.exec(""); chunker.exec( "" );
m = chunker.exec(soFar); m = chunker.exec( soFar );
if ( m ) { if ( m ) {
soFar = m[3]; soFar = m[3];
@ -6942,8 +7320,10 @@ var Sizzle = function(selector, context, results, seed) {
} while ( m ); } while ( m );
if ( parts.length > 1 && origPOS.exec( selector ) ) { if ( parts.length > 1 && origPOS.exec( selector ) ) {
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
set = posProcess( parts[0] + parts[1], context ); set = posProcess( parts[0] + parts[1], context, seed );
} else { } else {
set = Expr.relative[ parts[0] ] ? set = Expr.relative[ parts[0] ] ?
[ context ] : [ context ] :
@ -6956,26 +7336,34 @@ var Sizzle = function(selector, context, results, seed) {
selector += parts.shift(); selector += parts.shift();
} }
set = posProcess( selector, set ); set = posProcess( selector, set, seed );
} }
} }
} else { } else {
// Take a shortcut and set the context if the root selector is an ID // Take a shortcut and set the context if the root selector is an ID
// (but not if it'll be faster if the inner selector is an ID) // (but not if it'll be faster if the inner selector is an ID)
if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
ret = Sizzle.find( parts.shift(), context, contextXML ); ret = Sizzle.find( parts.shift(), context, contextXML );
context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; context = ret.expr ?
Sizzle.filter( ret.expr, ret.set )[0] :
ret.set[0];
} }
if ( context ) { if ( context ) {
ret = seed ? ret = seed ?
{ expr: parts.pop(), set: makeArray(seed) } : { expr: parts.pop(), set: makeArray(seed) } :
Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
set = ret.expr ?
Sizzle.filter( ret.expr, ret.set ) :
ret.set;
if ( parts.length > 0 ) { if ( parts.length > 0 ) {
checkSet = makeArray(set); checkSet = makeArray( set );
} else { } else {
prune = false; prune = false;
} }
@ -6996,6 +7384,7 @@ var Sizzle = function(selector, context, results, seed) {
Expr.relative[ cur ]( checkSet, pop, contextXML ); Expr.relative[ cur ]( checkSet, pop, contextXML );
} }
} else { } else {
checkSet = parts = []; checkSet = parts = [];
} }
@ -7012,12 +7401,14 @@ var Sizzle = function(selector, context, results, seed) {
if ( toString.call(checkSet) === "[object Array]" ) { if ( toString.call(checkSet) === "[object Array]" ) {
if ( !prune ) { if ( !prune ) {
results.push.apply( results, checkSet ); results.push.apply( results, checkSet );
} else if ( context && context.nodeType === 1 ) { } else if ( context && context.nodeType === 1 ) {
for ( i = 0; checkSet[i] != null; i++ ) { for ( i = 0; checkSet[i] != null; i++ ) {
if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
results.push( set[i] ); results.push( set[i] );
} }
} }
} else { } else {
for ( i = 0; checkSet[i] != null; i++ ) { for ( i = 0; checkSet[i] != null; i++ ) {
if ( checkSet[i] && checkSet[i].nodeType === 1 ) { if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
@ -7025,6 +7416,7 @@ var Sizzle = function(selector, context, results, seed) {
} }
} }
} }
} else { } else {
makeArray( checkSet, results ); makeArray( checkSet, results );
} }
@ -7037,15 +7429,15 @@ var Sizzle = function(selector, context, results, seed) {
return results; return results;
}; };
Sizzle.uniqueSort = function(results){ Sizzle.uniqueSort = function( results ) {
if ( sortOrder ) { if ( sortOrder ) {
hasDuplicate = baseHasDuplicate; hasDuplicate = baseHasDuplicate;
results.sort(sortOrder); results.sort( sortOrder );
if ( hasDuplicate ) { if ( hasDuplicate ) {
for ( var i = 1; i < results.length; i++ ) { for ( var i = 1; i < results.length; i++ ) {
if ( results[i] === results[i-1] ) { if ( results[i] === results[ i - 1 ] ) {
results.splice(i--, 1); results.splice( i--, 1 );
} }
} }
} }
@ -7054,27 +7446,32 @@ Sizzle.uniqueSort = function(results){
return results; return results;
}; };
Sizzle.matches = function(expr, set){ Sizzle.matches = function( expr, set ) {
return Sizzle(expr, null, null, set); return Sizzle( expr, null, null, set );
}; };
Sizzle.find = function(expr, context, isXML){ Sizzle.matchesSelector = function( node, expr ) {
var set; return Sizzle( expr, null, null, [node] ).length > 0;
};
Sizzle.find = function( expr, context, isXML ) {
var set, i, len, match, type, left;
if ( !expr ) { if ( !expr ) {
return []; return [];
} }
for ( var i = 0, l = Expr.order.length; i < l; i++ ) { for ( i = 0, len = Expr.order.length; i < len; i++ ) {
var type = Expr.order[i], match; type = Expr.order[i];
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
var left = match[1]; left = match[1];
match.splice(1,1); match.splice( 1, 1 );
if ( left.substr( left.length - 1 ) !== "\\" ) { if ( left.substr( left.length - 1 ) !== "\\" ) {
match[1] = (match[1] || "").replace(/\\/g, ""); match[1] = (match[1] || "").replace( rBackslash, "" );
set = Expr.find[ type ]( match, context, isXML ); set = Expr.find[ type ]( match, context, isXML );
if ( set != null ) { if ( set != null ) {
expr = expr.replace( Expr.match[ type ], "" ); expr = expr.replace( Expr.match[ type ], "" );
break; break;
@ -7084,20 +7481,29 @@ Sizzle.find = function(expr, context, isXML){
} }
if ( !set ) { if ( !set ) {
set = context.getElementsByTagName("*"); set = typeof context.getElementsByTagName !== "undefined" ?
context.getElementsByTagName( "*" ) :
[];
} }
return {set: set, expr: expr}; return { set: set, expr: expr };
}; };
Sizzle.filter = function(expr, set, inplace, not){ Sizzle.filter = function( expr, set, inplace, not ) {
var old = expr, result = [], curLoop = set, match, anyFound, var match, anyFound,
isXMLFilter = set && set[0] && Sizzle.isXML(set[0]); type, found, item, filter, left,
i, pass,
old = expr,
result = [],
curLoop = set,
isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
while ( expr && set.length ) { while ( expr && set.length ) {
for ( var type in Expr.filter ) { for ( type in Expr.filter ) {
if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
var filter = Expr.filter[ type ], found, item, left = match[1]; filter = Expr.filter[ type ];
left = match[1];
anyFound = false; anyFound = false;
match.splice(1,1); match.splice(1,1);
@ -7115,23 +7521,26 @@ Sizzle.filter = function(expr, set, inplace, not){
if ( !match ) { if ( !match ) {
anyFound = found = true; anyFound = found = true;
} else if ( match === true ) { } else if ( match === true ) {
continue; continue;
} }
} }
if ( match ) { if ( match ) {
for ( var i = 0; (item = curLoop[i]) != null; i++ ) { for ( i = 0; (item = curLoop[i]) != null; i++ ) {
if ( item ) { if ( item ) {
found = filter( item, match, i, curLoop ); found = filter( item, match, i, curLoop );
var pass = not ^ !!found; pass = not ^ found;
if ( inplace && found != null ) { if ( inplace && found != null ) {
if ( pass ) { if ( pass ) {
anyFound = true; anyFound = true;
} else { } else {
curLoop[i] = false; curLoop[i] = false;
} }
} else if ( pass ) { } else if ( pass ) {
result.push( item ); result.push( item );
anyFound = true; anyFound = true;
@ -7160,6 +7569,7 @@ Sizzle.filter = function(expr, set, inplace, not){
if ( expr === old ) { if ( expr === old ) {
if ( anyFound == null ) { if ( anyFound == null ) {
Sizzle.error( expr ); Sizzle.error( expr );
} else { } else {
break; break;
} }
@ -7172,35 +7582,78 @@ Sizzle.filter = function(expr, set, inplace, not){
}; };
Sizzle.error = function( msg ) { Sizzle.error = function( msg ) {
throw "Syntax error, unrecognized expression: " + msg; throw new Error( "Syntax error, unrecognized expression: " + msg );
};
var getText = Sizzle.getText = function( elem ) {
var i, node,
nodeType = elem.nodeType,
ret = "";
if ( nodeType ) {
if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
// Use textContent || innerText for elements
if ( typeof elem.textContent === 'string' ) {
return elem.textContent;
} else if ( typeof elem.innerText === 'string' ) {
// Replace IE's carriage returns
return elem.innerText.replace( rReturn, '' );
} else {
// Traverse it's children
for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
ret += getText( elem );
}
}
} else if ( nodeType === 3 || nodeType === 4 ) {
return elem.nodeValue;
}
} else {
// If no nodeType, this is expected to be an array
for ( i = 0; (node = elem[i]); i++ ) {
// Do not traverse comment nodes
if ( node.nodeType !== 8 ) {
ret += getText( node );
}
}
}
return ret;
}; };
var Expr = Sizzle.selectors = { var Expr = Sizzle.selectors = {
order: [ "ID", "NAME", "TAG" ], order: [ "ID", "NAME", "TAG" ],
match: { match: {
ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/, CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
}, },
leftMatch: {}, leftMatch: {},
attrMap: { attrMap: {
"class": "className", "class": "className",
"for": "htmlFor" "for": "htmlFor"
}, },
attrHandle: { attrHandle: {
href: function(elem){ href: function( elem ) {
return elem.getAttribute("href"); return elem.getAttribute( "href" );
},
type: function( elem ) {
return elem.getAttribute( "type" );
} }
}, },
relative: { relative: {
"+": function(checkSet, part){ "+": function(checkSet, part){
var isPartStr = typeof part === "string", var isPartStr = typeof part === "string",
isTag = isPartStr && !/\W/.test(part), isTag = isPartStr && !rNonWord.test( part ),
isPartStrNotTag = isPartStr && !isTag; isPartStrNotTag = isPartStr && !isTag;
if ( isTag ) { if ( isTag ) {
@ -7221,23 +7674,29 @@ var Expr = Sizzle.selectors = {
Sizzle.filter( part, checkSet, true ); Sizzle.filter( part, checkSet, true );
} }
}, },
">": function(checkSet, part){
var isPartStr = typeof part === "string",
elem, i = 0, l = checkSet.length;
if ( isPartStr && !/\W/.test(part) ) { ">": function( checkSet, part ) {
var elem,
isPartStr = typeof part === "string",
i = 0,
l = checkSet.length;
if ( isPartStr && !rNonWord.test( part ) ) {
part = part.toLowerCase(); part = part.toLowerCase();
for ( ; i < l; i++ ) { for ( ; i < l; i++ ) {
elem = checkSet[i]; elem = checkSet[i];
if ( elem ) { if ( elem ) {
var parent = elem.parentNode; var parent = elem.parentNode;
checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
} }
} }
} else { } else {
for ( ; i < l; i++ ) { for ( ; i < l; i++ ) {
elem = checkSet[i]; elem = checkSet[i];
if ( elem ) { if ( elem ) {
checkSet[i] = isPartStr ? checkSet[i] = isPartStr ?
elem.parentNode : elem.parentNode :
@ -7250,39 +7709,50 @@ var Expr = Sizzle.selectors = {
} }
} }
}, },
"": function(checkSet, part, isXML){ "": function(checkSet, part, isXML){
var doneName = done++, checkFn = dirCheck, nodeCheck; var nodeCheck,
doneName = done++,
checkFn = dirCheck;
if ( typeof part === "string" && !/\W/.test(part) ) { if ( typeof part === "string" && !rNonWord.test( part ) ) {
part = part.toLowerCase(); part = part.toLowerCase();
nodeCheck = part; nodeCheck = part;
checkFn = dirNodeCheck; checkFn = dirNodeCheck;
} }
checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
}, },
"~": function(checkSet, part, isXML){
var doneName = done++, checkFn = dirCheck, nodeCheck;
if ( typeof part === "string" && !/\W/.test(part) ) { "~": function( checkSet, part, isXML ) {
var nodeCheck,
doneName = done++,
checkFn = dirCheck;
if ( typeof part === "string" && !rNonWord.test( part ) ) {
part = part.toLowerCase(); part = part.toLowerCase();
nodeCheck = part; nodeCheck = part;
checkFn = dirNodeCheck; checkFn = dirNodeCheck;
} }
checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
} }
}, },
find: { find: {
ID: function(match, context, isXML){ ID: function( match, context, isXML ) {
if ( typeof context.getElementById !== "undefined" && !isXML ) { if ( typeof context.getElementById !== "undefined" && !isXML ) {
var m = context.getElementById(match[1]); var m = context.getElementById(match[1]);
return m ? [m] : []; // Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
return m && m.parentNode ? [m] : [];
} }
}, },
NAME: function(match, context){
NAME: function( match, context ) {
if ( typeof context.getElementsByName !== "undefined" ) { if ( typeof context.getElementsByName !== "undefined" ) {
var ret = [], results = context.getElementsByName(match[1]); var ret = [],
results = context.getElementsByName( match[1] );
for ( var i = 0, l = results.length; i < l; i++ ) { for ( var i = 0, l = results.length; i < l; i++ ) {
if ( results[i].getAttribute("name") === match[1] ) { if ( results[i].getAttribute("name") === match[1] ) {
@ -7293,13 +7763,16 @@ var Expr = Sizzle.selectors = {
return ret.length === 0 ? null : ret; return ret.length === 0 ? null : ret;
} }
}, },
TAG: function(match, context){
return context.getElementsByTagName(match[1]); TAG: function( match, context ) {
if ( typeof context.getElementsByTagName !== "undefined" ) {
return context.getElementsByTagName( match[1] );
}
} }
}, },
preFilter: { preFilter: {
CLASS: function(match, curLoop, inplace, result, not, isXML){ CLASS: function( match, curLoop, inplace, result, not, isXML ) {
match = " " + match[1].replace(/\\/g, "") + " "; match = " " + match[1].replace( rBackslash, "" ) + " ";
if ( isXML ) { if ( isXML ) {
return match; return match;
@ -7307,10 +7780,11 @@ var Expr = Sizzle.selectors = {
for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
if ( elem ) { if ( elem ) {
if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) { if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
if ( !inplace ) { if ( !inplace ) {
result.push( elem ); result.push( elem );
} }
} else if ( inplace ) { } else if ( inplace ) {
curLoop[i] = false; curLoop[i] = false;
} }
@ -7319,16 +7793,25 @@ var Expr = Sizzle.selectors = {
return false; return false;
}, },
ID: function(match){
return match[1].replace(/\\/g, ""); ID: function( match ) {
return match[1].replace( rBackslash, "" );
}, },
TAG: function(match, curLoop){
return match[1].toLowerCase(); TAG: function( match, curLoop ) {
return match[1].replace( rBackslash, "" ).toLowerCase();
}, },
CHILD: function(match){
CHILD: function( match ) {
if ( match[1] === "nth" ) { if ( match[1] === "nth" ) {
if ( !match[2] ) {
Sizzle.error( match[0] );
}
match[2] = match[2].replace(/^\+|\s*/g, '');
// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
@ -7336,141 +7819,196 @@ var Expr = Sizzle.selectors = {
match[2] = (test[1] + (test[2] || 1)) - 0; match[2] = (test[1] + (test[2] || 1)) - 0;
match[3] = test[3] - 0; match[3] = test[3] - 0;
} }
else if ( match[2] ) {
Sizzle.error( match[0] );
}
// TODO: Move to normal caching system // TODO: Move to normal caching system
match[0] = done++; match[0] = done++;
return match; return match;
}, },
ATTR: function(match, curLoop, inplace, result, not, isXML){
var name = match[1].replace(/\\/g, ""); ATTR: function( match, curLoop, inplace, result, not, isXML ) {
var name = match[1] = match[1].replace( rBackslash, "" );
if ( !isXML && Expr.attrMap[name] ) { if ( !isXML && Expr.attrMap[name] ) {
match[1] = Expr.attrMap[name]; match[1] = Expr.attrMap[name];
} }
// Handle if an un-quoted value was used
match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
if ( match[2] === "~=" ) { if ( match[2] === "~=" ) {
match[4] = " " + match[4] + " "; match[4] = " " + match[4] + " ";
} }
return match; return match;
}, },
PSEUDO: function(match, curLoop, inplace, result, not){
PSEUDO: function( match, curLoop, inplace, result, not ) {
if ( match[1] === "not" ) { if ( match[1] === "not" ) {
// If we're dealing with a complex expression, or a simple one // If we're dealing with a complex expression, or a simple one
if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
match[3] = Sizzle(match[3], null, null, curLoop); match[3] = Sizzle(match[3], null, null, curLoop);
} else { } else {
var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
if ( !inplace ) { if ( !inplace ) {
result.push.apply( result, ret ); result.push.apply( result, ret );
} }
return false; return false;
} }
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true; return true;
} }
return match; return match;
}, },
POS: function(match){
POS: function( match ) {
match.unshift( true ); match.unshift( true );
return match; return match;
} }
}, },
filters: { filters: {
enabled: function(elem){ enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden"; return elem.disabled === false && elem.type !== "hidden";
}, },
disabled: function(elem){
disabled: function( elem ) {
return elem.disabled === true; return elem.disabled === true;
}, },
checked: function(elem){
checked: function( elem ) {
return elem.checked === true; return elem.checked === true;
}, },
selected: function(elem){
selected: function( elem ) {
// Accessing this property makes selected-by-default // Accessing this property makes selected-by-default
// options in Safari work properly // options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex; elem.parentNode.selectedIndex;
}
return elem.selected === true; return elem.selected === true;
}, },
parent: function(elem){
parent: function( elem ) {
return !!elem.firstChild; return !!elem.firstChild;
}, },
empty: function(elem){
empty: function( elem ) {
return !elem.firstChild; return !elem.firstChild;
}, },
has: function(elem, i, match){
has: function( elem, i, match ) {
return !!Sizzle( match[3], elem ).length; return !!Sizzle( match[3], elem ).length;
}, },
header: function(elem){
header: function( elem ) {
return (/h\d/i).test( elem.nodeName ); return (/h\d/i).test( elem.nodeName );
}, },
text: function(elem){
return "text" === elem.type; text: function( elem ) {
var attr = elem.getAttribute( "type" ), type = elem.type;
// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
// use getAttribute instead to test this case
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
}, },
radio: function(elem){
return "radio" === elem.type; radio: function( elem ) {
return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
}, },
checkbox: function(elem){
return "checkbox" === elem.type; checkbox: function( elem ) {
return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
}, },
file: function(elem){
return "file" === elem.type; file: function( elem ) {
return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
}, },
password: function(elem){
return "password" === elem.type; password: function( elem ) {
return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
}, },
submit: function(elem){
return "submit" === elem.type; submit: function( elem ) {
var name = elem.nodeName.toLowerCase();
return (name === "input" || name === "button") && "submit" === elem.type;
}, },
image: function(elem){
return "image" === elem.type; image: function( elem ) {
return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
}, },
reset: function(elem){
return "reset" === elem.type; reset: function( elem ) {
var name = elem.nodeName.toLowerCase();
return (name === "input" || name === "button") && "reset" === elem.type;
}, },
button: function(elem){
return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; button: function( elem ) {
var name = elem.nodeName.toLowerCase();
return name === "input" && "button" === elem.type || name === "button";
}, },
input: function(elem){
return (/input|select|textarea|button/i).test(elem.nodeName); input: function( elem ) {
return (/input|select|textarea|button/i).test( elem.nodeName );
},
focus: function( elem ) {
return elem === elem.ownerDocument.activeElement;
} }
}, },
setFilters: { setFilters: {
first: function(elem, i){ first: function( elem, i ) {
return i === 0; return i === 0;
}, },
last: function(elem, i, match, array){
last: function( elem, i, match, array ) {
return i === array.length - 1; return i === array.length - 1;
}, },
even: function(elem, i){
even: function( elem, i ) {
return i % 2 === 0; return i % 2 === 0;
}, },
odd: function(elem, i){
odd: function( elem, i ) {
return i % 2 === 1; return i % 2 === 1;
}, },
lt: function(elem, i, match){
lt: function( elem, i, match ) {
return i < match[3] - 0; return i < match[3] - 0;
}, },
gt: function(elem, i, match){
gt: function( elem, i, match ) {
return i > match[3] - 0; return i > match[3] - 0;
}, },
nth: function(elem, i, match){
nth: function( elem, i, match ) {
return match[3] - 0 === i; return match[3] - 0 === i;
}, },
eq: function(elem, i, match){
eq: function( elem, i, match ) {
return match[3] - 0 === i; return match[3] - 0 === i;
} }
}, },
filter: { filter: {
PSEUDO: function(elem, match, i, array){ PSEUDO: function( elem, match, i, array ) {
var name = match[1], filter = Expr.filters[ name ]; var name = match[1],
filter = Expr.filters[ name ];
if ( filter ) { if ( filter ) {
return filter( elem, i, match, array ); return filter( elem, i, match, array );
} else if ( name === "contains" ) { } else if ( name === "contains" ) {
return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
} else if ( name === "not" ) { } else if ( name === "not" ) {
var not = match[3]; var not = match[3];
@ -7481,72 +8019,96 @@ var Expr = Sizzle.selectors = {
} }
return true; return true;
} else { } else {
Sizzle.error( "Syntax error, unrecognized expression: " + name ); Sizzle.error( name );
} }
}, },
CHILD: function(elem, match){
var type = match[1], node = elem; CHILD: function( elem, match ) {
switch (type) { var first, last,
case 'only': doneName, parent, cache,
case 'first': count, diff,
type = match[1],
node = elem;
switch ( type ) {
case "only":
case "first":
while ( (node = node.previousSibling) ) { while ( (node = node.previousSibling) ) {
if ( node.nodeType === 1 ) { if ( node.nodeType === 1 ) {
return false; return false;
} }
} }
if ( type === "first" ) { if ( type === "first" ) {
return true; return true;
} }
node = elem; node = elem;
case 'last':
/* falls through */
case "last":
while ( (node = node.nextSibling) ) { while ( (node = node.nextSibling) ) {
if ( node.nodeType === 1 ) { if ( node.nodeType === 1 ) {
return false; return false;
} }
} }
return true; return true;
case 'nth':
var first = match[2], last = match[3]; case "nth":
first = match[2];
last = match[3];
if ( first === 1 && last === 0 ) { if ( first === 1 && last === 0 ) {
return true; return true;
} }
var doneName = match[0], doneName = match[0];
parent = elem.parentNode; parent = elem.parentNode;
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
var count = 0; count = 0;
for ( node = parent.firstChild; node; node = node.nextSibling ) { for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) { if ( node.nodeType === 1 ) {
node.nodeIndex = ++count; node.nodeIndex = ++count;
} }
} }
parent.sizcache = doneName;
parent[ expando ] = doneName;
} }
var diff = elem.nodeIndex - last; diff = elem.nodeIndex - last;
if ( first === 0 ) { if ( first === 0 ) {
return diff === 0; return diff === 0;
} else { } else {
return ( diff % first === 0 && diff / first >= 0 ); return ( diff % first === 0 && diff / first >= 0 );
} }
} }
}, },
ID: function(elem, match){
ID: function( elem, match ) {
return elem.nodeType === 1 && elem.getAttribute("id") === match; return elem.nodeType === 1 && elem.getAttribute("id") === match;
}, },
TAG: function(elem, match){
return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; TAG: function( elem, match ) {
return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
}, },
CLASS: function(elem, match){
CLASS: function( elem, match ) {
return (" " + (elem.className || elem.getAttribute("class")) + " ") return (" " + (elem.className || elem.getAttribute("class")) + " ")
.indexOf( match ) > -1; .indexOf( match ) > -1;
}, },
ATTR: function(elem, match){
ATTR: function( elem, match ) {
var name = match[1], var name = match[1],
result = Expr.attrHandle[ name ] ? result = Sizzle.attr ?
Sizzle.attr( elem, name ) :
Expr.attrHandle[ name ] ?
Expr.attrHandle[ name ]( elem ) : Expr.attrHandle[ name ]( elem ) :
elem[ name ] != null ? elem[ name ] != null ?
elem[ name ] : elem[ name ] :
@ -7557,6 +8119,8 @@ var Expr = Sizzle.selectors = {
return result == null ? return result == null ?
type === "!=" : type === "!=" :
!type && Sizzle.attr ?
result != null :
type === "=" ? type === "=" ?
value === check : value === check :
type === "*=" ? type === "*=" ?
@ -7575,8 +8139,10 @@ var Expr = Sizzle.selectors = {
value === check || value.substr(0, check.length + 1) === check + "-" : value === check || value.substr(0, check.length + 1) === check + "-" :
false; false;
}, },
POS: function(elem, match, i, array){
var name = match[2], filter = Expr.setFilters[ name ]; POS: function( elem, match, i, array ) {
var name = match[2],
filter = Expr.setFilters[ name ];
if ( filter ) { if ( filter ) {
return filter( elem, i, match, array ); return filter( elem, i, match, array );
@ -7594,8 +8160,11 @@ for ( var type in Expr.match ) {
Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
} }
// Expose origPOS
// "global" as in regardless of relation to brackets/parens
Expr.match.globalPOS = origPOS;
var makeArray = function(array, results) { var makeArray = function( array, results ) {
array = Array.prototype.slice.call( array, 0 ); array = Array.prototype.slice.call( array, 0 );
if ( results ) { if ( results ) {
@ -7614,17 +8183,20 @@ try {
Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
// Provide a fallback method if it does not work // Provide a fallback method if it does not work
} catch(e){ } catch( e ) {
makeArray = function(array, results) { makeArray = function( array, results ) {
var ret = results || [], i = 0; var i = 0,
ret = results || [];
if ( toString.call(array) === "[object Array]" ) { if ( toString.call(array) === "[object Array]" ) {
Array.prototype.push.apply( ret, array ); Array.prototype.push.apply( ret, array );
} else { } else {
if ( typeof array.length === "number" ) { if ( typeof array.length === "number" ) {
for ( var l = array.length; i < l; i++ ) { for ( var l = array.length; i < l; i++ ) {
ret.push( array[i] ); ret.push( array[i] );
} }
} else { } else {
for ( ; array[i]; i++ ) { for ( ; array[i]; i++ ) {
ret.push( array[i] ); ret.push( array[i] );
@ -7636,110 +8208,141 @@ try {
}; };
} }
var sortOrder; var sortOrder, siblingCheck;
if ( document.documentElement.compareDocumentPosition ) { if ( document.documentElement.compareDocumentPosition ) {
sortOrder = function( a, b ) { sortOrder = function( a, b ) {
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { if ( a === b ) {
if ( a == b ) {
hasDuplicate = true; hasDuplicate = true;
return 0;
} }
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
return a.compareDocumentPosition ? -1 : 1; return a.compareDocumentPosition ? -1 : 1;
} }
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; return a.compareDocumentPosition(b) & 4 ? -1 : 1;
if ( ret === 0 ) {
hasDuplicate = true;
}
return ret;
}; };
} else if ( "sourceIndex" in document.documentElement ) {
} else {
sortOrder = function( a, b ) { sortOrder = function( a, b ) {
if ( !a.sourceIndex || !b.sourceIndex ) { // The nodes are identical, we can exit early
if ( a == b ) { if ( a === b ) {
hasDuplicate = true; hasDuplicate = true;
} return 0;
return a.sourceIndex ? -1 : 1;
// Fallback to using sourceIndex (in IE) if it's available on both nodes
} else if ( a.sourceIndex && b.sourceIndex ) {
return a.sourceIndex - b.sourceIndex;
} }
var ret = a.sourceIndex - b.sourceIndex; var al, bl,
if ( ret === 0 ) { ap = [],
hasDuplicate = true; bp = [],
} aup = a.parentNode,
return ret; bup = b.parentNode,
}; cur = aup;
} else if ( document.createRange ) {
sortOrder = function( a, b ) { // If the nodes are siblings (or identical) we can do a quick check
if ( !a.ownerDocument || !b.ownerDocument ) { if ( aup === bup ) {
if ( a == b ) { return siblingCheck( a, b );
hasDuplicate = true;
} // If no parents were found then the nodes are disconnected
return a.ownerDocument ? -1 : 1; } else if ( !aup ) {
return -1;
} else if ( !bup ) {
return 1;
} }
var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); // Otherwise they're somewhere else in the tree so we need
aRange.setStart(a, 0); // to build up a full list of the parentNodes for comparison
aRange.setEnd(a, 0); while ( cur ) {
bRange.setStart(b, 0); ap.unshift( cur );
bRange.setEnd(b, 0); cur = cur.parentNode;
var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
if ( ret === 0 ) {
hasDuplicate = true;
} }
cur = bup;
while ( cur ) {
bp.unshift( cur );
cur = cur.parentNode;
}
al = ap.length;
bl = bp.length;
// Start walking down the tree looking for a discrepancy
for ( var i = 0; i < al && i < bl; i++ ) {
if ( ap[i] !== bp[i] ) {
return siblingCheck( ap[i], bp[i] );
}
}
// We ended someplace up the tree so do a sibling check
return i === al ?
siblingCheck( a, bp[i], -1 ) :
siblingCheck( ap[i], b, 1 );
};
siblingCheck = function( a, b, ret ) {
if ( a === b ) {
return ret; return ret;
}
var cur = a.nextSibling;
while ( cur ) {
if ( cur === b ) {
return -1;
}
cur = cur.nextSibling;
}
return 1;
}; };
} }
// Utility function for retreiving the text value of an array of DOM nodes
Sizzle.getText = function( elems ) {
var ret = "", elem;
for ( var i = 0; elems[i]; i++ ) {
elem = elems[i];
// Get the text from text nodes and CDATA nodes
if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
ret += elem.nodeValue;
// Traverse everything else, except comment nodes
} else if ( elem.nodeType !== 8 ) {
ret += Sizzle.getText( elem.childNodes );
}
}
return ret;
};
// Check to see if the browser returns elements by name when // Check to see if the browser returns elements by name when
// querying by getElementById (and provide a workaround) // querying by getElementById (and provide a workaround)
(function(){ (function(){
// We're going to inject a fake input element with a specified name // We're going to inject a fake input element with a specified name
var form = document.createElement("div"), var form = document.createElement("div"),
id = "script" + (new Date()).getTime(); id = "script" + (new Date()).getTime(),
root = document.documentElement;
form.innerHTML = "<a name='" + id + "'/>"; form.innerHTML = "<a name='" + id + "'/>";
// Inject it into the root element, check its status, and remove it quickly // Inject it into the root element, check its status, and remove it quickly
var root = document.documentElement;
root.insertBefore( form, root.firstChild ); root.insertBefore( form, root.firstChild );
// The workaround has to do additional checks after a getElementById // The workaround has to do additional checks after a getElementById
// Which slows things down for other browsers (hence the branching) // Which slows things down for other browsers (hence the branching)
if ( document.getElementById( id ) ) { if ( document.getElementById( id ) ) {
Expr.find.ID = function(match, context, isXML){ Expr.find.ID = function( match, context, isXML ) {
if ( typeof context.getElementById !== "undefined" && !isXML ) { if ( typeof context.getElementById !== "undefined" && !isXML ) {
var m = context.getElementById(match[1]); var m = context.getElementById(match[1]);
return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
return m ?
m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
[m] :
undefined :
[];
} }
}; };
Expr.filter.ID = function(elem, match){ Expr.filter.ID = function( elem, match ) {
var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
return elem.nodeType === 1 && node && node.nodeValue === match; return elem.nodeType === 1 && node && node.nodeValue === match;
}; };
} }
root.removeChild( form ); root.removeChild( form );
root = form = null; // release memory in IE
// release memory in IE
root = form = null;
})(); })();
(function(){ (function(){
@ -7752,8 +8355,8 @@ Sizzle.getText = function( elems ) {
// Make sure no comments are found // Make sure no comments are found
if ( div.getElementsByTagName("*").length > 0 ) { if ( div.getElementsByTagName("*").length > 0 ) {
Expr.find.TAG = function(match, context){ Expr.find.TAG = function( match, context ) {
var results = context.getElementsByTagName(match[1]); var results = context.getElementsByTagName( match[1] );
// Filter out possible comments // Filter out possible comments
if ( match[1] === "*" ) { if ( match[1] === "*" ) {
@ -7774,19 +8377,25 @@ Sizzle.getText = function( elems ) {
// Check to see if an attribute returns normalized href attributes // Check to see if an attribute returns normalized href attributes
div.innerHTML = "<a href='#'></a>"; div.innerHTML = "<a href='#'></a>";
if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
div.firstChild.getAttribute("href") !== "#" ) { div.firstChild.getAttribute("href") !== "#" ) {
Expr.attrHandle.href = function(elem){
return elem.getAttribute("href", 2); Expr.attrHandle.href = function( elem ) {
return elem.getAttribute( "href", 2 );
}; };
} }
div = null; // release memory in IE // release memory in IE
div = null;
})(); })();
if ( document.querySelectorAll ) { if ( document.querySelectorAll ) {
(function(){ (function(){
var oldSizzle = Sizzle, div = document.createElement("div"); var oldSizzle = Sizzle,
div = document.createElement("div"),
id = "__sizzle__";
div.innerHTML = "<p class='TEST'></p>"; div.innerHTML = "<p class='TEST'></p>";
// Safari can't handle uppercase or unicode characters when // Safari can't handle uppercase or unicode characters when
@ -7795,15 +8404,86 @@ if ( document.querySelectorAll ) {
return; return;
} }
Sizzle = function(query, context, extra, seed){ Sizzle = function( query, context, extra, seed ) {
context = context || document; context = context || document;
// Only use querySelectorAll on non-XML documents // Only use querySelectorAll on non-XML documents
// (ID selectors don't work in non-HTML documents) // (ID selectors don't work in non-HTML documents)
if ( !seed && context.nodeType === 9 && !Sizzle.isXML(context) ) { if ( !seed && !Sizzle.isXML(context) ) {
// See if we find a selector to speed up
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
// Speed-up: Sizzle("TAG")
if ( match[1] ) {
return makeArray( context.getElementsByTagName( query ), extra );
// Speed-up: Sizzle(".CLASS")
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
return makeArray( context.getElementsByClassName( match[2] ), extra );
}
}
if ( context.nodeType === 9 ) {
// Speed-up: Sizzle("body")
// The body element only exists once, optimize finding it
if ( query === "body" && context.body ) {
return makeArray( [ context.body ], extra );
// Speed-up: Sizzle("#ID")
} else if ( match && match[3] ) {
var elem = context.getElementById( match[3] );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
if ( elem && elem.parentNode ) {
// Handle the case where IE and Opera return items
// by name instead of ID
if ( elem.id === match[3] ) {
return makeArray( [ elem ], extra );
}
} else {
return makeArray( [], extra );
}
}
try { try {
return makeArray( context.querySelectorAll(query), extra ); return makeArray( context.querySelectorAll(query), extra );
} catch(e){} } catch(qsaError) {}
// qSA works strangely on Element-rooted queries
// We can work around this by specifying an extra ID on the root
// and working up from there (Thanks to Andrew Dupont for the technique)
// IE 8 doesn't work on object elements
} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
var oldContext = context,
old = context.getAttribute( "id" ),
nid = old || id,
hasParent = context.parentNode,
relativeHierarchySelector = /^\s*[+~]/.test( query );
if ( !old ) {
context.setAttribute( "id", nid );
} else {
nid = nid.replace( /'/g, "\\$&" );
}
if ( relativeHierarchySelector && hasParent ) {
context = context.parentNode;
}
try {
if ( !relativeHierarchySelector || hasParent ) {
return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
}
} catch(pseudoError) {
} finally {
if ( !old ) {
oldContext.removeAttribute( "id" );
}
}
}
} }
return oldSizzle(query, context, extra, seed); return oldSizzle(query, context, extra, seed);
@ -7813,10 +8493,55 @@ if ( document.querySelectorAll ) {
Sizzle[ prop ] = oldSizzle[ prop ]; Sizzle[ prop ] = oldSizzle[ prop ];
} }
div = null; // release memory in IE // release memory in IE
div = null;
})(); })();
} }
(function(){
var html = document.documentElement,
matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
if ( matches ) {
// Check to see if it's possible to do matchesSelector
// on a disconnected node (IE 9 fails this)
var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
pseudoWorks = false;
try {
// This should fail with an exception
// Gecko does not error, returns false instead
matches.call( document.documentElement, "[test!='']:sizzle" );
} catch( pseudoError ) {
pseudoWorks = true;
}
Sizzle.matchesSelector = function( node, expr ) {
// Make sure that attribute selectors are quoted
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
if ( !Sizzle.isXML( node ) ) {
try {
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
var ret = matches.call( node, expr );
// IE 9's matchesSelector returns false on disconnected nodes
if ( ret || !disconnectedMatch ||
// As well, disconnected nodes are said to be in a document
// fragment in IE 9, so check for that
node.document && node.document.nodeType !== 11 ) {
return ret;
}
}
} catch(e) {}
}
return Sizzle(expr, null, null, [node]).length > 0;
};
}
})();
(function(){ (function(){
var div = document.createElement("div"); var div = document.createElement("div");
@ -7836,30 +8561,33 @@ if ( document.querySelectorAll ) {
} }
Expr.order.splice(1, 0, "CLASS"); Expr.order.splice(1, 0, "CLASS");
Expr.find.CLASS = function(match, context, isXML) { Expr.find.CLASS = function( match, context, isXML ) {
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
return context.getElementsByClassName(match[1]); return context.getElementsByClassName(match[1]);
} }
}; };
div = null; // release memory in IE // release memory in IE
div = null;
})(); })();
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
for ( var i = 0, l = checkSet.length; i < l; i++ ) { for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i]; var elem = checkSet[i];
if ( elem ) { if ( elem ) {
elem = elem[dir];
var match = false; var match = false;
elem = elem[dir];
while ( elem ) { while ( elem ) {
if ( elem.sizcache === doneName ) { if ( elem[ expando ] === doneName ) {
match = checkSet[elem.sizset]; match = checkSet[elem.sizset];
break; break;
} }
if ( elem.nodeType === 1 && !isXML ){ if ( elem.nodeType === 1 && !isXML ){
elem.sizcache = doneName; elem[ expando ] = doneName;
elem.sizset = i; elem.sizset = i;
} }
@ -7879,21 +8607,24 @@ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
for ( var i = 0, l = checkSet.length; i < l; i++ ) { for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i]; var elem = checkSet[i];
if ( elem ) { if ( elem ) {
elem = elem[dir];
var match = false; var match = false;
elem = elem[dir];
while ( elem ) { while ( elem ) {
if ( elem.sizcache === doneName ) { if ( elem[ expando ] === doneName ) {
match = checkSet[elem.sizset]; match = checkSet[elem.sizset];
break; break;
} }
if ( elem.nodeType === 1 ) { if ( elem.nodeType === 1 ) {
if ( !isXML ) { if ( !isXML ) {
elem.sizcache = doneName; elem[ expando ] = doneName;
elem.sizset = i; elem.sizset = i;
} }
if ( typeof cur !== "string" ) { if ( typeof cur !== "string" ) {
if ( elem === cur ) { if ( elem === cur ) {
match = true; match = true;
@ -7914,21 +8645,34 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
} }
} }
Sizzle.contains = document.compareDocumentPosition ? function(a, b){ if ( document.documentElement.contains ) {
return !!(a.compareDocumentPosition(b) & 16); Sizzle.contains = function( a, b ) {
} : function(a, b){
return a !== b && (a.contains ? a.contains(b) : true); return a !== b && (a.contains ? a.contains(b) : true);
}; };
Sizzle.isXML = function(elem){ } else if ( document.documentElement.compareDocumentPosition ) {
Sizzle.contains = function( a, b ) {
return !!(a.compareDocumentPosition(b) & 16);
};
} else {
Sizzle.contains = function() {
return false;
};
}
Sizzle.isXML = function( elem ) {
// documentElement is verified for cases where it doesn't yet exist // documentElement is verified for cases where it doesn't yet exist
// (such as loading iframes in IE - #4833) // (such as loading iframes in IE - #4833)
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false; return documentElement ? documentElement.nodeName !== "HTML" : false;
}; };
var posProcess = function(selector, context){ var posProcess = function( selector, context, seed ) {
var tmpSet = [], later = "", match, var match,
tmpSet = [],
later = "",
root = context.nodeType ? [context] : context; root = context.nodeType ? [context] : context;
// Position selectors must be done after the filter // Position selectors must be done after the filter
@ -7941,7 +8685,7 @@ var posProcess = function(selector, context){
selector = Expr.relative[selector] ? selector + "*" : selector; selector = Expr.relative[selector] ? selector + "*" : selector;
for ( var i = 0, l = root.length; i < l; i++ ) { for ( var i = 0, l = root.length; i < l; i++ ) {
Sizzle( selector, root[i], tmpSet ); Sizzle( selector, root[i], tmpSet, seed );
} }
return Sizzle.filter( later, tmpSet ); return Sizzle.filter( later, tmpSet );
@ -7970,8 +8714,7 @@ window.tinymce.dom.Sizzle = Sizzle;
('getPos,getRect,getParent,add,setStyle,getStyle,setStyles,' + ('getPos,getRect,getParent,add,setStyle,getStyle,setStyles,' +
'setAttrib,setAttribs,getAttrib,addClass,removeClass,' + 'setAttrib,setAttribs,getAttrib,addClass,removeClass,' +
'hasClass,getOuterHTML,setOuterHTML,remove,show,hide,' + 'hasClass,getOuterHTML,setOuterHTML,remove,show,hide,' +
'isHidden,setHTML,get').split(/,/) 'isHidden,setHTML,get').split(/,/), function(k) {
, function(k) {
t[k] = function() { t[k] = function() {
var a = [id], i; var a = [id], i;
@ -7983,7 +8726,8 @@ window.tinymce.dom.Sizzle = Sizzle;
return a; return a;
}; };
}); }
);
tinymce.extend(t, { tinymce.extend(t, {
on : function(n, f, s) { on : function(n, f, s) {
@ -8069,7 +8813,7 @@ window.tinymce.dom.Sizzle = Sizzle;
}; };
// Shorten names // Shorten names
var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each; var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each, TreeWalker = tinymce.dom.TreeWalker;
tinymce.create('tinymce.dom.Selection', { tinymce.create('tinymce.dom.Selection', {
Selection : function(dom, win, serializer) { Selection : function(dom, win, serializer) {
@ -8176,7 +8920,7 @@ window.tinymce.dom.Sizzle = Sizzle;
} else { } else {
rng.deleteContents(); rng.deleteContents();
if (doc.body.childNodes.length == 0) { if (doc.body.childNodes.length === 0) {
doc.body.innerHTML = content; doc.body.innerHTML = content;
} else { } else {
// createContextualFragment doesn't exists in IE 9 DOMRanges // createContextualFragment doesn't exists in IE 9 DOMRanges
@ -8312,7 +9056,29 @@ window.tinymce.dom.Sizzle = Sizzle;
return index; return index;
}; };
if (type == 2) { function normalizeTableCellSelection(rng) {
function moveEndPoint(start) {
var container, offset, childNodes, prefix = start ? 'start' : 'end';
container = rng[prefix + 'Container'];
offset = rng[prefix + 'Offset'];
if (container.nodeType == 1 && container.nodeName == "TR") {
childNodes = container.childNodes;
container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
if (container) {
offset = start ? 0 : container.childNodes.length;
rng['set' + (start ? 'Start' : 'End')](container, offset);
}
}
};
moveEndPoint(true);
moveEndPoint();
return rng;
};
function getLocation() { function getLocation() {
var rng = t.getRng(true), root = dom.getRoot(), bookmark = {}; var rng = t.getRng(true), root = dom.getRoot(), bookmark = {};
@ -8352,6 +9118,7 @@ window.tinymce.dom.Sizzle = Sizzle;
return bookmark; return bookmark;
}; };
if (type == 2) {
if (t.tridentSel) if (t.tridentSel)
return t.tridentSel.getBookmark(type); return t.tridentSel.getBookmark(type);
@ -8384,7 +9151,7 @@ window.tinymce.dom.Sizzle = Sizzle;
// Detect the empty space after block elements in IE and move the end back one character <p></p>] becomes <p>]</p> // Detect the empty space after block elements in IE and move the end back one character <p></p>] becomes <p>]</p>
rng.moveToElementText(rng2.parentElement()); rng.moveToElementText(rng2.parentElement());
if (rng.compareEndPoints('StartToEnd', rng2) == 0) if (rng.compareEndPoints('StartToEnd', rng2) === 0)
rng2.move('character', -1); rng2.move('character', -1);
rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>'); rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
@ -8406,13 +9173,8 @@ window.tinymce.dom.Sizzle = Sizzle;
if (name == 'IMG') if (name == 'IMG')
return {name : name, index : findIndex(name, element)}; return {name : name, index : findIndex(name, element)};
// Can't insert a node into the root of document WebKit defaults to document
if (rng.startContainer.nodeType == 9) {
return;
}
// W3C method // W3C method
rng2 = rng.cloneRange(); rng2 = normalizeTableCellSelection(rng.cloneRange());
// Insert end marker // Insert end marker
if (!collapsed) { if (!collapsed) {
@ -8420,6 +9182,7 @@ window.tinymce.dom.Sizzle = Sizzle;
rng2.insertNode(dom.create('span', {'data-mce-type' : "bookmark", id : id + '_end', style : styles}, chr)); rng2.insertNode(dom.create('span', {'data-mce-type' : "bookmark", id : id + '_end', style : styles}, chr));
} }
rng = normalizeTableCellSelection(rng);
rng.collapse(true); rng.collapse(true);
rng.insertNode(dom.create('span', {'data-mce-type' : "bookmark", id : id + '_start', style : styles}, chr)); rng.insertNode(dom.create('span', {'data-mce-type' : "bookmark", id : id + '_start', style : styles}, chr));
} }
@ -8432,11 +9195,6 @@ window.tinymce.dom.Sizzle = Sizzle;
moveToBookmark : function(bookmark) { moveToBookmark : function(bookmark) {
var t = this, dom = t.dom, marker1, marker2, rng, root, startContainer, endContainer, startOffset, endOffset; var t = this, dom = t.dom, marker1, marker2, rng, root, startContainer, endContainer, startOffset, endOffset;
if (bookmark) {
if (bookmark.start) {
rng = dom.createRng();
root = dom.getRoot();
function setEndPoint(start) { function setEndPoint(start) {
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children; var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
@ -8471,13 +9229,6 @@ window.tinymce.dom.Sizzle = Sizzle;
return true; return true;
}; };
if (t.tridentSel)
return t.tridentSel.moveToBookmark(bookmark);
if (setEndPoint(true) && setEndPoint()) {
t.setRng(rng);
}
} else if (bookmark.id) {
function restoreEndPoint(suffix) { function restoreEndPoint(suffix) {
var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep; var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
@ -8541,13 +9292,25 @@ window.tinymce.dom.Sizzle = Sizzle;
}; };
function addBogus(node) { function addBogus(node) {
// Adds a bogus BR element for empty block elements or just a space on IE since it renders BR elements incorrectly // Adds a bogus BR element for empty block elements
if (dom.isBlock(node) && !node.innerHTML) if (dom.isBlock(node) && !node.innerHTML && !isIE)
node.innerHTML = !isIE ? '<br data-mce-bogus="1" />' : ' '; node.innerHTML = '<br data-mce-bogus="1" />';
return node; return node;
}; };
if (bookmark) {
if (bookmark.start) {
rng = dom.createRng();
root = dom.getRoot();
if (t.tridentSel)
return t.tridentSel.moveToBookmark(bookmark);
if (setEndPoint(true) && setEndPoint()) {
t.setRng(rng);
}
} else if (bookmark.id) {
// Restore start/end points // Restore start/end points
restoreEndPoint('start'); restoreEndPoint('start');
restoreEndPoint('end'); restoreEndPoint('end');
@ -8568,19 +9331,12 @@ window.tinymce.dom.Sizzle = Sizzle;
select : function(node, content) { select : function(node, content) {
var t = this, dom = t.dom, rng = dom.createRng(), idx; var t = this, dom = t.dom, rng = dom.createRng(), idx;
if (node) {
idx = dom.nodeIndex(node);
rng.setStart(node.parentNode, idx);
rng.setEnd(node.parentNode, idx + 1);
// Find first/last text node or BR element
if (content) {
function setPoint(node, start) { function setPoint(node, start) {
var walker = new tinymce.dom.TreeWalker(node, node); var walker = new TreeWalker(node, node);
do { do {
// Text node // Text node
if (node.nodeType == 3 && tinymce.trim(node.nodeValue).length != 0) { if (node.nodeType == 3 && tinymce.trim(node.nodeValue).length !== 0) {
if (start) if (start)
rng.setStart(node, 0); rng.setStart(node, 0);
else else
@ -8601,6 +9357,13 @@ window.tinymce.dom.Sizzle = Sizzle;
} while (node = (start ? walker.next() : walker.prev())); } while (node = (start ? walker.next() : walker.prev()));
}; };
if (node) {
idx = dom.nodeIndex(node);
rng.setStart(node.parentNode, idx);
rng.setEnd(node.parentNode, idx + 1);
// Find first/last text node or BR element
if (content) {
setPoint(node, 1); setPoint(node, 1);
setPoint(node); setPoint(node);
} }
@ -8644,48 +9407,58 @@ window.tinymce.dom.Sizzle = Sizzle;
}, },
getRng : function(w3c) { getRng : function(w3c) {
var t = this, s, r, elm, doc = t.win.document; var self = this, selection, rng, elm, doc = self.win.document;
// Found tridentSel object then we need to use that one // Found tridentSel object then we need to use that one
if (w3c && t.tridentSel) if (w3c && self.tridentSel) {
return t.tridentSel.getRangeAt(0); return self.tridentSel.getRangeAt(0);
}
try { try {
if (s = t.getSel()) if (selection = self.getSel()) {
r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : doc.createRange()); rng = selection.rangeCount > 0 ? selection.getRangeAt(0) : (selection.createRange ? selection.createRange() : doc.createRange());
}
} catch (ex) { } catch (ex) {
// IE throws unspecified error here if TinyMCE is placed in a frame/iframe // IE throws unspecified error here if TinyMCE is placed in a frame/iframe
} }
// We have W3C ranges and it's IE then fake control selection since IE9 doesn't handle that correctly yet // We have W3C ranges and it's IE then fake control selection since IE9 doesn't handle that correctly yet
if (tinymce.isIE && r && r.setStart && doc.selection.createRange().item) { if (tinymce.isIE && rng && rng.setStart && doc.selection.createRange().item) {
elm = doc.selection.createRange().item(0); elm = doc.selection.createRange().item(0);
r = doc.createRange(); rng = doc.createRange();
r.setStartBefore(elm); rng.setStartBefore(elm);
r.setEndAfter(elm); rng.setEndAfter(elm);
} }
// No range found then create an empty one // No range found then create an empty one
// This can occur when the editor is placed in a hidden container element on Gecko // This can occur when the editor is placed in a hidden container element on Gecko
// Or on IE when there was an exception // Or on IE when there was an exception
if (!r) if (!rng) {
r = doc.createRange ? doc.createRange() : doc.body.createTextRange(); rng = doc.createRange ? doc.createRange() : doc.body.createTextRange();
}
if (t.selectedRange && t.explicitRange) { // If range is at start of document then move it to start of body
if (r.compareBoundaryPoints(r.START_TO_START, t.selectedRange) === 0 && r.compareBoundaryPoints(r.END_TO_END, t.selectedRange) === 0) { if (rng.setStart && rng.startContainer.nodeType === 9 && rng.collapsed) {
elm = self.dom.getRoot();
rng.setStart(elm, 0);
rng.setEnd(elm, 0);
}
if (self.selectedRange && self.explicitRange) {
if (rng.compareBoundaryPoints(rng.START_TO_START, self.selectedRange) === 0 && rng.compareBoundaryPoints(rng.END_TO_END, self.selectedRange) === 0) {
// Safari, Opera and Chrome only ever select text which causes the range to change. // Safari, Opera and Chrome only ever select text which causes the range to change.
// This lets us use the originally set range if the selection hasn't been changed by the user. // This lets us use the originally set range if the selection hasn't been changed by the user.
r = t.explicitRange; rng = self.explicitRange;
} else { } else {
t.selectedRange = null; self.selectedRange = null;
t.explicitRange = null; self.explicitRange = null;
} }
} }
return r; return rng;
}, },
setRng : function(r) { setRng : function(r, forward) {
var s, t = this; var s, t = this;
if (!t.tridentSel) { if (!t.tridentSel) {
@ -8701,6 +9474,13 @@ window.tinymce.dom.Sizzle = Sizzle;
} }
s.addRange(r); s.addRange(r);
// Forward is set to false and we have an extend function
if (forward === false && s.extend) {
s.collapse(r.endContainer, r.endOffset);
s.extend(r.startContainer, r.startOffset);
}
// adding range isn't always successful so we need to check range count otherwise an exception can occur // adding range isn't always successful so we need to check range count otherwise an exception can occur
t.selectedRange = s.rangeCount > 0 ? s.getRangeAt(0) : null; t.selectedRange = s.rangeCount > 0 ? s.getRangeAt(0) : null;
} }
@ -8735,6 +9515,14 @@ window.tinymce.dom.Sizzle = Sizzle;
getNode : function() { getNode : function() {
var t = this, rng = t.getRng(), sel = t.getSel(), elm, start = rng.startContainer, end = rng.endContainer; var t = this, rng = t.getRng(), sel = t.getSel(), elm, start = rng.startContainer, end = rng.endContainer;
function skipEmptyTextNodes(n, forwards) {
var orig = n;
while (n && n.nodeType === 3 && n.length === 0) {
n = forwards ? n.nextSibling : n.previousSibling;
}
return n || orig;
};
// Range maybe lost after the editor is made visible again // Range maybe lost after the editor is made visible again
if (!rng) if (!rng)
return t.dom.getRoot(); return t.dom.getRoot();
@ -8758,13 +9546,6 @@ window.tinymce.dom.Sizzle = Sizzle;
// Handle cases where the selection is immediately wrapped around a node and return that node instead of it's parent. // Handle cases where the selection is immediately wrapped around a node and return that node instead of it's parent.
// This happens when you double click an underlined word in FireFox. // This happens when you double click an underlined word in FireFox.
if (start.nodeType === 3 && end.nodeType === 3) { if (start.nodeType === 3 && end.nodeType === 3) {
function skipEmptyTextNodes(n, forwards) {
var orig = n;
while (n && n.nodeType === 3 && n.length === 0) {
n = forwards ? n.nextSibling : n.previousSibling;
}
return n || orig;
}
if (start.length === rng.startOffset) { if (start.length === rng.startOffset) {
start = skipEmptyTextNodes(start.nextSibling, true); start = skipEmptyTextNodes(start.nextSibling, true);
} else { } else {
@ -8802,7 +9583,7 @@ window.tinymce.dom.Sizzle = Sizzle;
if (sb && eb && sb != eb) { if (sb && eb && sb != eb) {
n = sb; n = sb;
var walker = new tinymce.dom.TreeWalker(sb, dom.getRoot()); var walker = new TreeWalker(sb, dom.getRoot());
while ((n = walker.next()) && n != eb) { while ((n = walker.next()) && n != eb) {
if (dom.isBlock(n)) if (dom.isBlock(n))
bl.push(n); bl.push(n);
@ -8815,54 +9596,120 @@ window.tinymce.dom.Sizzle = Sizzle;
return bl; return bl;
}, },
isForward: function(){
var dom = this.dom, sel = this.getSel(), anchorRange, focusRange;
// No support for selection direction then always return true
if (!sel || sel.anchorNode == null || sel.focusNode == null) {
return true;
}
anchorRange = dom.createRng();
anchorRange.setStart(sel.anchorNode, sel.anchorOffset);
anchorRange.collapse(true);
focusRange = dom.createRng();
focusRange.setStart(sel.focusNode, sel.focusOffset);
focusRange.collapse(true);
return anchorRange.compareBoundaryPoints(anchorRange.START_TO_START, focusRange) <= 0;
},
normalize : function() { normalize : function() {
var self = this, rng, normalized; var self = this, rng, normalized, collapsed, node, sibling;
// TODO:
// Retain selection direction.
// Lean left/right on Gecko for inline elements.
// Run this on mouse up/key up when the user manually moves the selection
// Normalize only on non IE browsers for now
if (tinymce.isIE)
return;
function normalizeEndPoint(start) { function normalizeEndPoint(start) {
var container, offset, walker, dom = self.dom, body = dom.getRoot(), node; var container, offset, walker, dom = self.dom, body = dom.getRoot(), node, nonEmptyElementsMap, nodeName;
function hasBrBeforeAfter(node, left) {
var walker = new TreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || body);
while (node = walker[left ? 'prev' : 'next']()) {
if (node.nodeName === "BR") {
return true;
}
}
};
// Walks the dom left/right to find a suitable text node to move the endpoint into
// It will only walk within the current parent block or body and will stop if it hits a block or a BR/IMG
function findTextNodeRelative(left, startNode) {
var walker, lastInlineElement;
startNode = startNode || container;
walker = new TreeWalker(startNode, dom.getParent(startNode.parentNode, dom.isBlock) || body);
// Walk left until we hit a text node we can move to or a block/br/img
while (node = walker[left ? 'prev' : 'next']()) {
// Found text node that has a length
if (node.nodeType === 3 && node.nodeValue.length > 0) {
container = node;
offset = left ? node.nodeValue.length : 0;
normalized = true;
return;
}
// Break if we find a block or a BR/IMG/INPUT etc
if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
return;
}
lastInlineElement = node;
}
// Only fetch the last inline element when in caret mode for now
if (collapsed && lastInlineElement) {
container = lastInlineElement;
normalized = true;
offset = 0;
}
};
container = rng[(start ? 'start' : 'end') + 'Container']; container = rng[(start ? 'start' : 'end') + 'Container'];
offset = rng[(start ? 'start' : 'end') + 'Offset']; offset = rng[(start ? 'start' : 'end') + 'Offset'];
nonEmptyElementsMap = dom.schema.getNonEmptyElements();
// If the container is a document move it to the body element // If the container is a document move it to the body element
if (container.nodeType === 9) { if (container.nodeType === 9) {
container = container.body; container = dom.getRoot();
offset = 0; offset = 0;
} }
// If the container is body try move it into the closest text node or position // If the container is body try move it into the closest text node or position
// TODO: Add more logic here to handle element selection cases
if (container === body) { if (container === body) {
// If start is before/after a image, table etc
if (start) {
node = container.childNodes[offset > 0 ? offset - 1 : 0];
if (node) {
nodeName = node.nodeName.toLowerCase();
if (nonEmptyElementsMap[node.nodeName] || node.nodeName == "TABLE") {
return;
}
}
}
// Resolve the index // Resolve the index
if (container.hasChildNodes()) { if (container.hasChildNodes()) {
container = container.childNodes[Math.min(!start && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1)]; container = container.childNodes[Math.min(!start && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1)];
offset = 0; offset = 0;
// Don't walk into elements that doesn't have any child nodes like a IMG // Don't walk into elements that doesn't have any child nodes like a IMG
if (container.hasChildNodes()) { if (container.hasChildNodes() && !/TABLE/.test(container.nodeName)) {
// Walk the DOM to find a text node to place the caret at or a BR // Walk the DOM to find a text node to place the caret at or a BR
node = container; node = container;
walker = new tinymce.dom.TreeWalker(container, body); walker = new TreeWalker(container, body);
do { do {
// Found a text node use that position // Found a text node use that position
if (node.nodeType === 3) { if (node.nodeType === 3 && node.nodeValue.length > 0) {
offset = start ? 0 : node.nodeValue.length - 1; offset = start ? 0 : node.nodeValue.length;
container = node; container = node;
normalized = true; normalized = true;
break; break;
} }
// Found a BR/IMG element that we can place the caret before // Found a BR/IMG element that we can place the caret before
if (/^(BR|IMG)$/.test(node.nodeName)) { if (nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
offset = dom.nodeIndex(node); offset = dom.nodeIndex(node);
container = node.parentNode; container = node.parentNode;
@ -8879,23 +9726,61 @@ window.tinymce.dom.Sizzle = Sizzle;
} }
} }
// Lean the caret to the left if possible
if (collapsed) {
// So this: <b>x</b><i>|x</i>
// Becomes: <b>x|</b><i>x</i>
// Seems that only gecko has issues with this
if (container.nodeType === 3 && offset === 0) {
findTextNodeRelative(true);
}
// Lean left into empty inline elements when the caret is before a BR
// So this: <i><b></b><i>|<br></i>
// Becomes: <i><b>|</b><i><br></i>
// Seems that only gecko has issues with this
if (container.nodeType === 1) {
node = container.childNodes[offset];
if(node && node.nodeName === 'BR' && !hasBrBeforeAfter(node) && !hasBrBeforeAfter(node, true)) {
findTextNodeRelative(true, container.childNodes[offset]);
}
}
}
// Lean the start of the selection right if possible
// So this: x[<b>x]</b>
// Becomes: x<b>[x]</b>
if (start && !collapsed && container.nodeType === 3 && offset === container.nodeValue.length) {
findTextNodeRelative(false);
}
// Set endpoint if it was normalized // Set endpoint if it was normalized
if (normalized) if (normalized)
rng['set' + (start ? 'Start' : 'End')](container, offset); rng['set' + (start ? 'Start' : 'End')](container, offset);
}; };
// Normalize only on non IE browsers for now
if (tinymce.isIE)
return;
rng = self.getRng(); rng = self.getRng();
collapsed = rng.collapsed;
// Normalize the end points // Normalize the end points
normalizeEndPoint(true); normalizeEndPoint(true);
if (!rng.collapsed) if (!collapsed)
normalizeEndPoint(); normalizeEndPoint();
// Set the selection if it was normalized // Set the selection if it was normalized
if (normalized) { if (normalized) {
// If it was collapsed then make sure it still is
if (collapsed) {
rng.collapse(true);
}
//console.log(self.dom.dumpRng(rng)); //console.log(self.dom.dumpRng(rng));
self.setRng(rng); self.setRng(rng, self.isForward());
} }
}, },
@ -8913,9 +9798,6 @@ window.tinymce.dom.Sizzle = Sizzle;
_fixIESelection : function() { _fixIESelection : function() {
var dom = this.dom, doc = dom.doc, body = doc.body, started, startRng, htmlElm; var dom = this.dom, doc = dom.doc, body = doc.body, started, startRng, htmlElm;
// Make HTML element unselectable since we are going to handle selection by hand
doc.documentElement.unselectable = true;
// Return range from point or null if it failed // Return range from point or null if it failed
function rngFromPoint(x, y) { function rngFromPoint(x, y) {
var rng = body.createTextRange(); var rng = body.createTextRange();
@ -8965,6 +9847,9 @@ window.tinymce.dom.Sizzle = Sizzle;
startRng = started = 0; startRng = started = 0;
}; };
// Make HTML element unselectable since we are going to handle selection by hand
doc.documentElement.unselectable = true;
// Detect when user selects outside BODY // Detect when user selects outside BODY
dom.bind(doc, ['mousedown', 'contextmenu'], function(e) { dom.bind(doc, ['mousedown', 'contextmenu'], function(e) {
if (e.target.nodeName === 'HTML') { if (e.target.nodeName === 'HTML') {
@ -9039,13 +9924,13 @@ window.tinymce.dom.Sizzle = Sizzle;
} }
}); });
// Remove internal classes mceItem<..> // Remove internal classes mceItem<..> or mceSelected
htmlParser.addAttributeFilter('class', function(nodes, name) { htmlParser.addAttributeFilter('class', function(nodes, name) {
var i = nodes.length, node, value; var i = nodes.length, node, value;
while (i--) { while (i--) {
node = nodes[i]; node = nodes[i];
value = node.attr('class').replace(/\s*mce(Item\w+|Selected)\s*/g, ''); value = node.attr('class').replace(/(?:^|\s)mce(Item\w+|Selected)(?!\S)/g, '');
node.attr('class', value.length > 0 ? value : null); node.attr('class', value.length > 0 ? value : null);
} }
}); });
@ -9223,7 +10108,7 @@ window.tinymce.dom.Sizzle = Sizzle;
// Parse and serialize HTML // Parse and serialize HTML
args.content = htmlSerializer.serialize( args.content = htmlSerializer.serialize(
htmlParser.parse(args.getInner ? node.innerHTML : tinymce.trim(dom.getOuterHTML(node), args), args) htmlParser.parse(tinymce.trim(args.getInner ? node.innerHTML : dom.getOuterHTML(node)), args)
); );
// Replace all BOM characters for now until we can find a better solution // Replace all BOM characters for now until we can find a better solution
@ -9263,7 +10148,7 @@ window.tinymce.dom.Sizzle = Sizzle;
scriptLoadedCallbacks = {}, scriptLoadedCallbacks = {},
queueLoadedCallbacks = [], queueLoadedCallbacks = [],
loading = 0, loading = 0,
undefined; undef;
function loadScript(url, callback) { function loadScript(url, callback) {
var t = this, dom = tinymce.DOM, elm, uri, loc, id; var t = this, dom = tinymce.DOM, elm, uri, loc, id;
@ -9372,7 +10257,7 @@ window.tinymce.dom.Sizzle = Sizzle;
var item, state = states[url]; var item, state = states[url];
// Add url to load queue // Add url to load queue
if (state == undefined) { if (state == undef) {
queue.push(url); queue.push(url);
states[url] = QUEUED; states[url] = QUEUED;
} }
@ -9402,7 +10287,7 @@ window.tinymce.dom.Sizzle = Sizzle;
callback.func.call(callback.scope); callback.func.call(callback.scope);
}); });
scriptLoadedCallbacks[url] = undefined; scriptLoadedCallbacks[url] = undef;
}; };
queueLoadedCallbacks.push({ queueLoadedCallbacks.push({
@ -9459,46 +10344,6 @@ window.tinymce.dom.Sizzle = Sizzle;
tinymce.ScriptLoader = new tinymce.dom.ScriptLoader(); tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();
})(tinymce); })(tinymce);
tinymce.dom.TreeWalker = function(start_node, root_node) {
var node = start_node;
function findSibling(node, start_name, sibling_name, shallow) {
var sibling, parent;
if (node) {
// Walk into nodes if it has a start
if (!shallow && node[start_name])
return node[start_name];
// Return the sibling if it has one
if (node != root_node) {
sibling = node[sibling_name];
if (sibling)
return sibling;
// Walk up the parents to look for siblings
for (parent = node.parentNode; parent && parent != root_node; parent = parent.parentNode) {
sibling = parent[sibling_name];
if (sibling)
return sibling;
}
}
}
};
this.current = function() {
return node;
};
this.next = function(shallow) {
return (node = findSibling(node, 'firstChild', 'nextSibling', shallow));
};
this.prev = function(shallow) {
return (node = findSibling(node, 'lastChild', 'previousSibling', shallow));
};
};
(function(tinymce) { (function(tinymce) {
tinymce.dom.RangeUtils = function(dom) { tinymce.dom.RangeUtils = function(dom) {
var INVISIBLE_CHAR = '\uFEFF'; var INVISIBLE_CHAR = '\uFEFF';
@ -10159,8 +11004,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
update : function() { update : function() {
var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th; var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th;
tw = s.max_width ? Math.min(tb.clientWidth, s.max_width) : tb.clientWidth; tw = s.max_width ? Math.min(tb.offsetWidth, s.max_width) : tb.offsetWidth;
th = s.max_height ? Math.min(tb.clientHeight, s.max_height) : tb.clientHeight; th = s.max_height ? Math.min(tb.offsetHeight, s.max_height) : tb.offsetHeight;
if (!DOM.boxModel) if (!DOM.boxModel)
t.element.setStyles({width : tw + 2, height : th + 2}); t.element.setStyles({width : tw + 2, height : th + 2});
@ -10519,7 +11364,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
})(tinymce); })(tinymce);
(function(tinymce) { (function(tinymce) {
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher; var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, undef;
tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', { tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {
ListBox : function(id, s, ed) { ListBox : function(id, s, ed) {
@ -10546,7 +11391,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
t.marked = {}; t.marked = {};
if (va == undefined) if (va == undef)
return t.selectByIndex(-1); return t.selectByIndex(-1);
// Is string or number make function selector // Is string or number make function selector
@ -10638,7 +11483,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
showMenu : function() { showMenu : function() {
var t = this, p2, e = DOM.get(this.id), m; var t = this, p2, e = DOM.get(this.id), m;
if (t.isDisabled() || t.items.length == 0) if (t.isDisabled() || t.items.length === 0)
return; return;
if (t.menu && t.menu.isMenuVisible) if (t.menu && t.menu.isMenuVisible)
@ -10705,7 +11550,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
m = t.settings.control_manager.createDropMenu(t.id + '_menu', { m = t.settings.control_manager.createDropMenu(t.id + '_menu', {
menu_line : 1, menu_line : 1,
'class' : t.classPrefix + 'Menu mceNoIcons', 'class' : t.classPrefix + 'Menu mceNoIcons',
max_width : 150, max_width : 250,
max_height : 150 max_height : 150
}); });
@ -10725,7 +11570,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
each(t.items, function(o) { each(t.items, function(o) {
// No value then treat it as a title // No value then treat it as a title
if (o.value === undefined) { if (o.value === undef) {
m.add({ m.add({
title : o.title, title : o.title,
role : "option", role : "option",
@ -10815,7 +11660,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
})(tinymce); })(tinymce);
(function(tinymce) { (function(tinymce) {
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher; var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, undef;
tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', { tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {
NativeListBox : function(id, s) { NativeListBox : function(id, s) {
@ -10835,7 +11680,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
select : function(va) { select : function(va) {
var t = this, fv, f; var t = this, fv, f;
if (va == undefined) if (va == undef)
return t.selectByIndex(-1); return t.selectByIndex(-1);
// Is string or number make function selector // Is string or number make function selector
@ -10988,7 +11833,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
m.settings.vp_offset_x = p2.x; m.settings.vp_offset_x = p2.x;
m.settings.vp_offset_y = p2.y; m.settings.vp_offset_y = p2.y;
m.settings.keyboard_focus = t._focused; m.settings.keyboard_focus = t._focused;
m.showMenu(0, e.clientHeight); m.showMenu(0, e.firstChild.clientHeight);
Event.add(DOM.doc, 'mousedown', t.hideMenu, t); Event.add(DOM.doc, 'mousedown', t.hideMenu, t);
t.setState('Selected', 1); t.setState('Selected', 1);
@ -11172,7 +12017,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
p2 = DOM.getPos(e); p2 = DOM.getPos(e);
DOM.setStyles(t.id + '_menu', { DOM.setStyles(t.id + '_menu', {
left : p2.x, left : p2.x,
top : p2.y + e.clientHeight, top : p2.y + e.firstChild.clientHeight,
zIndex : 200000 zIndex : 200000
}); });
e = 0; e = 0;
@ -11215,7 +12060,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
renderMenu : function() { renderMenu : function() {
var t = this, m, i = 0, s = t.settings, n, tb, tr, w, context; var t = this, m, i = 0, s = t.settings, n, tb, tr, w, context;
w = DOM.add(s.menu_container, 'div', {role: 'listbox', id : t.id + '_menu', 'class' : s['menu_class'] + ' ' + s['class'], style : 'position:absolute;left:0;top:-1000px;'}); w = DOM.add(s.menu_container, 'div', {role: 'listbox', id : t.id + '_menu', 'class' : s.menu_class + ' ' + s['class'], style : 'position:absolute;left:0;top:-1000px;'});
m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'}); m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'});
DOM.add(m, 'span', {'class' : 'mceMenuLine'}); DOM.add(m, 'span', {'class' : 'mceMenuLine'});
@ -11244,7 +12089,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
// adding a proper ARIA role = button causes JAWS to read things incorrectly on IE. // adding a proper ARIA role = button causes JAWS to read things incorrectly on IE.
if (!tinymce.isIE ) { if (!tinymce.isIE ) {
settings['role']= 'option'; settings.role = 'option';
} }
n = DOM.add(n, 'a', settings); n = DOM.add(n, 'a', settings);
@ -11540,7 +12385,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
if (typeof u === "object") if (typeof u === "object")
url = u.prefix + u.resource + u.suffix; url = u.prefix + u.resource + u.suffix;
if (url.indexOf('/') != 0 && url.indexOf('://') == -1) if (url.indexOf('/') !== 0 && url.indexOf('://') == -1)
url = tinymce.baseURL + '/' + url; url = tinymce.baseURL + '/' + url;
t.urls[n] = url.substring(0, url.lastIndexOf('/')); t.urls[n] = url.substring(0, url.lastIndexOf('/'));
@ -11564,7 +12409,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
DOM = tinymce.DOM, Event = tinymce.dom.Event, DOM = tinymce.DOM, Event = tinymce.dom.Event,
ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
explode = tinymce.explode, explode = tinymce.explode,
Dispatcher = tinymce.util.Dispatcher, undefined, instanceCounter = 0; Dispatcher = tinymce.util.Dispatcher, undef, instanceCounter = 0;
// Setup some URLs where the editor API is located and where the document is // Setup some URLs where the editor API is located and where the document is
tinymce.documentBaseURL = window.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, ''); tinymce.documentBaseURL = window.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
@ -11634,6 +12479,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
return f.apply(s || this, Array.prototype.slice.call(arguments, 2)); return f.apply(s || this, Array.prototype.slice.call(arguments, 2));
}; };
function hasClass(n, c) {
return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c);
};
s = extend({ s = extend({
theme : "simple", theme : "simple",
language : "en" language : "en"
@ -11677,10 +12526,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
case "textareas": case "textareas":
case "specific_textareas": case "specific_textareas":
function hasClass(n, c) {
return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c);
};
each(DOM.select('textarea'), function(elm) { each(DOM.select('textarea'), function(elm) {
if (s.editor_deselector && hasClass(elm, s.editor_deselector)) if (s.editor_deselector && hasClass(elm, s.editor_deselector))
return; return;
@ -11741,7 +12586,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}, },
get : function(id) { get : function(id) {
if (id === undefined) if (id === undef)
return this.editors; return this.editors;
return this.editors[id]; return this.editors[id];
@ -11794,6 +12639,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
execCommand : function(c, u, v) { execCommand : function(c, u, v) {
var t = this, ed = t.get(v), w; var t = this, ed = t.get(v), w;
function clr() {
ed.destroy();
w.detachEvent('onunload', clr);
w = w.tinyMCE = w.tinymce = null; // IE leak
};
// Manager commands // Manager commands
switch (c) { switch (c) {
case "mceFocus": case "mceFocus":
@ -11822,12 +12673,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Fix IE memory leaks // Fix IE memory leaks
if (tinymce.isIE) { if (tinymce.isIE) {
function clr() {
ed.destroy();
w.detachEvent('onunload', clr);
w = w.tinyMCE = w.tinymce = null; // IE leak
};
w.attachEvent('onunload', clr); w.attachEvent('onunload', clr);
} }
@ -11910,108 +12755,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
(function(tinymce) { (function(tinymce) {
// Shorten these names // Shorten these names
var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend,
Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isGecko = tinymce.isGecko, each = tinymce.each, isGecko = tinymce.isGecko,
isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, is = tinymce.is, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, is = tinymce.is,
ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode, VK = tinymce.VK; explode = tinymce.explode;
tinymce.create('tinymce.Editor', { tinymce.create('tinymce.Editor', {
Editor : function(id, s) { Editor : function(id, settings) {
var t = this; var self = this, TRUE = true;
t.id = t.editorId = id; self.settings = settings = extend({
t.execCommands = {};
t.queryStateCommands = {};
t.queryValueCommands = {};
t.isNotDirty = false;
t.plugins = {};
// Add events to the editor
each([
'onPreInit',
'onBeforeRenderUI',
'onPostRender',
'onLoad',
'onInit',
'onRemove',
'onActivate',
'onDeactivate',
'onClick',
'onEvent',
'onMouseUp',
'onMouseDown',
'onDblClick',
'onKeyDown',
'onKeyUp',
'onKeyPress',
'onContextMenu',
'onSubmit',
'onReset',
'onPaste',
'onPreProcess',
'onPostProcess',
'onBeforeSetContent',
'onBeforeGetContent',
'onSetContent',
'onGetContent',
'onLoadContent',
'onSaveContent',
'onNodeChange',
'onChange',
'onBeforeExecCommand',
'onExecCommand',
'onUndo',
'onRedo',
'onVisualAid',
'onSetProgressState',
'onSetAttrib'
], function(e) {
t[e] = new Dispatcher(t);
});
t.settings = s = extend({
id : id, id : id,
language : 'en', language : 'en',
docs_language : 'en',
theme : 'simple', theme : 'simple',
skin : 'default', skin : 'default',
delta_width : 0, delta_width : 0,
@ -12019,58 +12774,63 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
popup_css : '', popup_css : '',
plugins : '', plugins : '',
document_base_url : tinymce.documentBaseURL, document_base_url : tinymce.documentBaseURL,
add_form_submit_trigger : 1, add_form_submit_trigger : TRUE,
submit_patch : 1, submit_patch : TRUE,
add_unload_trigger : 1, add_unload_trigger : TRUE,
convert_urls : 1, convert_urls : TRUE,
relative_urls : 1, relative_urls : TRUE,
remove_script_host : 1, remove_script_host : TRUE,
table_inline_editing : 0, table_inline_editing : false,
object_resizing : 1, object_resizing : TRUE,
cleanup : 1, accessibility_focus : TRUE,
accessibility_focus : 1,
custom_shortcuts : 1,
custom_undo_redo_keyboard_shortcuts : 1,
custom_undo_redo_restore_selection : 1,
custom_undo_redo : 1,
doctype : tinymce.isIE6 ? '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">' : '<!DOCTYPE>', // Use old doctype on IE 6 to avoid horizontal scroll doctype : tinymce.isIE6 ? '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">' : '<!DOCTYPE>', // Use old doctype on IE 6 to avoid horizontal scroll
visual_table_class : 'mceItemTable', visual : TRUE,
visual : 1,
font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large', font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
font_size_legacy_values : 'xx-small,small,medium,large,x-large,xx-large,300%', // See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size font_size_legacy_values : 'xx-small,small,medium,large,x-large,xx-large,300%', // See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size
apply_source_formatting : 1, apply_source_formatting : TRUE,
directionality : 'ltr', directionality : 'ltr',
forced_root_block : 'p', forced_root_block : 'p',
hidden_input : 1, hidden_input : TRUE,
padd_empty_editor : 1, padd_empty_editor : TRUE,
render_ui : 1, render_ui : TRUE,
init_theme : 1,
force_p_newlines : 1,
indentation : '30px', indentation : '30px',
keep_styles : 1, fix_table_elements : TRUE,
fix_table_elements : 1, inline_styles : TRUE,
inline_styles : 1, convert_fonts_to_spans : TRUE,
convert_fonts_to_spans : true,
indent : 'simple', indent : 'simple',
indent_before : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside', indent_before : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure',
indent_after : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside', indent_after : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure',
validate : true, validate : TRUE,
entity_encoding : 'named', entity_encoding : 'named',
url_converter : t.convertURL, url_converter : self.convertURL,
url_converter_scope : t, url_converter_scope : self,
ie7_compat : true ie7_compat : TRUE
}, s); }, settings);
t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, { self.id = self.editorId = id;
self.isNotDirty = false;
self.plugins = {};
self.documentBaseURI = new tinymce.util.URI(settings.document_base_url || tinymce.documentBaseURL, {
base_uri : tinyMCE.baseURI base_uri : tinyMCE.baseURI
}); });
t.baseURI = tinymce.baseURI; self.baseURI = tinymce.baseURI;
t.contentCSS = []; self.contentCSS = [];
// Creates all events like onClick, onSetContent etc see Editor.Events.js for the actual logic
self.setupEvents();
// Internal command handler objects
self.execCommands = {};
self.queryStateCommands = {};
self.queryValueCommands = {};
// Call setup // Call setup
t.execCallback('setup', t); self.execCallback('setup', self);
}, },
render : function(nst) { render : function(nst) {
@ -12091,8 +12851,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
return; return;
// Is a iPad/iPhone and not on iOS5, then skip initialization. We need to sniff // Is a iPad/iPhone and not on iOS5, then skip initialization. We need to sniff
// here since the browser says it has contentEditable support but there is no visible // here since the browser says it has contentEditable support but there is no visible caret.
// caret We will remove this check ones Apple implements full contentEditable support
if (tinymce.isIDevice && !tinymce.isIOS5) if (tinymce.isIDevice && !tinymce.isIOS5)
return; return;
@ -12171,9 +12930,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
var dependencies = PluginManager.dependencies(p); var dependencies = PluginManager.dependencies(p);
each(dependencies, function(dep) { each(dependencies, function(dep) {
var defaultSettings = {prefix:'plugins/', resource: dep, suffix:'/editor_plugin' + tinymce.suffix + '.js'}; var defaultSettings = {prefix:'plugins/', resource: dep, suffix:'/editor_plugin' + tinymce.suffix + '.js'};
var dep = PluginManager.createUrl(defaultSettings, dep); dep = PluginManager.createUrl(defaultSettings, dep);
PluginManager.load(dep.resource, dep); PluginManager.load(dep.resource, dep);
}); });
} else { } else {
// Skip safari plugin, since it is removed as of 3.3b1 // Skip safari plugin, since it is removed as of 3.3b1
@ -12207,7 +12965,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
o = ThemeManager.get(s.theme); o = ThemeManager.get(s.theme);
t.theme = new o(); t.theme = new o();
if (t.theme.init && s.init_theme) if (t.theme.init)
t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, '')); t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));
} }
function initPlugin(p) { function initPlugin(p) {
@ -12243,51 +13001,27 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
t.controlManager = new tinymce.ControlManager(t); t.controlManager = new tinymce.ControlManager(t);
if (s.custom_undo_redo) {
t.onBeforeExecCommand.add(function(ed, cmd, ui, val, a) {
if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))
t.undoManager.beforeChange();
});
t.onExecCommand.add(function(ed, cmd, ui, val, a) {
if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))
t.undoManager.add();
});
}
t.onExecCommand.add(function(ed, c) { t.onExecCommand.add(function(ed, c) {
// Don't refresh the select lists until caret move // Don't refresh the select lists until caret move
if (!/^(FontName|FontSize)$/.test(c)) if (!/^(FontName|FontSize)$/.test(c))
t.nodeChanged(); t.nodeChanged();
}); });
// Remove ghost selections on images and tables in Gecko
if (isGecko) {
function repaint(a, o) {
if (!o || !o.initial)
t.execCommand('mceRepaint');
};
t.onUndo.add(repaint);
t.onRedo.add(repaint);
t.onSetContent.add(repaint);
}
// Enables users to override the control factory // Enables users to override the control factory
t.onBeforeRenderUI.dispatch(t, t.controlManager); t.onBeforeRenderUI.dispatch(t, t.controlManager);
// Measure box // Measure box
if (s.render_ui) { if (s.render_ui && t.theme) {
w = s.width || e.style.width || e.offsetWidth; w = s.width || e.style.width || e.offsetWidth;
h = s.height || e.style.height || e.offsetHeight; h = s.height || e.style.height || e.offsetHeight;
t.orgDisplay = e.style.display; t.orgDisplay = e.style.display;
re = /^[0-9\.]+(|px)$/i; re = /^[0-9\.]+(|px)$/i;
if (re.test('' + w)) if (re.test('' + w))
w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100); w = Math.max(parseInt(w, 10) + (o.deltaWidth || 0), 100);
if (re.test('' + h)) if (re.test('' + h))
h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100); h = Math.max(parseInt(h, 10) + (o.deltaHeight || 0), 100);
// Render UI // Render UI
o = t.theme.renderUI({ o = t.theme.renderUI({
@ -12301,6 +13035,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
t.editorContainer = o.editorContainer; t.editorContainer = o.editorContainer;
} }
// Load specified content CSS last
if (s.content_css) {
each(explode(s.content_css), function(u) {
t.contentCSS.push(t.documentBaseURI.toAbsolute(u));
});
}
// Content editable mode ends here
if (s.content_editable) {
e = n = o = null; // Fix IE leak
return t.initContentBody();
}
// User specified a document.domain value // User specified a document.domain value
if (document.domain && location.hostname != document.domain) if (document.domain && location.hostname != document.domain)
@ -12312,13 +13058,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
height : h height : h
}); });
// Load specified content CSS last
if (s.content_css) {
tinymce.each(explode(s.content_css), function(u) {
t.contentCSS.push(t.documentBaseURI.toAbsolute(u));
});
}
h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : ''); h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : '');
if (h < 100) if (h < 100)
h = 100; h = 100;
@ -12362,7 +13101,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Domain relaxing enabled, then set document domain // Domain relaxing enabled, then set document domain
if (tinymce.relaxedDomain && (isIE || (tinymce.isOpera && parseFloat(opera.version()) < 11))) { if (tinymce.relaxedDomain && (isIE || (tinymce.isOpera && parseFloat(opera.version()) < 11))) {
// We need to write the contents here in IE since multiple writes messes up refresh button and back button // We need to write the contents here in IE since multiple writes messes up refresh button and back button
u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()'; u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.initContentBody();})()';
} }
// Create iframe // Create iframe
@ -12386,73 +13125,61 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
DOM.setAttrib(t.id, 'aria-hidden', true); DOM.setAttrib(t.id, 'aria-hidden', true);
if (!tinymce.relaxedDomain || !u) if (!tinymce.relaxedDomain || !u)
t.setupIframe(); t.initContentBody();
e = n = o = null; // Cleanup e = n = o = null; // Cleanup
}, },
setupIframe : function() { initContentBody : function() {
var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b; var self = this, settings = self.settings, targetElm = DOM.get(self.id), doc = self.getDoc(), html, body;
// Setup iframe body // Setup iframe body
if (!isIE || !tinymce.relaxedDomain) { if ((!isIE || !tinymce.relaxedDomain) && !settings.content_editable) {
d.open(); doc.open();
d.write(t.iframeHTML); doc.write(self.iframeHTML);
d.close(); doc.close();
if (tinymce.relaxedDomain) if (tinymce.relaxedDomain)
d.domain = tinymce.relaxedDomain; doc.domain = tinymce.relaxedDomain;
}
if (settings.content_editable) {
DOM.addClass(targetElm, 'mceContentBody');
self.contentDocument = doc = settings.content_document || document;
self.contentWindow = settings.content_window || window;
self.bodyElement = targetElm;
// Prevent leak in IE
settings.content_document = settings.content_window = null;
} }
// It will not steal focus while setting contentEditable // It will not steal focus while setting contentEditable
b = t.getBody(); body = self.getBody();
b.disabled = true; body.disabled = true;
if (!s.readonly) if (!settings.readonly)
b.contentEditable = true; body.contentEditable = self.getParam('content_editable_state', true);
b.disabled = false; body.disabled = false;
t.schema = new tinymce.html.Schema(s); self.schema = new tinymce.html.Schema(settings);
t.dom = new tinymce.dom.DOMUtils(t.getDoc(), { self.dom = new tinymce.dom.DOMUtils(doc, {
keep_values : true, keep_values : true,
url_converter : t.convertURL, url_converter : self.convertURL,
url_converter_scope : t, url_converter_scope : self,
hex_colors : s.force_hex_style_colors, hex_colors : settings.force_hex_style_colors,
class_filter : s.class_filter, class_filter : settings.class_filter,
update_styles : 1, update_styles : true,
fix_ie_paragraphs : 1, root_element : settings.content_editable ? self.id : null,
schema : t.schema schema : self.schema
}); });
t.parser = new tinymce.html.DomParser(s, t.schema); self.parser = new tinymce.html.DomParser(settings, self.schema);
// Force anchor names closed, unless the setting "allow_html_in_named_anchor" is explicitly included.
if (!t.settings.allow_html_in_named_anchor) {
t.parser.addAttributeFilter('name', function(nodes, name) {
var i = nodes.length, sibling, prevSibling, parent, node;
while (i--) {
node = nodes[i];
if (node.name === 'a' && node.firstChild) {
parent = node.parent;
// Move children after current node
sibling = node.lastChild;
do {
prevSibling = sibling.prev;
parent.insert(sibling, node);
sibling = prevSibling;
} while (sibling);
}
}
});
}
// Convert src and href into data-mce-src, data-mce-href and data-mce-style // Convert src and href into data-mce-src, data-mce-href and data-mce-style
t.parser.addAttributeFilter('src,href,style', function(nodes, name) { self.parser.addAttributeFilter('src,href,style', function(nodes, name) {
var i = nodes.length, node, dom = t.dom, value, internalName; var i = nodes.length, node, dom = self.dom, value, internalName;
while (i--) { while (i--) {
node = nodes[i]; node = nodes[i];
@ -12464,13 +13191,13 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
if (name === "style") if (name === "style")
node.attr(internalName, dom.serializeStyle(dom.parseStyle(value), node.name)); node.attr(internalName, dom.serializeStyle(dom.parseStyle(value), node.name));
else else
node.attr(internalName, t.convertURL(value, name, node.name)); node.attr(internalName, self.convertURL(value, name, node.name));
} }
} }
}); });
// Keep scripts from executing // Keep scripts from executing
t.parser.addNodeFilter('script', function(nodes, name) { self.parser.addNodeFilter('script', function(nodes, name) {
var i = nodes.length, node; var i = nodes.length, node;
while (i--) { while (i--) {
@ -12479,7 +13206,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
} }
}); });
t.parser.addNodeFilter('#cdata', function(nodes, name) { self.parser.addNodeFilter('#cdata', function(nodes, name) {
var i = nodes.length, node; var i = nodes.length, node;
while (i--) { while (i--) {
@ -12490,8 +13217,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
} }
}); });
t.parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function(nodes, name) { self.parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function(nodes, name) {
var i = nodes.length, node, nonEmptyElements = t.schema.getNonEmptyElements(); var i = nodes.length, node, nonEmptyElements = self.schema.getNonEmptyElements();
while (i--) { while (i--) {
node = nodes[i]; node = nodes[i];
@ -12501,306 +13228,89 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
} }
}); });
t.serializer = new tinymce.dom.Serializer(s, t.dom, t.schema); self.serializer = new tinymce.dom.Serializer(settings, self.dom, self.schema);
t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer); self.selection = new tinymce.dom.Selection(self.dom, self.getWin(), self.serializer);
t.formatter = new tinymce.Formatter(this); self.formatter = new tinymce.Formatter(self);
// Register default formats self.undoManager = new tinymce.UndoManager(self);
t.formatter.register({
alignleft : [
{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}, defaultBlock: 'div'},
{selector : 'img,table', collapsed : false, styles : {'float' : 'left'}}
],
aligncenter : [ self.forceBlocks = new tinymce.ForceBlocks(self);
{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}, defaultBlock: 'div'}, self.enterKey = new tinymce.EnterKey(self);
{selector : 'img', collapsed : false, styles : {display : 'block', marginLeft : 'auto', marginRight : 'auto'}}, self.editorCommands = new tinymce.EditorCommands(self);
{selector : 'table', collapsed : false, styles : {marginLeft : 'auto', marginRight : 'auto'}}
],
alignright : [
{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}, defaultBlock: 'div'},
{selector : 'img,table', collapsed : false, styles : {'float' : 'right'}}
],
alignfull : [
{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'justify'}, defaultBlock: 'div'}
],
bold : [
{inline : 'strong', remove : 'all'},
{inline : 'span', styles : {fontWeight : 'bold'}},
{inline : 'b', remove : 'all'}
],
italic : [
{inline : 'em', remove : 'all'},
{inline : 'span', styles : {fontStyle : 'italic'}},
{inline : 'i', remove : 'all'}
],
underline : [
{inline : 'span', styles : {textDecoration : 'underline'}, exact : true},
{inline : 'u', remove : 'all'}
],
strikethrough : [
{inline : 'span', styles : {textDecoration : 'line-through'}, exact : true},
{inline : 'strike', remove : 'all'}
],
forecolor : {inline : 'span', styles : {color : '%value'}, wrap_links : false},
hilitecolor : {inline : 'span', styles : {backgroundColor : '%value'}, wrap_links : false},
fontname : {inline : 'span', styles : {fontFamily : '%value'}},
fontsize : {inline : 'span', styles : {fontSize : '%value'}},
fontsize_class : {inline : 'span', attributes : {'class' : '%value'}},
blockquote : {block : 'blockquote', wrapper : 1, remove : 'all'},
subscript : {inline : 'sub'},
superscript : {inline : 'sup'},
link : {inline : 'a', selector : 'a', remove : 'all', split : true, deep : true,
onmatch : function(node) {
return true;
},
onformat : function(elm, fmt, vars) {
each(vars, function(value, key) {
t.dom.setAttrib(elm, key, value);
});
}
},
removeformat : [
{selector : 'b,strong,em,i,font,u,strike', remove : 'all', split : true, expand : false, block_expand : true, deep : true},
{selector : 'span', attributes : ['style', 'class'], remove : 'empty', split : true, expand : false, deep : true},
{selector : '*', attributes : ['style', 'class'], split : false, expand : false, deep : true}
]
});
// Register default block formats
each('p h1 h2 h3 h4 h5 h6 div address pre div code dt dd samp'.split(/\s/), function(name) {
t.formatter.register(name, {block : name, remove : 'all'});
});
// Register user defined formats
t.formatter.register(t.settings.formats);
t.undoManager = new tinymce.UndoManager(t);
// Pass through // Pass through
t.undoManager.onAdd.add(function(um, l) { self.serializer.onPreProcess.add(function(se, o) {
if (um.hasUndo()) return self.onPreProcess.dispatch(self, o, se);
return t.onChange.dispatch(t, l, um);
}); });
t.undoManager.onUndo.add(function(um, l) { self.serializer.onPostProcess.add(function(se, o) {
return t.onUndo.dispatch(t, l, um); return self.onPostProcess.dispatch(self, o, se);
}); });
t.undoManager.onRedo.add(function(um, l) { self.onPreInit.dispatch(self);
return t.onRedo.dispatch(t, l, um);
});
t.forceBlocks = new tinymce.ForceBlocks(t); if (!settings.gecko_spellcheck)
t.enterKey = new tinymce.EnterKey(t); doc.body.spellcheck = false;
t.editorCommands = new tinymce.EditorCommands(t); if (!settings.readonly) {
self.bindNativeEvents();
// Pass through
t.serializer.onPreProcess.add(function(se, o) {
return t.onPreProcess.dispatch(t, o, se);
});
t.serializer.onPostProcess.add(function(se, o) {
return t.onPostProcess.dispatch(t, o, se);
});
t.onPreInit.dispatch(t);
if (!s.gecko_spellcheck)
t.getBody().spellcheck = 0;
if (!s.readonly)
t._addEvents();
t.controlManager.onPostRender.dispatch(t, t.controlManager);
t.onPostRender.dispatch(t);
t.quirks = new tinymce.util.Quirks(this);
if (s.directionality)
t.getBody().dir = s.directionality;
if (s.nowrap)
t.getBody().style.whiteSpace = "nowrap";
if (s.handle_node_change_callback) {
t.onNodeChange.add(function(ed, cm, n) {
t.execCallback('handle_node_change_callback', t.id, n, -1, -1, true, t.selection.isCollapsed());
});
} }
if (s.save_callback) { self.controlManager.onPostRender.dispatch(self, self.controlManager);
t.onSaveContent.add(function(ed, o) { self.onPostRender.dispatch(self);
var h = t.execCallback('save_callback', t.id, o.content, t.getBody());
if (h) self.quirks = tinymce.util.Quirks(self);
o.content = h;
});
}
if (s.onchange_callback) { if (settings.directionality)
t.onChange.add(function(ed, l) { body.dir = settings.directionality;
t.execCallback('onchange_callback', t, l);
});
}
if (s.protect) { if (settings.nowrap)
t.onBeforeSetContent.add(function(ed, o) { body.style.whiteSpace = "nowrap";
if (s.protect) {
each(s.protect, function(pattern) { if (settings.protect) {
self.onBeforeSetContent.add(function(ed, o) {
each(settings.protect, function(pattern) {
o.content = o.content.replace(pattern, function(str) { o.content = o.content.replace(pattern, function(str) {
return '<!--mce:protected ' + escape(str) + '-->'; return '<!--mce:protected ' + escape(str) + '-->';
}); });
}); });
}
});
}
if (s.convert_newlines_to_brs) {
t.onBeforeSetContent.add(function(ed, o) {
if (o.initial)
o.content = o.content.replace(/\r?\n/g, '<br />');
});
}
if (s.preformatted) {
t.onPostProcess.add(function(ed, o) {
o.content = o.content.replace(/^\s*<pre.*?>/, '');
o.content = o.content.replace(/<\/pre>\s*$/, '');
if (o.set)
o.content = '<pre class="mceItemHidden">' + o.content + '</pre>';
});
}
if (s.verify_css_classes) {
t.serializer.attribValueFilter = function(n, v) {
var s, cl;
if (n == 'class') {
// Build regexp for classes
if (!t.classesRE) {
cl = t.dom.getClasses();
if (cl.length > 0) {
s = '';
each (cl, function(o) {
s += (s ? '|' : '') + o['class'];
});
t.classesRE = new RegExp('(' + s + ')', 'gi');
}
}
return !t.classesRE || /(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v) || t.classesRE.test(v) ? v : '';
}
return v;
};
}
if (s.cleanup_callback) {
t.onBeforeSetContent.add(function(ed, o) {
o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
});
t.onPreProcess.add(function(ed, o) {
if (o.set)
t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);
if (o.get)
t.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);
});
t.onPostProcess.add(function(ed, o) {
if (o.set)
o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
if (o.get)
o.content = t.execCallback('cleanup_callback', 'get_from_editor', o.content, o);
});
}
if (s.save_callback) {
t.onGetContent.add(function(ed, o) {
if (o.save)
o.content = t.execCallback('save_callback', t.id, o.content, t.getBody());
});
}
if (s.handle_event_callback) {
t.onEvent.add(function(ed, e, o) {
if (t.execCallback('handle_event_callback', e, ed, o) === false)
Event.cancel(e);
}); });
} }
// Add visual aids when new contents is added // Add visual aids when new contents is added
t.onSetContent.add(function() { self.onSetContent.add(function() {
t.addVisual(t.getBody()); self.addVisual(self.getBody());
}); });
// Remove empty contents // Remove empty contents
if (s.padd_empty_editor) { if (settings.padd_empty_editor) {
t.onPostProcess.add(function(ed, o) { self.onPostProcess.add(function(ed, o) {
o.content = o.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, ''); o.content = o.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');
}); });
} }
if (isGecko) { self.load({initial : true, format : 'html'});
// Fix gecko link bug, when a link is placed at the end of block elements there is self.startContent = self.getContent({format : 'raw'});
// no way to move the caret behind the link. This fix adds a bogus br element after the link
function fixLinks(ed, o) {
each(ed.dom.select('a'), function(n) {
var pn = n.parentNode;
if (ed.dom.isBlock(pn) && pn.lastChild === n) self.initialized = true;
ed.dom.add(pn, 'br', {'data-mce-bogus' : 1});
});
};
t.onExecCommand.add(function(ed, cmd) { self.onInit.dispatch(self);
if (cmd === 'CreateLink') self.execCallback('setupcontent_callback', self.id, body, doc);
fixLinks(ed); self.execCallback('init_instance_callback', self);
}); self.focus(true);
self.nodeChanged({initial : true});
t.onSetContent.add(t.selection.onSetContent.add(fixLinks));
}
t.load({initial : true, format : 'html'});
t.startContent = t.getContent({format : 'raw'});
t.undoManager.add();
t.initialized = true;
t.onInit.dispatch(t);
t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc());
t.execCallback('init_instance_callback', t);
t.focus(true);
t.nodeChanged({initial : 1});
// Load specified content CSS last // Load specified content CSS last
each(t.contentCSS, function(u) { each(self.contentCSS, function(url) {
t.dom.loadCSS(u); self.dom.loadCSS(url);
}); });
// Handle auto focus // Handle auto focus
if (s.auto_focus) { if (settings.auto_focus) {
setTimeout(function () { setTimeout(function () {
var ed = tinymce.get(s.auto_focus); var ed = tinymce.get(settings.auto_focus);
ed.selection.select(ed.getBody(), 1); ed.selection.select(ed.getBody(), 1);
ed.selection.collapse(1); ed.selection.collapse(1);
@ -12809,29 +13319,41 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}, 100); }, 100);
} }
e = null; // Clean up references for IE
targetElm = doc = body = null;
}, },
focus : function(skip_focus) {
var oed, self = this, selection = self.selection, contentEditable = self.settings.content_editable, ieRng, controlElm, doc = self.getDoc(), body;
focus : function(sf) { if (!skip_focus) {
var oed, t = this, selection = t.selection, ce = t.settings.content_editable, ieRng, controlElm, doc = t.getDoc();
if (!sf) {
// Get selected control element // Get selected control element
ieRng = selection.getRng(); ieRng = selection.getRng();
if (ieRng.item) { if (ieRng.item) {
controlElm = ieRng.item(0); controlElm = ieRng.item(0);
} }
t._refreshContentEditable(); self._refreshContentEditable();
// Is not content editable // Focus the window iframe
if (!ce) if (!contentEditable) {
t.getWin().focus(); self.getWin().focus();
}
// Focus the body as well since it's contentEditable // Focus the body as well since it's contentEditable
if (tinymce.isGecko) { if (tinymce.isGecko || contentEditable) {
t.getBody().focus(); body = self.getBody();
// Check for setActive since it doesn't scroll to the element
if (body.setActive) {
body.setActive();
} else {
body.focus();
}
if (contentEditable) {
selection.normalize();
}
} }
// Restore selected control element // Restore selected control element
@ -12842,17 +13364,16 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
ieRng.addElement(controlElm); ieRng.addElement(controlElm);
ieRng.select(); ieRng.select();
} }
} }
if (tinymce.activeEditor != t) { if (tinymce.activeEditor != self) {
if ((oed = tinymce.activeEditor) != null) if ((oed = tinymce.activeEditor) != null)
oed.onDeactivate.dispatch(oed, t); oed.onDeactivate.dispatch(oed, self);
t.onActivate.dispatch(t, oed); self.onActivate.dispatch(self, oed);
} }
tinymce._setActive(t); tinymce._setActive(self);
}, },
execCallback : function(n) { execCallback : function(n) {
@ -12884,7 +13405,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
if (!s) if (!s)
return ''; return '';
return i18n[c + '.' + s] || s.replace(/{\#([^}]+)\}/g, function(a, b) { return i18n[c + '.' + s] || s.replace(/\{\#([^\}]+)\}/g, function(a, b) {
return i18n[c + '.' + b] || '{#' + b + '}'; return i18n[c + '.' + b] || '{#' + b + '}';
}); });
}, },
@ -12918,37 +13439,40 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}, },
nodeChanged : function(o) { nodeChanged : function(o) {
var t = this, s = t.selection, n = s.getStart() || t.getBody(); var self = this, selection = self.selection, node;
// Fix for bug #1896577 it seems that this can not be fired while the editor is loading // Fix for bug #1896577 it seems that this can not be fired while the editor is loading
if (t.initialized) { if (self.initialized) {
o = o || {}; o = o || {};
n = isIE && n.ownerDocument != t.getDoc() ? t.getBody() : n; // Fix for IE initial state
// Get start node
node = selection.getStart() || self.getBody();
node = isIE && node.ownerDocument != self.getDoc() ? self.getBody() : node; // Fix for IE initial state
// Get parents and add them to object // Get parents and add them to object
o.parents = []; o.parents = [];
t.dom.getParent(n, function(node) { self.dom.getParent(node, function(node) {
if (node.nodeName == 'BODY') if (node.nodeName == 'BODY')
return true; return true;
o.parents.push(node); o.parents.push(node);
}); });
t.onNodeChange.dispatch( self.onNodeChange.dispatch(
t, self,
o ? o.controlManager || t.controlManager : t.controlManager, o ? o.controlManager || self.controlManager : self.controlManager,
n, node,
s.isCollapsed(), selection.isCollapsed(),
o o
); );
} }
}, },
addButton : function(n, s) { addButton : function(name, settings) {
var t = this; var self = this;
t.buttons = t.buttons || {}; self.buttons = self.buttons || {};
t.buttons[n] = s; self.buttons[name] = settings;
}, },
addCommand : function(name, callback, scope) { addCommand : function(name, callback, scope) {
@ -12966,7 +13490,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
addShortcut : function(pa, desc, cmd_func, sc) { addShortcut : function(pa, desc, cmd_func, sc) {
var t = this, c; var t = this, c;
if (!t.settings.custom_shortcuts) if (t.settings.custom_shortcuts === false)
return false; return false;
t.shortcuts = t.shortcuts || {}; t.shortcuts = t.shortcuts || {};
@ -12991,7 +13515,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
var o = { var o = {
func : cmd_func, func : cmd_func,
scope : sc || this, scope : sc || this,
desc : desc, desc : t.translate(desc),
alt : false, alt : false,
ctrl : false, ctrl : false,
shift : false shift : false
@ -13133,24 +13657,24 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}, },
show : function() { show : function() {
var t = this; var self = this;
DOM.show(t.getContainer()); DOM.show(self.getContainer());
DOM.hide(t.id); DOM.hide(self.id);
t.load(); self.load();
}, },
hide : function() { hide : function() {
var t = this, d = t.getDoc(); var self = this, doc = self.getDoc();
// Fixed bug where IE has a blinking cursor left from the editor // Fixed bug where IE has a blinking cursor left from the editor
if (isIE && d) if (isIE && doc)
d.execCommand('SelectAll'); doc.execCommand('SelectAll');
// We must save before we hide so Safari doesn't crash // We must save before we hide so Safari doesn't crash
t.save(); self.save();
DOM.hide(t.getContainer()); DOM.hide(self.getContainer());
DOM.setStyle(t.id, 'display', t.orgDisplay); DOM.setStyle(self.id, 'display', self.orgDisplay);
}, },
isHidden : function() { isHidden : function() {
@ -13192,12 +13716,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
o = o || {}; o = o || {};
o.save = true; o.save = true;
// Add undo level will trigger onchange event
if (!o.no_events) {
t.undoManager.typing = false;
t.undoManager.add();
}
o.element = e; o.element = e;
h = o.content = t.getContent(o); h = o.content = t.getContent(o);
@ -13283,6 +13801,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
args = args || {}; args = args || {};
args.format = args.format || 'html'; args.format = args.format || 'html';
args.get = true; args.get = true;
args.getInner = true;
// Do preprocessing // Do preprocessing
if (!args.no_events) if (!args.no_events)
@ -13310,12 +13829,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}, },
getContainer : function() { getContainer : function() {
var t = this; var self = this;
if (!t.container) if (!self.container)
t.container = DOM.get(t.editorContainer || t.id + '_parent'); self.container = DOM.get(self.editorContainer || self.id + '_parent');
return t.container; return self.container;
}, },
getContentAreaContainer : function() { getContentAreaContainer : function() {
@ -13327,125 +13846,125 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}, },
getWin : function() { getWin : function() {
var t = this, e; var self = this, elm;
if (!t.contentWindow) { if (!self.contentWindow) {
e = DOM.get(t.id + "_ifr"); elm = DOM.get(self.id + "_ifr");
if (e) if (elm)
t.contentWindow = e.contentWindow; self.contentWindow = elm.contentWindow;
} }
return t.contentWindow; return self.contentWindow;
}, },
getDoc : function() { getDoc : function() {
var t = this, w; var self = this, win;
if (!t.contentDocument) { if (!self.contentDocument) {
w = t.getWin(); win = self.getWin();
if (w) if (win)
t.contentDocument = w.document; self.contentDocument = win.document;
} }
return t.contentDocument; return self.contentDocument;
}, },
getBody : function() { getBody : function() {
return this.bodyElement || this.getDoc().body; return this.bodyElement || this.getDoc().body;
}, },
convertURL : function(u, n, e) { convertURL : function(url, name, elm) {
var t = this, s = t.settings; var self = this, settings = self.settings;
// Use callback instead // Use callback instead
if (s.urlconverter_callback) if (settings.urlconverter_callback)
return t.execCallback('urlconverter_callback', u, e, true, n); return self.execCallback('urlconverter_callback', url, elm, true, name);
// Don't convert link href since thats the CSS files that gets loaded into the editor also skip local file URLs // Don't convert link href since thats the CSS files that gets loaded into the editor also skip local file URLs
if (!s.convert_urls || (e && e.nodeName == 'LINK') || u.indexOf('file:') === 0) if (!settings.convert_urls || (elm && elm.nodeName == 'LINK') || url.indexOf('file:') === 0)
return u; return url;
// Convert to relative // Convert to relative
if (s.relative_urls) if (settings.relative_urls)
return t.documentBaseURI.toRelative(u); return self.documentBaseURI.toRelative(url);
// Convert to absolute // Convert to absolute
u = t.documentBaseURI.toAbsolute(u, s.remove_script_host); url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host);
return u; return url;
}, },
addVisual : function(e) { addVisual : function(elm) {
var t = this, s = t.settings; var self = this, settings = self.settings, dom = self.dom, cls;
e = e || t.getBody(); elm = elm || self.getBody();
if (!is(t.hasVisual)) if (!is(self.hasVisual))
t.hasVisual = s.visual; self.hasVisual = settings.visual;
each(t.dom.select('table,a', e), function(e) { each(dom.select('table,a', elm), function(elm) {
var v; var value;
switch (e.nodeName) { switch (elm.nodeName) {
case 'TABLE': case 'TABLE':
v = t.dom.getAttrib(e, 'border'); cls = settings.visual_table_class || 'mceItemTable';
value = dom.getAttrib(elm, 'border');
if (!v || v == '0') { if (!value || value == '0') {
if (t.hasVisual) if (self.hasVisual)
t.dom.addClass(e, s.visual_table_class); dom.addClass(elm, cls);
else else
t.dom.removeClass(e, s.visual_table_class); dom.removeClass(elm, cls);
} }
return; return;
case 'A': case 'A':
v = t.dom.getAttrib(e, 'name'); value = dom.getAttrib(elm, 'name');
cls = 'mceItemAnchor';
if (v) { if (value) {
if (t.hasVisual) if (self.hasVisual)
t.dom.addClass(e, 'mceItemAnchor'); dom.addClass(elm, cls);
else else
t.dom.removeClass(e, 'mceItemAnchor'); dom.removeClass(elm, cls);
} }
return; return;
} }
}); });
t.onVisualAid.dispatch(t, e, t.hasVisual); self.onVisualAid.dispatch(self, elm, self.hasVisual);
}, },
remove : function() { remove : function() {
var t = this, e = t.getContainer(); var self = this, elm = self.getContainer();
if (!t.removed) { if (!self.removed) {
t.removed = 1; // Cancels post remove event execution self.removed = 1; // Cancels post remove event execution
t.hide(); self.hide();
// Remove all events
// Don't clear the window or document if content editable // Don't clear the window or document if content editable
// is enabled since other instances might still be present // is enabled since other instances might still be present
if (!t.settings.content_editable) { if (!self.settings.content_editable) {
Event.clear(t.getWin()); Event.clear(self.getWin());
Event.clear(t.getDoc()); Event.clear(self.getDoc());
} }
Event.clear(t.getBody()); Event.clear(self.getBody());
Event.clear(t.formElement); Event.clear(self.formElement);
Event.unbind(e); Event.unbind(elm);
t.execCallback('remove_instance_callback', t); self.execCallback('remove_instance_callback', self);
t.onRemove.dispatch(t); self.onRemove.dispatch(self);
// Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command // Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command
t.onExecCommand.listeners = []; self.onExecCommand.listeners = [];
tinymce.remove(t); tinymce.remove(self);
DOM.remove(e); DOM.remove(elm);
} }
}, },
@ -13492,343 +14011,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Internal functions // Internal functions
_addEvents : function() {
// 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset
var t = this, i, s = t.settings, dom = t.dom, lo = {
mouseup : 'onMouseUp',
mousedown : 'onMouseDown',
click : 'onClick',
keyup : 'onKeyUp',
keydown : 'onKeyDown',
keypress : 'onKeyPress',
submit : 'onSubmit',
reset : 'onReset',
contextmenu : 'onContextMenu',
dblclick : 'onDblClick',
paste : 'onPaste' // Doesn't work in all browsers yet
};
function eventHandler(e, o) {
var ty = e.type;
// Don't fire events when it's removed
if (t.removed)
return;
// Generic event handler
if (t.onEvent.dispatch(t, e, o) !== false) {
// Specific event handler
t[lo[e.fakeType || e.type]].dispatch(t, e, o);
}
};
// Add DOM events
each(lo, function(v, k) {
switch (k) {
case 'contextmenu':
dom.bind(t.getDoc(), k, eventHandler);
break;
case 'paste':
dom.bind(t.getBody(), k, function(e) {
eventHandler(e);
});
break;
case 'submit':
case 'reset':
dom.bind(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);
break;
default:
dom.bind(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);
}
});
dom.bind(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {
t.focus(true);
});
// Fixes bug where a specified document_base_uri could result in broken images
// This will also fix drag drop of images in Gecko
if (tinymce.isGecko) {
dom.bind(t.getDoc(), 'DOMNodeInserted', function(e) {
var v;
e = e.target;
if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('data-mce-src')))
e.src = t.documentBaseURI.toAbsolute(v);
});
}
// Set various midas options in Gecko
if (isGecko) {
function setOpts() {
var t = this, d = t.getDoc(), s = t.settings;
if (isGecko && !s.readonly) {
t._refreshContentEditable();
try {
// Try new Gecko method
d.execCommand("styleWithCSS", 0, false);
} catch (ex) {
// Use old method
if (!t._isHidden())
try {d.execCommand("useCSS", 0, true);} catch (ex) {}
}
if (!s.table_inline_editing)
try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}
if (!s.object_resizing)
try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {}
}
};
t.onBeforeExecCommand.add(setOpts);
t.onMouseDown.add(setOpts);
}
// Add node change handlers
t.onMouseUp.add(t.nodeChanged);
//t.onClick.add(t.nodeChanged);
t.onKeyUp.add(function(ed, e) {
var c = e.keyCode;
if ((c >= 33 && c <= 36) || (c >= 37 && c <= 40) || c == 13 || c == 45 || c == 46 || c == 8 || (tinymce.isMac && (c == 91 || c == 93)) || e.ctrlKey)
t.nodeChanged();
});
// Add block quote deletion handler
t.onKeyDown.add(function(ed, e) {
if (e.keyCode != VK.BACKSPACE)
return;
var rng = ed.selection.getRng();
if (!rng.collapsed)
return;
var n = rng.startContainer;
var offset = rng.startOffset;
while (n && n.nodeType && n.nodeType != 1 && n.parentNode)
n = n.parentNode;
// Is the cursor at the beginning of a blockquote?
if (n && n.parentNode && n.parentNode.tagName === 'BLOCKQUOTE' && n.parentNode.firstChild == n && offset == 0) {
// Remove the blockquote
ed.formatter.toggle('blockquote', null, n.parentNode);
// Move the caret to the beginning of n
rng.setStart(n, 0);
rng.setEnd(n, 0);
ed.selection.setRng(rng);
ed.selection.collapse(false);
}
});
// Add reset handler
t.onReset.add(function() {
t.setContent(t.startContent, {format : 'raw'});
});
// Add shortcuts
if (s.custom_shortcuts) {
if (s.custom_undo_redo_keyboard_shortcuts) {
t.addShortcut('ctrl+z', t.getLang('undo_desc'), 'Undo');
t.addShortcut('ctrl+y', t.getLang('redo_desc'), 'Redo');
}
// Add default shortcuts for gecko
t.addShortcut('ctrl+b', t.getLang('bold_desc'), 'Bold');
t.addShortcut('ctrl+i', t.getLang('italic_desc'), 'Italic');
t.addShortcut('ctrl+u', t.getLang('underline_desc'), 'Underline');
// BlockFormat shortcuts keys
for (i=1; i<=6; i++)
t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, 'h' + i]);
t.addShortcut('ctrl+7', '', ['FormatBlock', false, 'p']);
t.addShortcut('ctrl+8', '', ['FormatBlock', false, 'div']);
t.addShortcut('ctrl+9', '', ['FormatBlock', false, 'address']);
function find(e) {
var v = null;
if (!e.altKey && !e.ctrlKey && !e.metaKey)
return v;
each(t.shortcuts, function(o) {
if (tinymce.isMac && o.ctrl != e.metaKey)
return;
else if (!tinymce.isMac && o.ctrl != e.ctrlKey)
return;
if (o.alt != e.altKey)
return;
if (o.shift != e.shiftKey)
return;
if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) {
v = o;
return false;
}
});
return v;
};
t.onKeyUp.add(function(ed, e) {
var o = find(e);
if (o)
return Event.cancel(e);
});
t.onKeyPress.add(function(ed, e) {
var o = find(e);
if (o)
return Event.cancel(e);
});
t.onKeyDown.add(function(ed, e) {
var o = find(e);
if (o) {
o.func.call(o.scope);
return Event.cancel(e);
}
});
}
if (tinymce.isIE) {
// Fix so resize will only update the width and height attributes not the styles of an image
// It will also block mceItemNoResize items
dom.bind(t.getDoc(), 'controlselect', function(e) {
var re = t.resizeInfo, cb;
e = e.target;
// Don't do this action for non image elements
if (e.nodeName !== 'IMG')
return;
if (re)
dom.unbind(re.node, re.ev, re.cb);
if (!dom.hasClass(e, 'mceItemNoResize')) {
ev = 'resizeend';
cb = dom.bind(e, ev, function(e) {
var v;
e = e.target;
if (v = dom.getStyle(e, 'width')) {
dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, ''));
dom.setStyle(e, 'width', '');
}
if (v = dom.getStyle(e, 'height')) {
dom.setAttrib(e, 'height', v.replace(/[^0-9%]+/g, ''));
dom.setStyle(e, 'height', '');
}
});
} else {
ev = 'resizestart';
cb = dom.bind(e, 'resizestart', Event.cancel, Event);
}
re = t.resizeInfo = {
node : e,
ev : ev,
cb : cb
};
});
}
if (tinymce.isOpera) {
t.onClick.add(function(ed, e) {
Event.prevent(e);
});
}
// Add custom undo/redo handlers
if (s.custom_undo_redo) {
function addUndo() {
t.undoManager.typing = false;
t.undoManager.add();
};
var focusLostFunc = tinymce.isGecko ? 'blur' : 'focusout';
dom.bind(t.getDoc(), focusLostFunc, function(e){
if (!t.removed && t.undoManager.typing)
addUndo();
});
// Add undo level when contents is drag/dropped within the editor
t.dom.bind(t.dom.getRoot(), 'dragend', function(e) {
addUndo();
});
t.onKeyUp.add(function(ed, e) {
var keyCode = e.keyCode;
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45 || e.ctrlKey)
addUndo();
});
t.onKeyDown.add(function(ed, e) {
var keyCode = e.keyCode, sel;
if (keyCode == 8) {
sel = t.getDoc().selection;
// Fix IE control + backspace browser bug
if (sel && sel.createRange && sel.createRange().item) {
t.undoManager.beforeChange();
ed.dom.remove(sel.createRange().item(0));
addUndo();
return Event.cancel(e);
}
}
// Is caracter positon keys left,right,up,down,home,end,pgdown,pgup,enter
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45) {
// Add position before enter key is pressed, used by IE since it still uses the default browser behavior
// Todo: Remove this once we normalize enter behavior on IE
if (tinymce.isIE && keyCode == 13)
t.undoManager.beforeChange();
if (t.undoManager.typing)
addUndo();
return;
}
// If key isn't shift,ctrl,alt,capslock,metakey
if ((keyCode < 16 || keyCode > 20) && keyCode != 224 && keyCode != 91 && !t.undoManager.typing) {
t.undoManager.beforeChange();
t.undoManager.typing = true;
t.undoManager.add();
}
});
t.onMouseDown.add(function() {
if (t.undoManager.typing)
addUndo();
});
}
},
_refreshContentEditable : function() { _refreshContentEditable : function() {
var self = this, body, parent; var self = this, body, parent;
@ -13852,14 +14034,294 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Weird, wheres that cursor selection? // Weird, wheres that cursor selection?
s = this.selection.getSel(); s = this.selection.getSel();
return (!s || !s.rangeCount || s.rangeCount == 0); return (!s || !s.rangeCount || s.rangeCount === 0);
} }
}); });
})(tinymce); })(tinymce);
(function(tinymce) {
var each = tinymce.each;
tinymce.Editor.prototype.setupEvents = function() {
var self = this, settings = self.settings;
// Add events to the editor
each([
'onPreInit',
'onBeforeRenderUI',
'onPostRender',
'onLoad',
'onInit',
'onRemove',
'onActivate',
'onDeactivate',
'onClick',
'onEvent',
'onMouseUp',
'onMouseDown',
'onDblClick',
'onKeyDown',
'onKeyUp',
'onKeyPress',
'onContextMenu',
'onSubmit',
'onReset',
'onPaste',
'onPreProcess',
'onPostProcess',
'onBeforeSetContent',
'onBeforeGetContent',
'onSetContent',
'onGetContent',
'onLoadContent',
'onSaveContent',
'onNodeChange',
'onChange',
'onBeforeExecCommand',
'onExecCommand',
'onUndo',
'onRedo',
'onVisualAid',
'onSetProgressState',
'onSetAttrib'
], function(name) {
self[name] = new tinymce.util.Dispatcher(self);
});
// Handle legacy cleanup_callback option
if (settings.cleanup_callback) {
self.onBeforeSetContent.add(function(ed, o) {
o.content = ed.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
});
self.onPreProcess.add(function(ed, o) {
if (o.set)
ed.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);
if (o.get)
ed.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);
});
self.onPostProcess.add(function(ed, o) {
if (o.set)
o.content = ed.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
if (o.get)
o.content = ed.execCallback('cleanup_callback', 'get_from_editor', o.content, o);
});
}
// Handle legacy save_callback option
if (settings.save_callback) {
self.onGetContent.add(function(ed, o) {
if (o.save)
o.content = ed.execCallback('save_callback', ed.id, o.content, ed.getBody());
});
}
// Handle legacy handle_event_callback option
if (settings.handle_event_callback) {
self.onEvent.add(function(ed, e, o) {
if (self.execCallback('handle_event_callback', e, ed, o) === false)
Event.cancel(e);
});
}
// Handle legacy handle_node_change_callback option
if (settings.handle_node_change_callback) {
self.onNodeChange.add(function(ed, cm, n) {
ed.execCallback('handle_node_change_callback', ed.id, n, -1, -1, true, ed.selection.isCollapsed());
});
}
// Handle legacy save_callback option
if (settings.save_callback) {
self.onSaveContent.add(function(ed, o) {
var h = ed.execCallback('save_callback', ed.id, o.content, ed.getBody());
if (h)
o.content = h;
});
}
// Handle legacy onchange_callback option
if (settings.onchange_callback) {
self.onChange.add(function(ed, l) {
ed.execCallback('onchange_callback', ed, l);
});
}
};
tinymce.Editor.prototype.bindNativeEvents = function() {
// 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset
var self = this, i, settings = self.settings, dom = self.dom, nativeToDispatcherMap;
nativeToDispatcherMap = {
mouseup : 'onMouseUp',
mousedown : 'onMouseDown',
click : 'onClick',
keyup : 'onKeyUp',
keydown : 'onKeyDown',
keypress : 'onKeyPress',
submit : 'onSubmit',
reset : 'onReset',
contextmenu : 'onContextMenu',
dblclick : 'onDblClick',
paste : 'onPaste' // Doesn't work in all browsers yet
};
// Handler that takes a native event and sends it out to a dispatcher like onKeyDown
function eventHandler(evt, args) {
var type = evt.type;
// Don't fire events when it's removed
if (self.removed)
return;
// Sends the native event out to a global dispatcher then to the specific event dispatcher
if (self.onEvent.dispatch(self, evt, args) !== false) {
self[nativeToDispatcherMap[evt.fakeType || evt.type]].dispatch(self, evt, args);
}
};
// Opera doesn't support focus event for contentEditable elements so we need to fake it
function doOperaFocus(e) {
self.focus(true);
};
function nodeChanged() {
// Normalize selection for example <b>a</b><i>|a</i> becomes <b>a|</b><i>a</i>
self.selection.normalize();
self.nodeChanged();
}
// Add DOM events
each(nativeToDispatcherMap, function(dispatcherName, nativeName) {
var root = settings.content_editable ? self.getBody() : self.getDoc();
switch (nativeName) {
case 'contextmenu':
dom.bind(root, nativeName, eventHandler);
break;
case 'paste':
dom.bind(self.getBody(), nativeName, eventHandler);
break;
case 'submit':
case 'reset':
dom.bind(self.getElement().form || tinymce.DOM.getParent(self.id, 'form'), nativeName, eventHandler);
break;
default:
dom.bind(root, nativeName, eventHandler);
}
});
// Set the editor as active when focused
dom.bind(settings.content_editable ? self.getBody() : (tinymce.isGecko ? self.getDoc() : self.getWin()), 'focus', function(e) {
self.focus(true);
});
if (settings.content_editable && tinymce.isOpera) {
dom.bind(self.getBody(), 'click', doOperaFocus);
dom.bind(self.getBody(), 'keydown', doOperaFocus);
}
// Add node change handler
self.onMouseUp.add(nodeChanged);
self.onKeyUp.add(function(ed, e) {
var keyCode = e.keyCode;
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45 || keyCode == 46 || keyCode == 8 || (tinymce.isMac && (keyCode == 91 || keyCode == 93)) || e.ctrlKey)
nodeChanged();
});
// Add reset handler
self.onReset.add(function() {
self.setContent(self.startContent, {format : 'raw'});
});
// Add shortcuts
function handleShortcut(e, execute) {
if (e.altKey || e.ctrlKey || e.metaKey) {
each(self.shortcuts, function(shortcut) {
var ctrlState = tinymce.isMac ? e.metaKey : e.ctrlKey;
if (shortcut.ctrl != ctrlState || shortcut.alt != e.altKey || shortcut.shift != e.shiftKey)
return;
if (e.keyCode == shortcut.keyCode || (e.charCode && e.charCode == shortcut.charCode)) {
e.preventDefault();
if (execute) {
shortcut.func.call(shortcut.scope);
}
return true;
}
});
}
};
self.onKeyUp.add(function(ed, e) {
handleShortcut(e);
});
self.onKeyPress.add(function(ed, e) {
handleShortcut(e);
});
self.onKeyDown.add(function(ed, e) {
handleShortcut(e, true);
});
if (tinymce.isOpera) {
self.onClick.add(function(ed, e) {
e.preventDefault();
});
}
};
})(tinymce);
(function(tinymce) { (function(tinymce) {
// Added for compression purposes // Added for compression purposes
var each = tinymce.each, undefined, TRUE = true, FALSE = false; var each = tinymce.each, undef, TRUE = true, FALSE = false;
tinymce.EditorCommands = function(editor) { tinymce.EditorCommands = function(editor) {
var dom = editor.dom, var dom = editor.dom,
@ -13922,10 +14384,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Private methods // Private methods
function execNativeCommand(command, ui, value) { function execNativeCommand(command, ui, value) {
if (ui === undefined) if (ui === undef)
ui = FALSE; ui = FALSE;
if (value === undefined) if (value === undef)
value = null; value = null;
return editor.getDoc().execCommand(command, ui, value); return editor.getDoc().execCommand(command, ui, value);
@ -13936,7 +14398,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}; };
function toggleFormat(name, value) { function toggleFormat(name, value) {
formatter.toggle(name, value ? {value : value} : undefined); formatter.toggle(name, value ? {value : value} : undef);
}; };
function storeSelection(type) { function storeSelection(type) {
@ -14336,9 +14798,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Override justify commands // Override justify commands
'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull' : function(command) { 'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull' : function(command) {
var name = 'align' + command.substring(7); var name = 'align' + command.substring(7);
// Use Formatter.matchNode instead of Formatter.match so that we don't match on parent node. This fixes bug where for both left var nodes = selection.isCollapsed() ? [dom.getParent(selection.getNode(), dom.isBlock)] : selection.getSelectedBlocks();
// and right align buttons can be active. This could occur when selected nodes have align right and the parent has align left.
var nodes = selection.isCollapsed() ? [selection.getNode()] : selection.getSelectedBlocks();
var matches = tinymce.map(nodes, function(node) { var matches = tinymce.map(nodes, function(node) {
return !!formatter.matchNode(node, name); return !!formatter.matchNode(node, name);
}); });
@ -14389,7 +14849,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}, 'value'); }, 'value');
// Add undo manager logic // Add undo manager logic
if (settings.custom_undo_redo) {
addCommands({ addCommands({
Undo : function() { Undo : function() {
editor.undoManager.undo(); editor.undoManager.undo();
@ -14399,7 +14858,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
editor.undoManager.redo(); editor.undoManager.redo();
} }
}); });
}
}; };
})(tinymce); })(tinymce);
@ -14407,21 +14865,116 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
var Dispatcher = tinymce.util.Dispatcher; var Dispatcher = tinymce.util.Dispatcher;
tinymce.UndoManager = function(editor) { tinymce.UndoManager = function(editor) {
var self, index = 0, data = [], beforeBookmark; var self, index = 0, data = [], beforeBookmark, onAdd, onUndo, onRedo;
function getContent() { function getContent() {
// Remove whitespace before/after and remove pure bogus nodes // Remove whitespace before/after and remove pure bogus nodes
return tinymce.trim(editor.getContent({format : 'raw', no_events : 1}).replace(/<span[^>]+data-mce-bogus[^>]+>[\u200B\uFEFF]+<\/span>/g, '')); return tinymce.trim(editor.getContent({format : 'raw', no_events : 1}).replace(/<span[^>]+data-mce-bogus[^>]+>[\u200B\uFEFF]+<\/span>/g, ''));
}; };
return self = { function addNonTypingUndoLevel() {
self.typing = false;
self.add();
};
// Create event instances
onAdd = new Dispatcher(self);
onUndo = new Dispatcher(self);
onRedo = new Dispatcher(self);
// Pass though onAdd event from UndoManager to Editor as onChange
onAdd.add(function(undoman, level) {
if (undoman.hasUndo())
return editor.onChange.dispatch(editor, level, undoman);
});
// Pass though onUndo event from UndoManager to Editor
onUndo.add(function(undoman, level) {
return editor.onUndo.dispatch(editor, level, undoman);
});
// Pass though onRedo event from UndoManager to Editor
onRedo.add(function(undoman, level) {
return editor.onRedo.dispatch(editor, level, undoman);
});
// Add initial undo level when the editor is initialized
editor.onInit.add(function() {
self.add();
});
// Get position before an execCommand is processed
editor.onBeforeExecCommand.add(function(ed, cmd, ui, val, args) {
if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!args || !args.skip_undo)) {
self.beforeChange();
}
});
// Add undo level after an execCommand call was made
editor.onExecCommand.add(function(ed, cmd, ui, val, args) {
if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!args || !args.skip_undo)) {
self.add();
}
});
// Add undo level on save contents, drag end and blur/focusout
editor.onSaveContent.add(addNonTypingUndoLevel);
editor.dom.bind(editor.dom.getRoot(), 'dragend', addNonTypingUndoLevel);
editor.dom.bind(editor.getDoc(), tinymce.isGecko ? 'blur' : 'focusout', function(e) {
if (!editor.removed && self.typing) {
addNonTypingUndoLevel();
}
});
editor.onKeyUp.add(function(editor, e) {
var keyCode = e.keyCode;
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 45 || keyCode == 13 || e.ctrlKey) {
addNonTypingUndoLevel();
}
});
editor.onKeyDown.add(function(editor, e) {
var keyCode = e.keyCode;
// Is caracter positon keys left,right,up,down,home,end,pgdown,pgup,enter
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 45) {
if (self.typing) {
addNonTypingUndoLevel();
}
return;
}
// If key isn't shift,ctrl,alt,capslock,metakey
if ((keyCode < 16 || keyCode > 20) && keyCode != 224 && keyCode != 91 && !self.typing) {
self.beforeChange();
self.typing = true;
self.add();
}
});
editor.onMouseDown.add(function(editor, e) {
if (self.typing) {
addNonTypingUndoLevel();
}
});
// Add keyboard shortcuts for undo/redo keys
editor.addShortcut('ctrl+z', 'undo_desc', 'Undo');
editor.addShortcut('ctrl+y', 'redo_desc', 'Redo');
self = {
// Explose for debugging reasons
data : data,
typing : false, typing : false,
onAdd : new Dispatcher(self), onAdd : onAdd,
onUndo : new Dispatcher(self), onUndo : onUndo,
onRedo : new Dispatcher(self), onRedo : onRedo,
beforeChange : function() { beforeChange : function() {
beforeBookmark = editor.selection.getBookmark(2, true); beforeBookmark = editor.selection.getBookmark(2, true);
@ -14518,22 +15071,22 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
return index < data.length - 1 && !this.typing; return index < data.length - 1 && !this.typing;
} }
}; };
return self;
}; };
})(tinymce); })(tinymce);
tinymce.ForceBlocks = function(editor) { tinymce.ForceBlocks = function(editor) {
var settings = editor.settings, dom = editor.dom, selection = editor.selection, blockElements = editor.schema.getBlockElements(); var settings = editor.settings, dom = editor.dom, selection = editor.selection, blockElements = editor.schema.getBlockElements();
// Force root blocks
if (settings.forced_root_block) {
function addRootBlocks() { function addRootBlocks() {
var node = selection.getStart(), rootNode = editor.getBody(), rng, startContainer, startOffset, endContainer, endOffset, rootBlockNode, tempNode, offset = -0xFFFFFF; var node = selection.getStart(), rootNode = editor.getBody(), rng, startContainer, startOffset, endContainer, endOffset, rootBlockNode, tempNode, offset = -0xFFFFFF, wrapped;
if (!node || node.nodeType !== 1 || !settings.forced_root_block) if (!node || node.nodeType !== 1 || !settings.forced_root_block)
return; return;
// Check if node is wrapped in block // Check if node is wrapped in block
while (node != rootNode) { while (node && node != rootNode) {
if (blockElements[node.nodeName]) if (blockElements[node.nodeName])
return; return;
@ -14567,11 +15120,13 @@ tinymce.ForceBlocks = function(editor) {
} }
// Wrap non block elements and text nodes // Wrap non block elements and text nodes
for (node = rootNode.firstChild; node; node) { node = rootNode.firstChild;
while (node) {
if (node.nodeType === 3 || (node.nodeType == 1 && !blockElements[node.nodeName])) { if (node.nodeType === 3 || (node.nodeType == 1 && !blockElements[node.nodeName])) {
if (!rootBlockNode) { if (!rootBlockNode) {
rootBlockNode = dom.create(settings.forced_root_block); rootBlockNode = dom.create(settings.forced_root_block);
node.parentNode.insertBefore(rootBlockNode, node); node.parentNode.insertBefore(rootBlockNode, node);
wrapped = true;
} }
tempNode = node; tempNode = node;
@ -14603,11 +15158,16 @@ tinymce.ForceBlocks = function(editor) {
} }
} }
// Only trigger nodeChange when we wrapped nodes to prevent a forever loop
if (wrapped) {
editor.nodeChanged(); editor.nodeChanged();
}
}; };
// Force root blocks
if (settings.forced_root_block) {
editor.onKeyUp.add(addRootBlocks); editor.onKeyUp.add(addRootBlocks);
editor.onClick.add(addRootBlocks); editor.onNodeChange.add(addRootBlocks);
} }
}; };
@ -14703,6 +15263,8 @@ tinymce.ForceBlocks = function(editor) {
if (v = ed.getParam('skin_variant')) if (v = ed.getParam('skin_variant'))
s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1); s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1);
s['class'] += ed.settings.directionality == "rtl" ? ' mceRtl' : '';
id = t.prefix + id; id = t.prefix + id;
cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu; cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu;
c = t.controls[id] = new cls(id, s); c = t.controls[id] = new cls(id, s);
@ -15121,20 +15683,8 @@ tinymce.ForceBlocks = function(editor) {
MCE_ATTR_RE = /^(src|href|style)$/, MCE_ATTR_RE = /^(src|href|style)$/,
FALSE = false, FALSE = false,
TRUE = true, TRUE = true,
undefined; undef,
getContentEditable = dom.getContentEditable;
// Returns the content editable state of a node
function getContentEditable(node) {
var contentEditable = node.getAttribute("data-mce-contenteditable");
// Check for fake content editable
if (contentEditable && contentEditable !== "inherit") {
return contentEditable;
}
// Check for real content editable
return node.contentEditable !== "inherit" ? node.contentEditable : null;
};
function isArray(obj) { function isArray(obj) {
return obj instanceof Array; return obj instanceof Array;
@ -15148,6 +15698,103 @@ tinymce.ForceBlocks = function(editor) {
return node.nodeType === 1 && node.id === '_mce_caret'; return node.nodeType === 1 && node.id === '_mce_caret';
}; };
function defaultFormats() {
register({
alignleft : [
{selector : 'figure,p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}, defaultBlock: 'div'},
{selector : 'img,table', collapsed : false, styles : {'float' : 'left'}}
],
aligncenter : [
{selector : 'figure,p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}, defaultBlock: 'div'},
{selector : 'img', collapsed : false, styles : {display : 'block', marginLeft : 'auto', marginRight : 'auto'}},
{selector : 'table', collapsed : false, styles : {marginLeft : 'auto', marginRight : 'auto'}}
],
alignright : [
{selector : 'figure,p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}, defaultBlock: 'div'},
{selector : 'img,table', collapsed : false, styles : {'float' : 'right'}}
],
alignfull : [
{selector : 'figure,p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'justify'}, defaultBlock: 'div'}
],
bold : [
{inline : 'strong', remove : 'all'},
{inline : 'span', styles : {fontWeight : 'bold'}},
{inline : 'b', remove : 'all'}
],
italic : [
{inline : 'em', remove : 'all'},
{inline : 'span', styles : {fontStyle : 'italic'}},
{inline : 'i', remove : 'all'}
],
underline : [
{inline : 'span', styles : {textDecoration : 'underline'}, exact : true},
{inline : 'u', remove : 'all'}
],
strikethrough : [
{inline : 'span', styles : {textDecoration : 'line-through'}, exact : true},
{inline : 'strike', remove : 'all'}
],
forecolor : {inline : 'span', styles : {color : '%value'}, wrap_links : false},
hilitecolor : {inline : 'span', styles : {backgroundColor : '%value'}, wrap_links : false},
fontname : {inline : 'span', styles : {fontFamily : '%value'}},
fontsize : {inline : 'span', styles : {fontSize : '%value'}},
fontsize_class : {inline : 'span', attributes : {'class' : '%value'}},
blockquote : {block : 'blockquote', wrapper : 1, remove : 'all'},
subscript : {inline : 'sub'},
superscript : {inline : 'sup'},
link : {inline : 'a', selector : 'a', remove : 'all', split : true, deep : true,
onmatch : function(node) {
return true;
},
onformat : function(elm, fmt, vars) {
each(vars, function(value, key) {
dom.setAttrib(elm, key, value);
});
}
},
removeformat : [
{selector : 'b,strong,em,i,font,u,strike', remove : 'all', split : true, expand : false, block_expand : true, deep : true},
{selector : 'span', attributes : ['style', 'class'], remove : 'empty', split : true, expand : false, deep : true},
{selector : '*', attributes : ['style', 'class'], split : false, expand : false, deep : true}
]
});
// Register default block formats
each('p h1 h2 h3 h4 h5 h6 div address pre div code dt dd samp'.split(/\s/), function(name) {
register(name, {block : name, remove : 'all'});
});
// Register user defined formats
register(ed.settings.formats);
};
function addKeyboardShortcuts() {
// Add some inline shortcuts
ed.addShortcut('ctrl+b', 'bold_desc', 'Bold');
ed.addShortcut('ctrl+i', 'italic_desc', 'Italic');
ed.addShortcut('ctrl+u', 'underline_desc', 'Underline');
// BlockFormat shortcuts keys
for (var i = 1; i <= 6; i++) {
ed.addShortcut('ctrl+' + i, '', ['FormatBlock', false, 'h' + i]);
}
ed.addShortcut('ctrl+7', '', ['FormatBlock', false, 'p']);
ed.addShortcut('ctrl+8', '', ['FormatBlock', false, 'div']);
ed.addShortcut('ctrl+9', '', ['FormatBlock', false, 'address']);
};
// Public functions // Public functions
function get(name) { function get(name) {
@ -15167,15 +15814,15 @@ tinymce.ForceBlocks = function(editor) {
each(format, function(format) { each(format, function(format) {
// Set deep to false by default on selector formats this to avoid removing // Set deep to false by default on selector formats this to avoid removing
// alignment on images inside paragraphs when alignment is changed on paragraphs // alignment on images inside paragraphs when alignment is changed on paragraphs
if (format.deep === undefined) if (format.deep === undef)
format.deep = !format.selector; format.deep = !format.selector;
// Default to true // Default to true
if (format.split === undefined) if (format.split === undef)
format.split = !format.selector || format.inline; format.split = !format.selector || format.inline;
// Default to true // Default to true
if (format.remove === undefined && format.selector && !format.inline) if (format.remove === undef && format.selector && !format.inline)
format.remove = 'none'; format.remove = 'none';
// Mark format as a mixed format inline + block level // Mark format as a mixed format inline + block level
@ -15248,7 +15895,7 @@ tinymce.ForceBlocks = function(editor) {
function findSelectionEnd(start, end) { function findSelectionEnd(start, end) {
var walker = new TreeWalker(end); var walker = new TreeWalker(end);
for (node = walker.current(); node; node = walker.prev()) { for (node = walker.current(); node; node = walker.prev()) {
if (node.childNodes.length > 1 || node == start) { if (node.childNodes.length > 1 || node == start || node.tagName == 'BR') {
return node; return node;
} }
} }
@ -15260,7 +15907,7 @@ tinymce.ForceBlocks = function(editor) {
var start = rng.startContainer; var start = rng.startContainer;
var end = rng.endContainer; var end = rng.endContainer;
if (start != end && rng.endOffset == 0) { if (start != end && rng.endOffset === 0) {
var newEnd = findSelectionEnd(start, end); var newEnd = findSelectionEnd(start, end);
var endOffset = newEnd.nodeType == 3 ? newEnd.length : newEnd.childNodes.length; var endOffset = newEnd.nodeType == 3 ? newEnd.length : newEnd.childNodes.length;
@ -15720,7 +16367,7 @@ tinymce.ForceBlocks = function(editor) {
}; };
function removeRngStyle(rng) { function removeRngStyle(rng) {
var startContainer, endContainer; var startContainer, endContainer, node;
rng = expandRng(rng, formatList, TRUE); rng = expandRng(rng, formatList, TRUE);
@ -15729,6 +16376,12 @@ tinymce.ForceBlocks = function(editor) {
endContainer = getContainer(rng); endContainer = getContainer(rng);
if (startContainer != endContainer) { if (startContainer != endContainer) {
// WebKit will render the table incorrectly if we wrap a TD in a SPAN so lets see if the can use the first child instead
// This will happen if you tripple click a table cell and use remove formatting
if (/^(TR|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) {
startContainer = (startContainer.nodeName == "TD" ? startContainer.firstChild : startContainer.firstChild.firstChild) || startContainer;
}
// Wrap start/end nodes in span element since these might be cloned/moved // Wrap start/end nodes in span element since these might be cloned/moved
startContainer = wrap(startContainer, 'span', {id : '_start', 'data-mce-type' : 'bookmark'}); startContainer = wrap(startContainer, 'span', {id : '_start', 'data-mce-type' : 'bookmark'});
endContainer = wrap(endContainer, 'span', {id : '_end', 'data-mce-type' : 'bookmark'}); endContainer = wrap(endContainer, 'span', {id : '_end', 'data-mce-type' : 'bookmark'});
@ -15790,20 +16443,12 @@ tinymce.ForceBlocks = function(editor) {
ed.nodeChanged(); ed.nodeChanged();
} else } else
performCaretAction('remove', name, vars); performCaretAction('remove', name, vars);
// Removed this logic since it breaks unit tests and produces empty caret elements since they will be destroyed in the cleanup process
// Also there must be a better way to rerender a table and I couldn't reproduce the case causing this might be some old WebKit
/*
// When you remove formatting from a table cell in WebKit (cell, not the contents of a cell) there is a rendering issue with column width
if (tinymce.isWebKit) {
ed.execCommand('mceCleanup');
}*/
}; };
function toggle(name, vars, node) { function toggle(name, vars, node) {
var fmt = get(name); var fmt = get(name);
if (match(name, vars, node) && (!('toggle' in fmt[0]) || fmt[0]['toggle'])) if (match(name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle))
remove(name, vars, node); remove(name, vars, node);
else else
apply(name, vars, node); apply(name, vars, node);
@ -15823,7 +16468,7 @@ tinymce.ForceBlocks = function(editor) {
// Check all items // Check all items
if (items) { if (items) {
// Non indexed object // Non indexed object
if (items.length === undefined) { if (items.length === undef) {
for (key in items) { for (key in items) {
if (items.hasOwnProperty(key)) { if (items.hasOwnProperty(key)) {
if (item_name === 'attributes') if (item_name === 'attributes')
@ -15961,6 +16606,10 @@ tinymce.ForceBlocks = function(editor) {
canApply : canApply canApply : canApply
}); });
// Initialize
defaultFormats();
addKeyboardShortcuts();
// Private functions // Private functions
function matchName(node, format) { function matchName(node, format) {
@ -16027,15 +16676,15 @@ tinymce.ForceBlocks = function(editor) {
}; };
function expandRng(rng, format, remove) { function expandRng(rng, format, remove) {
var sibling, lastIdx, leaf, var sibling, lastIdx, leaf, endPoint,
startContainer = rng.startContainer, startContainer = rng.startContainer,
startOffset = rng.startOffset, startOffset = rng.startOffset,
endContainer = rng.endContainer, endContainer = rng.endContainer,
endOffset = rng.endOffset, sibling, lastIdx, leaf, endPoint; endOffset = rng.endOffset;
// This function walks up the tree if there is no siblings before/after the node // This function walks up the tree if there is no siblings before/after the node
function findParentContainer(start) { function findParentContainer(start) {
var container, parent, child, sibling, siblingName; var container, parent, child, sibling, siblingName, root;
container = parent = start ? startContainer : endContainer; container = parent = start ? startContainer : endContainer;
siblingName = start ? 'previousSibling' : 'nextSibling'; siblingName = start ? 'previousSibling' : 'nextSibling';
@ -16075,7 +16724,7 @@ tinymce.ForceBlocks = function(editor) {
// This function walks down the tree to find the leaf at the selection. // This function walks down the tree to find the leaf at the selection.
// The offset is also returned as if node initially a leaf, the offset may be in the middle of the text node. // The offset is also returned as if node initially a leaf, the offset may be in the middle of the text node.
function findLeaf(node, offset) { function findLeaf(node, offset) {
if (offset === undefined) if (offset === undef)
offset = node.nodeType === 3 ? node.length : node.childNodes.length; offset = node.nodeType === 3 ? node.length : node.childNodes.length;
while (node && node.hasChildNodes()) { while (node && node.hasChildNodes()) {
node = node.childNodes[offset]; node = node.childNodes[offset];
@ -16118,29 +16767,6 @@ tinymce.ForceBlocks = function(editor) {
return node; return node;
}; };
// Expand to closest contentEditable element
startContainer = findParentContentEditable(startContainer);
endContainer = findParentContentEditable(endContainer);
// Exclude bookmark nodes if possible
if (isBookmarkNode(startContainer.parentNode) || isBookmarkNode(startContainer)) {
startContainer = isBookmarkNode(startContainer) ? startContainer : startContainer.parentNode;
startContainer = startContainer.nextSibling || startContainer;
if (startContainer.nodeType == 3)
startOffset = 0;
}
if (isBookmarkNode(endContainer.parentNode) || isBookmarkNode(endContainer)) {
endContainer = isBookmarkNode(endContainer) ? endContainer : endContainer.parentNode;
endContainer = endContainer.previousSibling || endContainer;
if (endContainer.nodeType == 3)
endOffset = endContainer.length;
}
if (format[0].inline) {
if (rng.collapsed) {
function findWordEndPoint(container, offset, start) { function findWordEndPoint(container, offset, start) {
var walker, node, pos, lastTextNode; var walker, node, pos, lastTextNode;
@ -16203,63 +16829,12 @@ tinymce.ForceBlocks = function(editor) {
return {container: lastTextNode, offset: offset}; return {container: lastTextNode, offset: offset};
} }
} };
// Expand left to closest word boundery
endPoint = findWordEndPoint(startContainer, startOffset, true);
if (endPoint) {
startContainer = endPoint.container;
startOffset = endPoint.offset;
}
// Expand right to closest word boundery
endPoint = findWordEndPoint(endContainer, endOffset);
if (endPoint) {
endContainer = endPoint.container;
endOffset = endPoint.offset;
}
}
// Avoid applying formatting to a trailing space.
leaf = findLeaf(endContainer, endOffset);
if (leaf.node) {
while (leaf.node && leaf.offset === 0 && leaf.node.previousSibling)
leaf = findLeaf(leaf.node.previousSibling);
if (leaf.node && leaf.offset > 0 && leaf.node.nodeType === 3 &&
leaf.node.nodeValue.charAt(leaf.offset - 1) === ' ') {
if (leaf.offset > 1) {
endContainer = leaf.node;
endContainer.splitText(leaf.offset - 1);
} else if (leaf.node.previousSibling) {
// TODO: Figure out why this is in here
//endContainer = leaf.node.previousSibling;
}
}
}
}
// Move start/end point up the tree if the leaves are sharp and if we are in different containers
// Example * becomes !: !<p><b><i>*text</i><i>text*</i></b></p>!
// This will reduce the number of wrapper elements that needs to be created
// Move start point up the tree
if (format[0].inline || format[0].block_expand) {
if (!format[0].inline || (startContainer.nodeType != 3 || startOffset === 0)) {
startContainer = findParentContainer(true);
}
if (!format[0].inline || (endContainer.nodeType != 3 || endOffset === endContainer.nodeValue.length)) {
endContainer = findParentContainer();
}
}
// Expand start/end container to matching selector
if (format[0].selector && format[0].expand !== FALSE && !format[0].inline) {
function findSelectorEndPoint(container, sibling_name) { function findSelectorEndPoint(container, sibling_name) {
var parents, i, y, curFormat; var parents, i, y, curFormat;
if (container.nodeType == 3 && container.nodeValue.length == 0 && container[sibling_name]) if (container.nodeType == 3 && container.nodeValue.length === 0 && container[sibling_name])
container = container[sibling_name]; container = container[sibling_name];
parents = getParents(container); parents = getParents(container);
@ -16279,13 +16854,6 @@ tinymce.ForceBlocks = function(editor) {
return container; return container;
}; };
// Find new startContainer/endContainer if there is better one
startContainer = findSelectorEndPoint(startContainer, 'previousSibling');
endContainer = findSelectorEndPoint(endContainer, 'nextSibling');
}
// Expand start/end container to matching block element or text node
if (format[0].block || format[0].selector) {
function findBlockEndPoint(container, sibling_name, sibling_name2) { function findBlockEndPoint(container, sibling_name, sibling_name2) {
var node; var node;
@ -16318,6 +16886,84 @@ tinymce.ForceBlocks = function(editor) {
return node || container; return node || container;
}; };
// Expand to closest contentEditable element
startContainer = findParentContentEditable(startContainer);
endContainer = findParentContentEditable(endContainer);
// Exclude bookmark nodes if possible
if (isBookmarkNode(startContainer.parentNode) || isBookmarkNode(startContainer)) {
startContainer = isBookmarkNode(startContainer) ? startContainer : startContainer.parentNode;
startContainer = startContainer.nextSibling || startContainer;
if (startContainer.nodeType == 3)
startOffset = 0;
}
if (isBookmarkNode(endContainer.parentNode) || isBookmarkNode(endContainer)) {
endContainer = isBookmarkNode(endContainer) ? endContainer : endContainer.parentNode;
endContainer = endContainer.previousSibling || endContainer;
if (endContainer.nodeType == 3)
endOffset = endContainer.length;
}
if (format[0].inline) {
if (rng.collapsed) {
// Expand left to closest word boundery
endPoint = findWordEndPoint(startContainer, startOffset, true);
if (endPoint) {
startContainer = endPoint.container;
startOffset = endPoint.offset;
}
// Expand right to closest word boundery
endPoint = findWordEndPoint(endContainer, endOffset);
if (endPoint) {
endContainer = endPoint.container;
endOffset = endPoint.offset;
}
}
// Avoid applying formatting to a trailing space.
leaf = findLeaf(endContainer, endOffset);
if (leaf.node) {
while (leaf.node && leaf.offset === 0 && leaf.node.previousSibling)
leaf = findLeaf(leaf.node.previousSibling);
if (leaf.node && leaf.offset > 0 && leaf.node.nodeType === 3 &&
leaf.node.nodeValue.charAt(leaf.offset - 1) === ' ') {
if (leaf.offset > 1) {
endContainer = leaf.node;
endContainer.splitText(leaf.offset - 1);
}
}
}
}
// Move start/end point up the tree if the leaves are sharp and if we are in different containers
// Example * becomes !: !<p><b><i>*text</i><i>text*</i></b></p>!
// This will reduce the number of wrapper elements that needs to be created
// Move start point up the tree
if (format[0].inline || format[0].block_expand) {
if (!format[0].inline || (startContainer.nodeType != 3 || startOffset === 0)) {
startContainer = findParentContainer(true);
}
if (!format[0].inline || (endContainer.nodeType != 3 || endOffset === endContainer.nodeValue.length)) {
endContainer = findParentContainer();
}
}
// Expand start/end container to matching selector
if (format[0].selector && format[0].expand !== FALSE && !format[0].inline) {
// Find new startContainer/endContainer if there is better one
startContainer = findSelectorEndPoint(startContainer, 'previousSibling');
endContainer = findSelectorEndPoint(endContainer, 'nextSibling');
}
// Expand start/end container to matching block element or text node
if (format[0].block || format[0].selector) {
// Find new startContainer/endContainer if there is better one // Find new startContainer/endContainer if there is better one
startContainer = findBlockEndPoint(startContainer, 'previousSibling'); startContainer = findBlockEndPoint(startContainer, 'previousSibling');
endContainer = findBlockEndPoint(endContainer, 'nextSibling'); endContainer = findBlockEndPoint(endContainer, 'nextSibling');
@ -16454,14 +17100,14 @@ tinymce.ForceBlocks = function(editor) {
function removeNode(node, format) { function removeNode(node, format) {
var parentNode = node.parentNode, rootBlockElm; var parentNode = node.parentNode, rootBlockElm;
if (format.block) {
if (!forcedRootBlock) {
function find(node, next, inc) { function find(node, next, inc) {
node = getNonWhiteSpaceSibling(node, next, inc); node = getNonWhiteSpaceSibling(node, next, inc);
return !node || (node.nodeName == 'BR' || isBlock(node)); return !node || (node.nodeName == 'BR' || isBlock(node));
}; };
if (format.block) {
if (!forcedRootBlock) {
// Append BR elements if needed before we remove the block // Append BR elements if needed before we remove the block
if (isBlock(node) && !isBlock(parentNode)) { if (isBlock(node) && !isBlock(parentNode)) {
if (!find(node, FALSE) && !find(node.firstChild, TRUE, 1)) if (!find(node, FALSE) && !find(node.firstChild, TRUE, 1))
@ -16541,7 +17187,7 @@ tinymce.ForceBlocks = function(editor) {
value = obj2[name]; value = obj2[name];
// Obj2 doesn't have obj1 item // Obj2 doesn't have obj1 item
if (value === undefined) if (value === undef)
return FALSE; return FALSE;
// Obj2 item has a different value // Obj2 item has a different value
@ -16574,8 +17220,6 @@ tinymce.ForceBlocks = function(editor) {
return TRUE; return TRUE;
}; };
// Check if next/prev exists and that they are elements
if (prev && next) {
function findElementSibling(node, sibling_name) { function findElementSibling(node, sibling_name) {
for (sibling = node; sibling; sibling = sibling[sibling_name]) { for (sibling = node; sibling; sibling = sibling[sibling_name]) {
if (sibling.nodeType == 3 && sibling.nodeValue.length !== 0) if (sibling.nodeType == 3 && sibling.nodeValue.length !== 0)
@ -16588,6 +17232,8 @@ tinymce.ForceBlocks = function(editor) {
return node; return node;
}; };
// Check if next/prev exists and that they are elements
if (prev && next) {
// If previous sibling is empty then jump over it // If previous sibling is empty then jump over it
prev = findElementSibling(prev, 'previousSibling'); prev = findElementSibling(prev, 'previousSibling');
next = findElementSibling(next, 'nextSibling'); next = findElementSibling(next, 'nextSibling');
@ -16641,7 +17287,7 @@ tinymce.ForceBlocks = function(editor) {
} }
// If end text node is excluded then walk to the previous node // If end text node is excluded then walk to the previous node
if (container.nodeType === 3 && !start && offset == 0) { if (container.nodeType === 3 && !start && offset === 0) {
container = new TreeWalker(container, ed.getBody()).prev() || container; container = new TreeWalker(container, ed.getBody()).prev() || container;
} }
@ -16894,6 +17540,15 @@ tinymce.ForceBlocks = function(editor) {
} }
}); });
// Remove bogus state if they got filled by contents using editor.selection.setContent
selection.onSetContent.add(function() {
dom.getParent(selection.getStart(), function(node) {
if (node.id !== caretContainerId && dom.getAttrib(node, 'data-mce-bogus') && !dom.isEmpty(node)) {
dom.setAttrib(node, 'data-mce-bogus', null);
}
});
});
self._hasCaretEvents = true; self._hasCaretEvents = true;
} }
@ -16907,14 +17562,15 @@ tinymce.ForceBlocks = function(editor) {
function moveStart(rng) { function moveStart(rng) {
var container = rng.startContainer, var container = rng.startContainer,
offset = rng.startOffset, offset = rng.startOffset, isAtEndOfText,
walker, node, nodes, tmpNode; walker, node, nodes, tmpNode;
// Convert text node into index if possible // Convert text node into index if possible
if (container.nodeType == 3 && offset >= container.nodeValue.length) { if (container.nodeType == 3 && offset >= container.nodeValue.length) {
// Get the parent container location and walk from there // Get the parent container location and walk from there
offset = nodeIndex(container);
container = container.parentNode; container = container.parentNode;
offset = nodeIndex(container) + 1; isAtEndOfText = true;
} }
// Move startContainer/startOffset in to a suitable node // Move startContainer/startOffset in to a suitable node
@ -16924,7 +17580,7 @@ tinymce.ForceBlocks = function(editor) {
walker = new TreeWalker(container, dom.getParent(container, dom.isBlock)); walker = new TreeWalker(container, dom.getParent(container, dom.isBlock));
// If offset is at end of the parent node walk to the next one // If offset is at end of the parent node walk to the next one
if (offset > nodes.length - 1) if (offset > nodes.length - 1 || isAtEndOfText)
walker.next(); walker.next();
for (node = walker.current(); node; node = walker.next()) { for (node = walker.current(); node; node = walker.next()) {
@ -16950,9 +17606,6 @@ tinymce.ForceBlocks = function(editor) {
tinymce.onAddEditor.add(function(tinymce, ed) { tinymce.onAddEditor.add(function(tinymce, ed) {
var filters, fontSizes, dom, settings = ed.settings; var filters, fontSizes, dom, settings = ed.settings;
if (settings.inline_styles) {
fontSizes = tinymce.explode(settings.font_size_legacy_values);
function replaceWithSpan(node, styles) { function replaceWithSpan(node, styles) {
tinymce.each(styles, function(value, name) { tinymce.each(styles, function(value, name) {
if (value) if (value)
@ -16962,13 +17615,26 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
dom.rename(node, 'span'); dom.rename(node, 'span');
}; };
function convert(editor, params) {
dom = editor.dom;
if (settings.convert_fonts_to_spans) {
tinymce.each(dom.select('font,u,strike', params.node), function(node) {
filters[node.nodeName.toLowerCase()](ed.dom, node);
});
}
};
if (settings.inline_styles) {
fontSizes = tinymce.explode(settings.font_size_legacy_values);
filters = { filters = {
font : function(dom, node) { font : function(dom, node) {
replaceWithSpan(node, { replaceWithSpan(node, {
backgroundColor : node.style.backgroundColor, backgroundColor : node.style.backgroundColor,
color : node.color, color : node.color,
fontFamily : node.face, fontFamily : node.face,
fontSize : fontSizes[parseInt(node.size) - 1] fontSize : fontSizes[parseInt(node.size, 10) - 1]
}); });
}, },
@ -16985,16 +17651,6 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
} }
}; };
function convert(editor, params) {
dom = editor.dom;
if (settings.convert_fonts_to_spans) {
tinymce.each(dom.select('font,u,strike', params.node), function(node) {
filters[node.nodeName.toLowerCase()](ed.dom, node);
});
}
};
ed.onPreProcess.add(convert); ed.onPreProcess.add(convert);
ed.onSetContent.add(convert); ed.onSetContent.add(convert);
@ -17011,16 +17667,21 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
var dom = editor.dom, selection = editor.selection, settings = editor.settings, undoManager = editor.undoManager; var dom = editor.dom, selection = editor.selection, settings = editor.settings, undoManager = editor.undoManager;
function handleEnterKey(evt) { function handleEnterKey(evt) {
var rng = selection.getRng(true), tmpRng, container, offset, parentBlock, newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName; var rng = selection.getRng(true), tmpRng, editableRoot, container, offset, parentBlock, documentMode,
newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer;
// Returns true if the block can be split into two blocks or not // Returns true if the block can be split into two blocks or not
function canSplitBlock(node) { function canSplitBlock(node) {
return node && dom.isBlock(node) && !/^(TD|TH|CAPTION)$/.test(node.nodeName) && !/^(fixed|absolute)/i.test(node.style.position); return node &&
dom.isBlock(node) &&
!/^(TD|TH|CAPTION)$/.test(node.nodeName) &&
!/^(fixed|absolute)/i.test(node.style.position) &&
dom.getContentEditable(node) !== "true";
}; };
// Moves the caret to a suitable position within the root for example in the first non pure whitespace text node or before an image // Moves the caret to a suitable position within the root for example in the first non pure whitespace text node or before an image
function moveToCaretPosition(root) { function moveToCaretPosition(root) {
var walker, node, rng, y, viewPort, lastNode = root; var walker, node, rng, y, viewPort, lastNode = root, tempElm;
rng = dom.createRng(); rng = dom.createRng();
@ -17050,8 +17711,19 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
} }
} else { } else {
if (root.nodeName == 'BR') { if (root.nodeName == 'BR') {
if (root.nextSibling && dom.isBlock(root.nextSibling)) {
// Trick on older IE versions to render the caret before the BR between two lists
if (!documentMode || documentMode < 9) {
tempElm = dom.create('br');
root.parentNode.insertBefore(tempElm, root);
}
rng.setStartBefore(root);
rng.setEndBefore(root);
} else {
rng.setStartAfter(root); rng.setStartAfter(root);
rng.setEndAfter(root); rng.setEndAfter(root);
}
} else { } else {
rng.setStart(root, 0); rng.setStart(root, 0);
rng.setEnd(root, 0); rng.setEnd(root, 0);
@ -17060,6 +17732,9 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
selection.setRng(rng); selection.setRng(rng);
// Remove tempElm created for old IE:s
dom.remove(tempElm);
viewPort = dom.getViewPort(editor.getWin()); viewPort = dom.getViewPort(editor.getWin());
// scrollIntoView seems to scroll the parent window in most browsers now including FF 3.0b4 so it's time to stop using it and do it our selfs // scrollIntoView seems to scroll the parent window in most browsers now including FF 3.0b4 so it's time to stop using it and do it our selfs
@ -17074,10 +17749,11 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
function createNewBlock(name) { function createNewBlock(name) {
var node = container, block, clonedNode, caretNode; var node = container, block, clonedNode, caretNode;
block = name ? dom.create(name) : parentBlock.cloneNode(false); block = name || parentBlockName == "TABLE" ? dom.create(name || newBlockName) : parentBlock.cloneNode(false);
caretNode = block; caretNode = block;
// Clone any parent styles // Clone any parent styles
if (settings.keep_styles !== false) {
do { do {
if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(node.nodeName)) { if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(node.nodeName)) {
clonedNode = node.cloneNode(false); clonedNode = node.cloneNode(false);
@ -17092,6 +17768,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
} }
} }
} while (node = node.parentNode); } while (node = node.parentNode);
}
// BR is needed in empty blocks on non IE browsers // BR is needed in empty blocks on non IE browsers
if (!tinymce.isIE) { if (!tinymce.isIE) {
@ -17103,13 +17780,23 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
// Returns true/false if the caret is at the start/end of the parent block element // Returns true/false if the caret is at the start/end of the parent block element
function isCaretAtStartOrEndOfBlock(start) { function isCaretAtStartOrEndOfBlock(start) {
var walker, node; var walker, node, name;
// Caret is in the middle of a text node like "a|b" // Caret is in the middle of a text node like "a|b"
if (container.nodeType == 3 && (start ? offset > 0 : offset < container.nodeValue.length)) { if (container.nodeType == 3 && (start ? offset > 0 : offset < container.nodeValue.length)) {
return false; return false;
} }
// If after the last element in block node edge case for #5091
if (container.parentNode == parentBlock && isAfterLastNodeInContainer && !start) {
return true;
}
// Caret can be before/after a table
if (container.nodeName === "TABLE" || (container.previousSibling && container.previousSibling.nodeName == "TABLE")) {
return (isAfterLastNodeInContainer && !start) || (!isAfterLastNodeInContainer && start);
}
// Walk the DOM and look for text nodes or non empty elements // Walk the DOM and look for text nodes or non empty elements
walker = new TreeWalker(container, parentBlock); walker = new TreeWalker(container, parentBlock);
while (node = (start ? walker.prev() : walker.next())) { while (node = (start ? walker.prev() : walker.next())) {
@ -17134,15 +17821,15 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
// Wraps any text nodes or inline elements in the specified forced root block name // Wraps any text nodes or inline elements in the specified forced root block name
function wrapSelfAndSiblingsInDefaultBlock(container, offset) { function wrapSelfAndSiblingsInDefaultBlock(container, offset) {
var newBlock, parentBlock, startNode, node, next; var newBlock, parentBlock, startNode, node, next, blockName = newBlockName || 'P';
// Not in a block element or in a table cell or caption // Not in a block element or in a table cell or caption
parentBlock = dom.getParent(container, dom.isBlock); parentBlock = dom.getParent(container, dom.isBlock);
if (newBlockName && !evt.shiftKey && (!parentBlock || !canSplitBlock(parentBlock))) { if (!parentBlock || !canSplitBlock(parentBlock)) {
parentBlock = parentBlock || dom.getRoot(); parentBlock = parentBlock || editableRoot;
if (!parentBlock.hasChildNodes()) { if (!parentBlock.hasChildNodes()) {
newBlock = dom.create(newBlockName); newBlock = dom.create(blockName);
parentBlock.appendChild(newBlock); parentBlock.appendChild(newBlock);
rng.setStart(newBlock, 0); rng.setStart(newBlock, 0);
rng.setEnd(newBlock, 0); rng.setEnd(newBlock, 0);
@ -17162,7 +17849,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
} }
if (startNode) { if (startNode) {
newBlock = dom.create(newBlockName); newBlock = dom.create(blockName);
startNode.parentNode.insertBefore(newBlock, startNode); startNode.parentNode.insertBefore(newBlock, startNode);
// Start wrapping until we hit a block // Start wrapping until we hit a block
@ -17241,7 +17928,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
// Inserts a BR element if the forced_root_block option is set to false or empty string // Inserts a BR element if the forced_root_block option is set to false or empty string
function insertBr() { function insertBr() {
var brElm, extraBr, documentMode; var brElm, extraBr;
if (container && container.nodeType == 3 && offset >= container.nodeValue.length) { if (container && container.nodeType == 3 && offset >= container.nodeValue.length) {
// Insert extra BR element at the end block elements // Insert extra BR element at the end block elements
@ -17258,7 +17945,6 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
rng.insertNode(brElm); rng.insertNode(brElm);
// Rendering modes below IE8 doesn't display BR elements in PRE unless we have a \n before it // Rendering modes below IE8 doesn't display BR elements in PRE unless we have a \n before it
documentMode = dom.doc.documentMode;
if (tinymce.isIE && parentBlockName == 'PRE' && (!documentMode || documentMode < 8)) { if (tinymce.isIE && parentBlockName == 'PRE' && (!documentMode || documentMode < 8)) {
brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm); brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm);
} }
@ -17286,6 +17972,22 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
} while (node); } while (node);
}; };
function getEditableRoot(node) {
var root = dom.getRoot(), parent, editableRoot;
// Get all parents until we hit a non editable parent or the root
parent = node;
while (parent !== root && dom.getContentEditable(parent) !== "false") {
if (dom.getContentEditable(parent) === "true") {
editableRoot = parent;
}
parent = parent.parentNode;
}
return parent !== root ? editableRoot : root;
};
// Delete any selected contents // Delete any selected contents
if (!rng.collapsed) { if (!rng.collapsed) {
editor.execCommand('Delete'); editor.execCommand('Delete');
@ -17302,18 +18004,40 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
offset = rng.startOffset; offset = rng.startOffset;
newBlockName = settings.forced_root_block; newBlockName = settings.forced_root_block;
newBlockName = newBlockName ? newBlockName.toUpperCase() : ''; newBlockName = newBlockName ? newBlockName.toUpperCase() : '';
documentMode = dom.doc.documentMode;
// Resolve node index // Resolve node index
if (container.nodeType == 1 && container.hasChildNodes()) { if (container.nodeType == 1 && container.hasChildNodes()) {
isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container; container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
offset = 0; offset = 0;
} }
// Get editable root node normaly the body element but sometimes a div or span
editableRoot = getEditableRoot(container);
// If there is no editable root then enter is done inside a contentEditable false element
if (!editableRoot) {
return;
}
undoManager.beforeChange(); undoManager.beforeChange();
// If editable root isn't block nor the root of the editor
if (!dom.isBlock(editableRoot) && editableRoot != dom.getRoot()) {
if (!newBlockName || evt.shiftKey) {
insertBr();
}
return;
}
// Wrap the current node and it's sibling in a default block if it's needed. // Wrap the current node and it's sibling in a default block if it's needed.
// for example this <td>text|<b>text2</b></td> will become this <td><p>text|<b>text2</p></b></td> // for example this <td>text|<b>text2</b></td> will become this <td><p>text|<b>text2</p></b></td>
// This won't happen if root blocks are disabled or the shiftKey is pressed
if ((newBlockName && !evt.shiftKey) || (!newBlockName && evt.shiftKey)) {
container = wrapSelfAndSiblingsInDefaultBlock(container, offset); container = wrapSelfAndSiblingsInDefaultBlock(container, offset);
}
// Find parent block and setup empty block paddings // Find parent block and setup empty block paddings
parentBlock = dom.getParent(container, dom.isBlock); parentBlock = dom.getParent(container, dom.isBlock);
@ -17394,3 +18118,4 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
}); });
}; };
})(tinymce); })(tinymce);

View file

@ -6,9 +6,9 @@
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 3.0.1341\n" "Project-Id-Version: 3.0.1343\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-05-13 10:00-0700\n" "POT-Creation-Date: 2012-05-15 10:00-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -150,15 +150,15 @@ msgstr ""
#: ../../addon/statusnet/statusnet.php:318 #: ../../addon/statusnet/statusnet.php:318
#: ../../addon/statusnet/statusnet.php:325 #: ../../addon/statusnet/statusnet.php:325
#: ../../addon/statusnet/statusnet.php:353 #: ../../addon/statusnet/statusnet.php:353
#: ../../addon/statusnet/statusnet.php:553 ../../addon/tumblr/tumblr.php:90 #: ../../addon/statusnet/statusnet.php:561 ../../addon/tumblr/tumblr.php:90
#: ../../addon/numfriends/numfriends.php:85 ../../addon/gnot/gnot.php:88 #: ../../addon/numfriends/numfriends.php:85 ../../addon/gnot/gnot.php:88
#: ../../addon/wppost/wppost.php:102 ../../addon/showmore/showmore.php:48 #: ../../addon/wppost/wppost.php:109 ../../addon/showmore/showmore.php:48
#: ../../addon/piwik/piwik.php:89 ../../addon/twitter/twitter.php:180 #: ../../addon/piwik/piwik.php:89 ../../addon/twitter/twitter.php:180
#: ../../addon/twitter/twitter.php:209 ../../addon/twitter/twitter.php:375 #: ../../addon/twitter/twitter.php:209 ../../addon/twitter/twitter.php:381
#: ../../addon/irc/irc.php:55 ../../addon/blogger/blogger.php:102 #: ../../addon/irc/irc.php:55 ../../addon/blogger/blogger.php:102
#: ../../addon/posterous/posterous.php:103 #: ../../addon/posterous/posterous.php:103
#: ../../view/theme/cleanzero/config.php:80 #: ../../view/theme/cleanzero/config.php:80
#: ../../view/theme/diabook/theme.php:753 #: ../../view/theme/diabook/theme.php:752
#: ../../view/theme/diabook/config.php:190 #: ../../view/theme/diabook/config.php:190
#: ../../view/theme/quattro/config.php:52 ../../view/theme/dispy/config.php:70 #: ../../view/theme/quattro/config.php:52 ../../view/theme/dispy/config.php:70
#: ../../include/conversation.php:558 #: ../../include/conversation.php:558
@ -352,7 +352,7 @@ msgstr ""
#: ../../mod/photos.php:51 ../../mod/photos.php:151 ../../mod/photos.php:879 #: ../../mod/photos.php:51 ../../mod/photos.php:151 ../../mod/photos.php:879
#: ../../mod/photos.php:950 ../../mod/photos.php:965 ../../mod/photos.php:1382 #: ../../mod/photos.php:950 ../../mod/photos.php:965 ../../mod/photos.php:1382
#: ../../mod/photos.php:1394 ../../addon/communityhome/communityhome.php:110 #: ../../mod/photos.php:1394 ../../addon/communityhome/communityhome.php:110
#: ../../view/theme/diabook/theme.php:594 #: ../../view/theme/diabook/theme.php:593
msgid "Contact Photos" msgid "Contact Photos"
msgstr "" msgstr ""
@ -375,7 +375,7 @@ msgstr ""
#: ../../mod/profile_photo.php:74 ../../mod/profile_photo.php:174 #: ../../mod/profile_photo.php:74 ../../mod/profile_photo.php:174
#: ../../mod/profile_photo.php:252 ../../mod/profile_photo.php:261 #: ../../mod/profile_photo.php:252 ../../mod/profile_photo.php:261
#: ../../addon/communityhome/communityhome.php:111 #: ../../addon/communityhome/communityhome.php:111
#: ../../view/theme/diabook/theme.php:595 #: ../../view/theme/diabook/theme.php:594
msgid "Profile Photos" msgid "Profile Photos"
msgstr "" msgstr ""
@ -397,7 +397,7 @@ msgstr ""
#: ../../mod/photos.php:528 ../../mod/like.php:127 ../../mod/tagger.php:70 #: ../../mod/photos.php:528 ../../mod/like.php:127 ../../mod/tagger.php:70
#: ../../addon/communityhome/communityhome.php:163 #: ../../addon/communityhome/communityhome.php:163
#: ../../view/theme/diabook/theme.php:566 ../../include/text.php:1305 #: ../../view/theme/diabook/theme.php:565 ../../include/text.php:1305
#: ../../include/diaspora.php:1654 ../../include/conversation.php:53 #: ../../include/diaspora.php:1654 ../../include/conversation.php:53
#: ../../include/conversation.php:126 #: ../../include/conversation.php:126
msgid "photo" msgid "photo"
@ -1775,8 +1775,8 @@ msgid "Remove account"
msgstr "" msgstr ""
#: ../../mod/settings.php:88 ../../mod/admin.php:735 ../../mod/admin.php:940 #: ../../mod/settings.php:88 ../../mod/admin.php:735 ../../mod/admin.php:940
#: ../../addon/mathjax/mathjax.php:36 ../../view/theme/diabook/theme.php:639 #: ../../addon/mathjax/mathjax.php:36 ../../view/theme/diabook/theme.php:638
#: ../../view/theme/diabook/theme.php:769 ../../include/nav.php:137 #: ../../view/theme/diabook/theme.php:768 ../../include/nav.php:137
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
@ -1832,7 +1832,7 @@ msgstr ""
#: ../../addon/impressum/impressum.php:77 #: ../../addon/impressum/impressum.php:77
#: ../../addon/openstreetmap/openstreetmap.php:80 #: ../../addon/openstreetmap/openstreetmap.php:80
#: ../../addon/mathjax/mathjax.php:66 ../../addon/piwik/piwik.php:105 #: ../../addon/mathjax/mathjax.php:66 ../../addon/piwik/piwik.php:105
#: ../../addon/twitter/twitter.php:370 #: ../../addon/twitter/twitter.php:376
msgid "Settings updated." msgid "Settings updated."
msgstr "" msgstr ""
@ -1842,12 +1842,12 @@ msgid "Add application"
msgstr "" msgstr ""
#: ../../mod/settings.php:542 ../../mod/settings.php:568 #: ../../mod/settings.php:542 ../../mod/settings.php:568
#: ../../addon/statusnet/statusnet.php:547 #: ../../addon/statusnet/statusnet.php:555
msgid "Consumer Key" msgid "Consumer Key"
msgstr "" msgstr ""
#: ../../mod/settings.php:543 ../../mod/settings.php:569 #: ../../mod/settings.php:543 ../../mod/settings.php:569
#: ../../addon/statusnet/statusnet.php:546 #: ../../addon/statusnet/statusnet.php:554
msgid "Consumer Secret" msgid "Consumer Secret"
msgstr "" msgstr ""
@ -2787,8 +2787,8 @@ msgstr ""
#: ../../addon/facebook/facebook.php:1564 #: ../../addon/facebook/facebook.php:1564
#: ../../addon/communityhome/communityhome.php:158 #: ../../addon/communityhome/communityhome.php:158
#: ../../addon/communityhome/communityhome.php:167 #: ../../addon/communityhome/communityhome.php:167
#: ../../view/theme/diabook/theme.php:561 #: ../../view/theme/diabook/theme.php:560
#: ../../view/theme/diabook/theme.php:570 ../../include/diaspora.php:1654 #: ../../view/theme/diabook/theme.php:569 ../../include/diaspora.php:1654
#: ../../include/conversation.php:48 ../../include/conversation.php:57 #: ../../include/conversation.php:48 ../../include/conversation.php:57
#: ../../include/conversation.php:121 ../../include/conversation.php:130 #: ../../include/conversation.php:121 ../../include/conversation.php:130
msgid "status" msgid "status"
@ -2796,7 +2796,7 @@ msgstr ""
#: ../../mod/like.php:144 ../../addon/facebook/facebook.php:1568 #: ../../mod/like.php:144 ../../addon/facebook/facebook.php:1568
#: ../../addon/communityhome/communityhome.php:172 #: ../../addon/communityhome/communityhome.php:172
#: ../../view/theme/diabook/theme.php:575 ../../include/diaspora.php:1670 #: ../../view/theme/diabook/theme.php:574 ../../include/diaspora.php:1670
#: ../../include/conversation.php:65 #: ../../include/conversation.php:65
#, php-format #, php-format
msgid "%1$s likes %2$s's %3$s" msgid "%1$s likes %2$s's %3$s"
@ -3137,7 +3137,7 @@ msgstr ""
msgid "Advanced" msgid "Advanced"
msgstr "" msgstr ""
#: ../../mod/admin.php:412 ../../addon/statusnet/statusnet.php:544 #: ../../mod/admin.php:412 ../../addon/statusnet/statusnet.php:552
msgid "Site name" msgid "Site name"
msgstr "" msgstr ""
@ -4073,7 +4073,7 @@ msgstr ""
msgid "No entries." msgid "No entries."
msgstr "" msgstr ""
#: ../../mod/suggest.php:38 ../../view/theme/diabook/theme.php:622 #: ../../mod/suggest.php:38 ../../view/theme/diabook/theme.php:621
#: ../../include/contact_widgets.php:34 #: ../../include/contact_widgets.php:34
msgid "Friend Suggestions" msgid "Friend Suggestions"
msgstr "" msgstr ""
@ -4088,7 +4088,7 @@ msgstr ""
msgid "Ignore/Hide" msgid "Ignore/Hide"
msgstr "" msgstr ""
#: ../../mod/directory.php:47 ../../view/theme/diabook/theme.php:620 #: ../../mod/directory.php:47 ../../view/theme/diabook/theme.php:619
msgid "Global Directory" msgid "Global Directory"
msgstr "" msgstr ""
@ -4673,7 +4673,7 @@ msgid "Latest likes"
msgstr "" msgstr ""
#: ../../addon/communityhome/communityhome.php:155 #: ../../addon/communityhome/communityhome.php:155
#: ../../view/theme/diabook/theme.php:558 ../../include/text.php:1303 #: ../../view/theme/diabook/theme.php:557 ../../include/text.php:1303
#: ../../include/conversation.php:45 ../../include/conversation.php:118 #: ../../include/conversation.php:45 ../../include/conversation.php:118
msgid "event" msgid "event"
msgstr "" msgstr ""
@ -4824,7 +4824,7 @@ msgstr ""
msgid "Post to Drupal by default" msgid "Post to Drupal by default"
msgstr "" msgstr ""
#: ../../addon/drpost/drpost.php:184 ../../addon/wppost/wppost.php:190 #: ../../addon/drpost/drpost.php:184 ../../addon/wppost/wppost.php:198
#: ../../addon/blogger/blogger.php:172 ../../addon/posterous/posterous.php:192 #: ../../addon/blogger/blogger.php:172 ../../addon/posterous/posterous.php:192
msgid "Post from Friendica" msgid "Post from Friendica"
msgstr "" msgstr ""
@ -5272,14 +5272,14 @@ msgid "Send public postings to StatusNet by default"
msgstr "" msgstr ""
#: ../../addon/statusnet/statusnet.php:345 #: ../../addon/statusnet/statusnet.php:345
msgid "Send #tag links to StatusNet" msgid "Send linked #-tags and @-names to StatusNet"
msgstr "" msgstr ""
#: ../../addon/statusnet/statusnet.php:350 ../../addon/twitter/twitter.php:206 #: ../../addon/statusnet/statusnet.php:350 ../../addon/twitter/twitter.php:206
msgid "Clear OAuth configuration" msgid "Clear OAuth configuration"
msgstr "" msgstr ""
#: ../../addon/statusnet/statusnet.php:545 #: ../../addon/statusnet/statusnet.php:553
msgid "API URL" msgid "API URL"
msgstr "" msgstr ""
@ -5346,30 +5346,38 @@ msgstr ""
msgid "Post to Wordpress" msgid "Post to Wordpress"
msgstr "" msgstr ""
#: ../../addon/wppost/wppost.php:74 #: ../../addon/wppost/wppost.php:76
msgid "WordPress Post Settings" msgid "WordPress Post Settings"
msgstr "" msgstr ""
#: ../../addon/wppost/wppost.php:76 #: ../../addon/wppost/wppost.php:78
msgid "Enable WordPress Post Plugin" msgid "Enable WordPress Post Plugin"
msgstr "" msgstr ""
#: ../../addon/wppost/wppost.php:81 #: ../../addon/wppost/wppost.php:83
msgid "WordPress username" msgid "WordPress username"
msgstr "" msgstr ""
#: ../../addon/wppost/wppost.php:86 #: ../../addon/wppost/wppost.php:88
msgid "WordPress password" msgid "WordPress password"
msgstr "" msgstr ""
#: ../../addon/wppost/wppost.php:91 #: ../../addon/wppost/wppost.php:93
msgid "WordPress API URL" msgid "WordPress API URL"
msgstr "" msgstr ""
#: ../../addon/wppost/wppost.php:96 #: ../../addon/wppost/wppost.php:98
msgid "Post to WordPress by default" msgid "Post to WordPress by default"
msgstr "" msgstr ""
#: ../../addon/wppost/wppost.php:102
msgid "Provide a backlink to the Friendica post"
msgstr ""
#: ../../addon/wppost/wppost.php:204
msgid "Read the original post and comment stream on Friendica"
msgstr ""
#: ../../addon/showmore/showmore.php:38 #: ../../addon/showmore/showmore.php:38
msgid "\"Show more\" Settings" msgid "\"Show more\" Settings"
msgstr "" msgstr ""
@ -5481,14 +5489,14 @@ msgid "Send public postings to Twitter by default"
msgstr "" msgstr ""
#: ../../addon/twitter/twitter.php:201 #: ../../addon/twitter/twitter.php:201
msgid "Send #tag links to Twitter" msgid "Send linked #-tags and @-names to Twitter"
msgstr "" msgstr ""
#: ../../addon/twitter/twitter.php:377 #: ../../addon/twitter/twitter.php:383
msgid "Consumer key" msgid "Consumer key"
msgstr "" msgstr ""
#: ../../addon/twitter/twitter.php:378 #: ../../addon/twitter/twitter.php:384
msgid "Consumer secret" msgid "Consumer secret"
msgstr "" msgstr ""
@ -5631,96 +5639,97 @@ msgid "Your personal photos"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:129 #: ../../view/theme/diabook/theme.php:129
#: ../../view/theme/diabook/theme.php:639 #: ../../view/theme/diabook/theme.php:638
#: ../../view/theme/diabook/theme.php:743 #: ../../view/theme/diabook/theme.php:742
#: ../../view/theme/diabook/config.php:201 #: ../../view/theme/diabook/config.php:201
msgid "Community Pages" msgid "Community Pages"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:486 #: ../../view/theme/diabook/theme.php:485
#: ../../view/theme/diabook/theme.php:745 #: ../../view/theme/diabook/theme.php:744
#: ../../view/theme/diabook/config.php:203 #: ../../view/theme/diabook/config.php:203
msgid "Community Profiles" msgid "Community Profiles"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:507 #: ../../view/theme/diabook/theme.php:506
#: ../../view/theme/diabook/theme.php:750 #: ../../view/theme/diabook/theme.php:749
#: ../../view/theme/diabook/config.php:208 #: ../../view/theme/diabook/config.php:208
msgid "Last users" msgid "Last users"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:536 #: ../../view/theme/diabook/theme.php:535
#: ../../view/theme/diabook/theme.php:752 #: ../../view/theme/diabook/theme.php:751
#: ../../view/theme/diabook/config.php:210 #: ../../view/theme/diabook/config.php:210
msgid "Last likes" msgid "Last likes"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:581 #: ../../view/theme/diabook/theme.php:580
#: ../../view/theme/diabook/theme.php:751 #: ../../view/theme/diabook/theme.php:750
#: ../../view/theme/diabook/config.php:209 #: ../../view/theme/diabook/config.php:209
msgid "Last photos" msgid "Last photos"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:618 #: ../../view/theme/diabook/theme.php:617
#: ../../view/theme/diabook/theme.php:748 #: ../../view/theme/diabook/theme.php:747
#: ../../view/theme/diabook/config.php:206 #: ../../view/theme/diabook/config.php:206
msgid "Find Friends" msgid "Find Friends"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:619 #: ../../view/theme/diabook/theme.php:618
msgid "Local Directory" msgid "Local Directory"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:621 ../../include/contact_widgets.php:35 #: ../../view/theme/diabook/theme.php:620 ../../include/contact_widgets.php:35
msgid "Similar Interests" msgid "Similar Interests"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:623 ../../include/contact_widgets.php:37 #: ../../view/theme/diabook/theme.php:622 ../../include/contact_widgets.php:37
msgid "Invite Friends" msgid "Invite Friends"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:674 #: ../../view/theme/diabook/theme.php:673
#: ../../view/theme/diabook/theme.php:744 #: ../../view/theme/diabook/theme.php:743
#: ../../view/theme/diabook/config.php:202 #: ../../view/theme/diabook/config.php:202
msgid "Earth Layers" msgid "Earth Layers"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:679 #: ../../view/theme/diabook/theme.php:678
msgid "Set zoomfactor for Earth Layers" msgid "Set zoomfactor for Earth Layers"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:680 #: ../../view/theme/diabook/theme.php:679
#: ../../view/theme/diabook/config.php:199 #: ../../view/theme/diabook/config.php:199
msgid "Set longitude (X) for Earth Layers" msgid "Set longitude (X) for Earth Layers"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:681 #: ../../view/theme/diabook/theme.php:680
#: ../../view/theme/diabook/config.php:200 #: ../../view/theme/diabook/config.php:200
msgid "Set latitude (Y) for Earth Layers" msgid "Set latitude (Y) for Earth Layers"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:694 #: ../../view/theme/diabook/theme.php:693
#: ../../view/theme/diabook/theme.php:746 #: ../../view/theme/diabook/theme.php:745
#: ../../view/theme/diabook/config.php:204 #: ../../view/theme/diabook/config.php:204
msgid "Help or @NewHere ?" msgid "Help or @NewHere ?"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:701 #: ../../view/theme/diabook/theme.php:700
#: ../../view/theme/diabook/theme.php:747 #: ../../view/theme/diabook/theme.php:746
#: ../../view/theme/diabook/config.php:205 #: ../../view/theme/diabook/config.php:205
msgid "Connect Services" msgid "Connect Services"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:708 #: ../../view/theme/diabook/theme.php:707
#: ../../view/theme/diabook/theme.php:749 #: ../../view/theme/diabook/theme.php:748
msgid "Last Tweets" msgid "Last Tweets"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:711 #: ../../view/theme/diabook/theme.php:710
#: ../../view/theme/diabook/config.php:197 #: ../../view/theme/diabook/config.php:197
msgid "Set twitter search term" msgid "Set twitter search term"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:730
#: ../../view/theme/diabook/theme.php:731 #: ../../view/theme/diabook/theme.php:731
#: ../../view/theme/diabook/theme.php:732 #: ../../view/theme/diabook/theme.php:732
#: ../../view/theme/diabook/theme.php:733 #: ../../view/theme/diabook/theme.php:733
@ -5729,11 +5738,11 @@ msgstr ""
#: ../../view/theme/diabook/theme.php:736 #: ../../view/theme/diabook/theme.php:736
#: ../../view/theme/diabook/theme.php:737 #: ../../view/theme/diabook/theme.php:737
#: ../../view/theme/diabook/theme.php:738 #: ../../view/theme/diabook/theme.php:738
#: ../../view/theme/diabook/theme.php:739 #: ../../view/theme/diabook/theme.php:739 ../../include/acl_selectors.php:288
#: ../../view/theme/diabook/theme.php:740 ../../include/acl_selectors.php:288
msgid "don't show" msgid "don't show"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:730
#: ../../view/theme/diabook/theme.php:731 #: ../../view/theme/diabook/theme.php:731
#: ../../view/theme/diabook/theme.php:732 #: ../../view/theme/diabook/theme.php:732
#: ../../view/theme/diabook/theme.php:733 #: ../../view/theme/diabook/theme.php:733
@ -5742,12 +5751,11 @@ msgstr ""
#: ../../view/theme/diabook/theme.php:736 #: ../../view/theme/diabook/theme.php:736
#: ../../view/theme/diabook/theme.php:737 #: ../../view/theme/diabook/theme.php:737
#: ../../view/theme/diabook/theme.php:738 #: ../../view/theme/diabook/theme.php:738
#: ../../view/theme/diabook/theme.php:739 #: ../../view/theme/diabook/theme.php:739 ../../include/acl_selectors.php:287
#: ../../view/theme/diabook/theme.php:740 ../../include/acl_selectors.php:287
msgid "show" msgid "show"
msgstr "" msgstr ""
#: ../../view/theme/diabook/theme.php:741 #: ../../view/theme/diabook/theme.php:740
msgid "Show/hide boxes at right-hand column:" msgid "Show/hide boxes at right-hand column:"
msgstr "" msgstr ""

View file

@ -19,8 +19,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: friendica\n" "Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: http://bugs.friendica.com/\n" "Report-Msgid-Bugs-To: http://bugs.friendica.com/\n"
"POT-Creation-Date: 2012-05-06 10:00-0700\n" "POT-Creation-Date: 2012-05-14 10:00-0700\n"
"PO-Revision-Date: 2012-05-08 07:06+0000\n" "PO-Revision-Date: 2012-05-15 08:40+0000\n"
"Last-Translator: bavatar <tobias.diekershoff@gmx.net>\n" "Last-Translator: bavatar <tobias.diekershoff@gmx.net>\n"
"Language-Team: German (http://www.transifex.net/projects/p/friendica/language/de/)\n" "Language-Team: German (http://www.transifex.net/projects/p/friendica/language/de/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -60,14 +60,14 @@ msgstr "Konnte den Kontakt nicht aktualisieren."
#: ../../mod/register.php:38 ../../mod/regmod.php:116 ../../mod/item.php:124 #: ../../mod/register.php:38 ../../mod/regmod.php:116 ../../mod/item.php:124
#: ../../mod/item.php:140 ../../mod/profile_photo.php:19 #: ../../mod/item.php:140 ../../mod/profile_photo.php:19
#: ../../mod/profile_photo.php:139 ../../mod/profile_photo.php:150 #: ../../mod/profile_photo.php:139 ../../mod/profile_photo.php:150
#: ../../mod/profile_photo.php:163 ../../mod/message.php:38 #: ../../mod/profile_photo.php:163 ../../mod/message.php:44
#: ../../mod/message.php:90 ../../mod/allfriends.php:9 #: ../../mod/message.php:96 ../../mod/allfriends.php:9
#: ../../mod/nogroup.php:25 ../../mod/wall_upload.php:53 #: ../../mod/nogroup.php:25 ../../mod/wall_upload.php:53
#: ../../mod/follow.php:8 ../../mod/display.php:138 ../../mod/profiles.php:7 #: ../../mod/follow.php:8 ../../mod/display.php:138 ../../mod/profiles.php:7
#: ../../mod/profiles.php:365 ../../mod/delegate.php:6 #: ../../mod/profiles.php:365 ../../mod/delegate.php:6
#: ../../mod/suggest.php:28 ../../mod/invite.php:13 ../../mod/invite.php:81 #: ../../mod/suggest.php:28 ../../mod/invite.php:13 ../../mod/invite.php:81
#: ../../mod/dfrn_confirm.php:53 ../../addon/facebook/facebook.php:495 #: ../../mod/dfrn_confirm.php:53 ../../addon/facebook/facebook.php:495
#: ../../include/items.php:3192 ../../index.php:306 #: ../../include/items.php:3202 ../../index.php:306
msgid "Permission denied." msgid "Permission denied."
msgstr "Zugriff verweigert." msgstr "Zugriff verweigert."
@ -97,7 +97,7 @@ msgid "Return to contact editor"
msgstr "Zurück zum Kontakteditor" msgstr "Zurück zum Kontakteditor"
#: ../../mod/crepair.php:148 ../../mod/settings.php:541 #: ../../mod/crepair.php:148 ../../mod/settings.php:541
#: ../../mod/settings.php:567 ../../mod/admin.php:640 ../../mod/admin.php:649 #: ../../mod/settings.php:567 ../../mod/admin.php:643 ../../mod/admin.php:652
msgid "Name" msgid "Name"
msgstr "Name" msgstr "Name"
@ -141,9 +141,9 @@ msgstr "Neues Foto von dieser URL"
#: ../../mod/localtime.php:45 ../../mod/contacts.php:322 #: ../../mod/localtime.php:45 ../../mod/contacts.php:322
#: ../../mod/settings.php:539 ../../mod/settings.php:685 #: ../../mod/settings.php:539 ../../mod/settings.php:685
#: ../../mod/settings.php:746 ../../mod/settings.php:940 #: ../../mod/settings.php:746 ../../mod/settings.php:940
#: ../../mod/manage.php:109 ../../mod/group.php:85 ../../mod/admin.php:402 #: ../../mod/manage.php:109 ../../mod/group.php:85 ../../mod/admin.php:404
#: ../../mod/admin.php:637 ../../mod/admin.php:773 ../../mod/admin.php:972 #: ../../mod/admin.php:640 ../../mod/admin.php:776 ../../mod/admin.php:975
#: ../../mod/admin.php:1059 ../../mod/profiles.php:534 #: ../../mod/admin.php:1062 ../../mod/profiles.php:534
#: ../../mod/invite.php:119 ../../addon/facebook/facebook.php:597 #: ../../mod/invite.php:119 ../../addon/facebook/facebook.php:597
#: ../../addon/yourls/yourls.php:76 ../../addon/ljpost/ljpost.php:93 #: ../../addon/yourls/yourls.php:76 ../../addon/ljpost/ljpost.php:93
#: ../../addon/nsfw/nsfw.php:57 ../../addon/planets/planets.php:158 #: ../../addon/nsfw/nsfw.php:57 ../../addon/planets/planets.php:158
@ -154,7 +154,7 @@ msgstr "Neues Foto von dieser URL"
#: ../../addon/blockem/blockem.php:57 ../../addon/qcomment/qcomment.php:61 #: ../../addon/blockem/blockem.php:57 ../../addon/qcomment/qcomment.php:61
#: ../../addon/openstreetmap/openstreetmap.php:70 #: ../../addon/openstreetmap/openstreetmap.php:70
#: ../../addon/mathjax/mathjax.php:42 ../../addon/editplain/editplain.php:84 #: ../../addon/mathjax/mathjax.php:42 ../../addon/editplain/editplain.php:84
#: ../../addon/blackout/blackout.php:94 ../../addon/gravatar/gravatar.php:86 #: ../../addon/blackout/blackout.php:98 ../../addon/gravatar/gravatar.php:86
#: ../../addon/pageheader/pageheader.php:55 ../../addon/ijpost/ijpost.php:93 #: ../../addon/pageheader/pageheader.php:55 ../../addon/ijpost/ijpost.php:93
#: ../../addon/jappixmini/jappixmini.php:302 #: ../../addon/jappixmini/jappixmini.php:302
#: ../../addon/statusnet/statusnet.php:278 #: ../../addon/statusnet/statusnet.php:278
@ -168,12 +168,12 @@ msgstr "Neues Foto von dieser URL"
#: ../../addon/piwik/piwik.php:89 ../../addon/twitter/twitter.php:180 #: ../../addon/piwik/piwik.php:89 ../../addon/twitter/twitter.php:180
#: ../../addon/twitter/twitter.php:209 ../../addon/twitter/twitter.php:375 #: ../../addon/twitter/twitter.php:209 ../../addon/twitter/twitter.php:375
#: ../../addon/irc/irc.php:55 ../../addon/blogger/blogger.php:102 #: ../../addon/irc/irc.php:55 ../../addon/blogger/blogger.php:102
#: ../../addon/posterous/posterous.php:90 #: ../../addon/posterous/posterous.php:103
#: ../../view/theme/cleanzero/config.php:80 #: ../../view/theme/cleanzero/config.php:80
#: ../../view/theme/diabook/theme.php:590 #: ../../view/theme/diabook/theme.php:752
#: ../../view/theme/diabook/config.php:95 #: ../../view/theme/diabook/config.php:190
#: ../../view/theme/quattro/config.php:52 ../../view/theme/dispy/config.php:70 #: ../../view/theme/quattro/config.php:52 ../../view/theme/dispy/config.php:70
#: ../../include/conversation.php:555 #: ../../include/conversation.php:558
msgid "Submit" msgid "Submit"
msgstr "Senden" msgstr "Senden"
@ -231,8 +231,8 @@ msgstr "Veranstaltung bearbeiten"
msgid "link to source" msgid "link to source"
msgstr "Link zum Originalbeitrag" msgstr "Link zum Originalbeitrag"
#: ../../mod/events.php:324 ../../view/theme/diabook/theme.php:69 #: ../../mod/events.php:324 ../../view/theme/diabook/theme.php:126
#: ../../include/nav.php:52 ../../boot.php:1493 #: ../../include/nav.php:52 ../../boot.php:1503
msgid "Events" msgid "Events"
msgstr "Veranstaltungen" msgstr "Veranstaltungen"
@ -282,7 +282,7 @@ msgid "Description:"
msgstr "Beschreibung" msgstr "Beschreibung"
#: ../../mod/events.php:423 ../../include/event.php:37 #: ../../mod/events.php:423 ../../include/event.php:37
#: ../../include/bb2diaspora.php:260 ../../boot.php:1092 #: ../../include/bb2diaspora.php:260 ../../boot.php:1102
msgid "Location:" msgid "Location:"
msgstr "Ort:" msgstr "Ort:"
@ -357,14 +357,14 @@ msgstr "Ja"
msgid "No" msgid "No"
msgstr "Nein" msgstr "Nein"
#: ../../mod/photos.php:43 ../../boot.php:1487 #: ../../mod/photos.php:43 ../../boot.php:1497
msgid "Photo Albums" msgid "Photo Albums"
msgstr "Fotoalben" msgstr "Fotoalben"
#: ../../mod/photos.php:51 ../../mod/photos.php:151 ../../mod/photos.php:879 #: ../../mod/photos.php:51 ../../mod/photos.php:151 ../../mod/photos.php:879
#: ../../mod/photos.php:950 ../../mod/photos.php:965 ../../mod/photos.php:1382 #: ../../mod/photos.php:950 ../../mod/photos.php:965 ../../mod/photos.php:1382
#: ../../mod/photos.php:1394 ../../addon/communityhome/communityhome.php:110 #: ../../mod/photos.php:1394 ../../addon/communityhome/communityhome.php:110
#: ../../view/theme/diabook/theme.php:485 #: ../../view/theme/diabook/theme.php:593
msgid "Contact Photos" msgid "Contact Photos"
msgstr "Kontaktbilder" msgstr "Kontaktbilder"
@ -387,7 +387,7 @@ msgstr "Kontaktinformationen nicht verfügbar"
#: ../../mod/profile_photo.php:74 ../../mod/profile_photo.php:174 #: ../../mod/profile_photo.php:74 ../../mod/profile_photo.php:174
#: ../../mod/profile_photo.php:252 ../../mod/profile_photo.php:261 #: ../../mod/profile_photo.php:252 ../../mod/profile_photo.php:261
#: ../../addon/communityhome/communityhome.php:111 #: ../../addon/communityhome/communityhome.php:111
#: ../../view/theme/diabook/theme.php:486 #: ../../view/theme/diabook/theme.php:594
msgid "Profile Photos" msgid "Profile Photos"
msgstr "Profilbilder" msgstr "Profilbilder"
@ -409,7 +409,7 @@ msgstr "wurde getaggt in einem"
#: ../../mod/photos.php:528 ../../mod/like.php:127 ../../mod/tagger.php:70 #: ../../mod/photos.php:528 ../../mod/like.php:127 ../../mod/tagger.php:70
#: ../../addon/communityhome/communityhome.php:163 #: ../../addon/communityhome/communityhome.php:163
#: ../../view/theme/diabook/theme.php:457 ../../include/text.php:1305 #: ../../view/theme/diabook/theme.php:565 ../../include/text.php:1305
#: ../../include/diaspora.php:1654 ../../include/conversation.php:53 #: ../../include/diaspora.php:1654 ../../include/conversation.php:53
#: ../../include/conversation.php:126 #: ../../include/conversation.php:126
msgid "photo" msgid "photo"
@ -499,7 +499,7 @@ msgstr "Foto bearbeiten"
msgid "Use as profile photo" msgid "Use as profile photo"
msgstr "Als Profilbild verwenden" msgstr "Als Profilbild verwenden"
#: ../../mod/photos.php:1078 ../../include/conversation.php:480 #: ../../mod/photos.php:1078 ../../include/conversation.php:483
msgid "Private Message" msgid "Private Message"
msgstr "Private Nachricht" msgstr "Private Nachricht"
@ -532,44 +532,44 @@ msgid ""
"Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping" "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"
msgstr "Beispiel: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping" msgstr "Beispiel: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"
#: ../../mod/photos.php:1211 ../../include/conversation.php:529 #: ../../mod/photos.php:1211 ../../include/conversation.php:532
msgid "I like this (toggle)" msgid "I like this (toggle)"
msgstr "Ich mag das (toggle)" msgstr "Ich mag das (toggle)"
#: ../../mod/photos.php:1212 ../../include/conversation.php:530 #: ../../mod/photos.php:1212 ../../include/conversation.php:533
msgid "I don't like this (toggle)" msgid "I don't like this (toggle)"
msgstr "Ich mag das nicht (toggle)" msgstr "Ich mag das nicht (toggle)"
#: ../../mod/photos.php:1213 ../../include/conversation.php:964 #: ../../mod/photos.php:1213 ../../include/conversation.php:967
msgid "Share" msgid "Share"
msgstr "Teilen" msgstr "Teilen"
#: ../../mod/photos.php:1214 ../../mod/editpost.php:104 #: ../../mod/photos.php:1214 ../../mod/editpost.php:104
#: ../../mod/wallmessage.php:145 ../../mod/message.php:188 #: ../../mod/wallmessage.php:145 ../../mod/message.php:214
#: ../../mod/message.php:380 ../../include/conversation.php:361 #: ../../mod/message.php:408 ../../include/conversation.php:364
#: ../../include/conversation.php:706 ../../include/conversation.php:983 #: ../../include/conversation.php:709 ../../include/conversation.php:986
msgid "Please wait" msgid "Please wait"
msgstr "Bitte warten" msgstr "Bitte warten"
#: ../../mod/photos.php:1230 ../../mod/photos.php:1270 #: ../../mod/photos.php:1230 ../../mod/photos.php:1270
#: ../../mod/photos.php:1301 ../../include/conversation.php:552 #: ../../mod/photos.php:1301 ../../include/conversation.php:555
msgid "This is you" msgid "This is you"
msgstr "Das bist du" msgstr "Das bist du"
#: ../../mod/photos.php:1232 ../../mod/photos.php:1272 #: ../../mod/photos.php:1232 ../../mod/photos.php:1272
#: ../../mod/photos.php:1303 ../../include/conversation.php:554 #: ../../mod/photos.php:1303 ../../include/conversation.php:557
#: ../../boot.php:506 #: ../../boot.php:516
msgid "Comment" msgid "Comment"
msgstr "Kommentar" msgstr "Kommentar"
#: ../../mod/photos.php:1234 ../../mod/editpost.php:125 #: ../../mod/photos.php:1234 ../../mod/editpost.php:125
#: ../../include/conversation.php:564 ../../include/conversation.php:1001 #: ../../include/conversation.php:567 ../../include/conversation.php:1004
msgid "Preview" msgid "Preview"
msgstr "Vorschau" msgstr "Vorschau"
#: ../../mod/photos.php:1331 ../../mod/settings.php:602 #: ../../mod/photos.php:1331 ../../mod/settings.php:602
#: ../../mod/settings.php:683 ../../mod/group.php:168 ../../mod/admin.php:644 #: ../../mod/settings.php:683 ../../mod/group.php:168 ../../mod/admin.php:647
#: ../../include/conversation.php:318 ../../include/conversation.php:584 #: ../../include/conversation.php:321 ../../include/conversation.php:587
msgid "Delete" msgid "Delete"
msgstr "Löschen" msgstr "Löschen"
@ -585,7 +585,7 @@ msgstr "Neueste Fotos"
msgid "Not available." msgid "Not available."
msgstr "Nicht verfügbar." msgstr "Nicht verfügbar."
#: ../../mod/community.php:30 ../../view/theme/diabook/theme.php:71 #: ../../mod/community.php:30 ../../view/theme/diabook/theme.php:128
#: ../../include/nav.php:101 #: ../../include/nav.php:101
msgid "Community" msgid "Community"
msgstr "Gemeinschaft" msgstr "Gemeinschaft"
@ -634,28 +634,28 @@ msgstr "Beitrag nicht gefunden"
msgid "Edit post" msgid "Edit post"
msgstr "Beitrag bearbeiten" msgstr "Beitrag bearbeiten"
#: ../../mod/editpost.php:80 ../../include/conversation.php:950 #: ../../mod/editpost.php:80 ../../include/conversation.php:953
msgid "Post to Email" msgid "Post to Email"
msgstr "An E-Mail senden" msgstr "An E-Mail senden"
#: ../../mod/editpost.php:95 ../../mod/settings.php:601 #: ../../mod/editpost.php:95 ../../mod/settings.php:601
#: ../../include/conversation.php:571 #: ../../include/conversation.php:574
msgid "Edit" msgid "Edit"
msgstr "Bearbeiten" msgstr "Bearbeiten"
#: ../../mod/editpost.php:96 ../../mod/wallmessage.php:143 #: ../../mod/editpost.php:96 ../../mod/wallmessage.php:143
#: ../../mod/message.php:186 ../../mod/message.php:378 #: ../../mod/message.php:212 ../../mod/message.php:406
#: ../../include/conversation.php:965 #: ../../include/conversation.php:968
msgid "Upload photo" msgid "Upload photo"
msgstr "Foto hochladen" msgstr "Foto hochladen"
#: ../../mod/editpost.php:97 ../../include/conversation.php:967 #: ../../mod/editpost.php:97 ../../include/conversation.php:970
msgid "Attach file" msgid "Attach file"
msgstr "Datei anhängen" msgstr "Datei anhängen"
#: ../../mod/editpost.php:98 ../../mod/wallmessage.php:144 #: ../../mod/editpost.php:98 ../../mod/wallmessage.php:144
#: ../../mod/message.php:187 ../../mod/message.php:379 #: ../../mod/message.php:213 ../../mod/message.php:407
#: ../../include/conversation.php:969 #: ../../include/conversation.php:972
msgid "Insert web link" msgid "Insert web link"
msgstr "einen Link einfügen" msgstr "einen Link einfügen"
@ -671,35 +671,35 @@ msgstr "Vorbis [.ogg] Video einfügen"
msgid "Insert Vorbis [.ogg] audio" msgid "Insert Vorbis [.ogg] audio"
msgstr "Vorbis [.ogg] Audio einfügen" msgstr "Vorbis [.ogg] Audio einfügen"
#: ../../mod/editpost.php:102 ../../include/conversation.php:975 #: ../../mod/editpost.php:102 ../../include/conversation.php:978
msgid "Set your location" msgid "Set your location"
msgstr "Deinen Standort festlegen" msgstr "Deinen Standort festlegen"
#: ../../mod/editpost.php:103 ../../include/conversation.php:977 #: ../../mod/editpost.php:103 ../../include/conversation.php:980
msgid "Clear browser location" msgid "Clear browser location"
msgstr "Browser-Standort leeren" msgstr "Browser-Standort leeren"
#: ../../mod/editpost.php:105 ../../include/conversation.php:984 #: ../../mod/editpost.php:105 ../../include/conversation.php:987
msgid "Permission settings" msgid "Permission settings"
msgstr "Berechtigungseinstellungen" msgstr "Berechtigungseinstellungen"
#: ../../mod/editpost.php:113 ../../include/conversation.php:993 #: ../../mod/editpost.php:113 ../../include/conversation.php:996
msgid "CC: email addresses" msgid "CC: email addresses"
msgstr "Cc:-E-Mail-Addressen" msgstr "Cc:-E-Mail-Addressen"
#: ../../mod/editpost.php:114 ../../include/conversation.php:994 #: ../../mod/editpost.php:114 ../../include/conversation.php:997
msgid "Public post" msgid "Public post"
msgstr "Öffentlicher Beitrag" msgstr "Öffentlicher Beitrag"
#: ../../mod/editpost.php:117 ../../include/conversation.php:980 #: ../../mod/editpost.php:117 ../../include/conversation.php:983
msgid "Set title" msgid "Set title"
msgstr "Titel setzen" msgstr "Titel setzen"
#: ../../mod/editpost.php:119 ../../include/conversation.php:982 #: ../../mod/editpost.php:119 ../../include/conversation.php:985
msgid "Categories (comma-separated list)" msgid "Categories (comma-separated list)"
msgstr "Kategorien (kommasepariert)" msgstr "Kategorien (kommasepariert)"
#: ../../mod/editpost.php:120 ../../include/conversation.php:996 #: ../../mod/editpost.php:120 ../../include/conversation.php:999
msgid "Example: bob@example.com, mary@example.com" msgid "Example: bob@example.com, mary@example.com"
msgstr "Z.B.: bob@example.com, mary@example.com" msgstr "Z.B.: bob@example.com, mary@example.com"
@ -780,7 +780,7 @@ msgstr "Es scheint so, als ob du bereits mit %s befreundet bist."
msgid "Invalid profile URL." msgid "Invalid profile URL."
msgstr "Ungültige Profil-URL." msgstr "Ungültige Profil-URL."
#: ../../mod/dfrn_request.php:476 ../../mod/follow.php:20 #: ../../mod/dfrn_request.php:476 ../../mod/follow.php:23
msgid "Disallowed profile URL." msgid "Disallowed profile URL."
msgstr "Nicht erlaubte Profil-URL." msgstr "Nicht erlaubte Profil-URL."
@ -816,7 +816,7 @@ msgstr "Bitte bestätige deine Kontaktanfrage bei %s."
msgid "Confirm" msgid "Confirm"
msgstr "Bestätigen" msgstr "Bestätigen"
#: ../../mod/dfrn_request.php:688 ../../include/items.php:2707 #: ../../mod/dfrn_request.php:688 ../../include/items.php:2717
msgid "[Name Withheld]" msgid "[Name Withheld]"
msgstr "[Name unterdrückt]" msgstr "[Name unterdrückt]"
@ -1180,7 +1180,7 @@ msgid "is interested in:"
msgstr "ist interessiert an:" msgstr "ist interessiert an:"
#: ../../mod/match.php:58 ../../mod/suggest.php:59 #: ../../mod/match.php:58 ../../mod/suggest.php:59
#: ../../include/contact_widgets.php:9 ../../boot.php:1036 #: ../../include/contact_widgets.php:9 ../../boot.php:1046
msgid "Connect" msgid "Connect"
msgstr "Verbinden" msgstr "Verbinden"
@ -1228,7 +1228,7 @@ msgstr "Netzwerk"
msgid "Personal" msgid "Personal"
msgstr "Persönlich" msgstr "Persönlich"
#: ../../mod/notifications.php:90 ../../view/theme/diabook/theme.php:65 #: ../../mod/notifications.php:90 ../../view/theme/diabook/theme.php:122
#: ../../include/nav.php:77 ../../include/nav.php:115 #: ../../include/nav.php:77 ../../include/nav.php:115
msgid "Home" msgid "Home"
msgstr "Pinnwand" msgstr "Pinnwand"
@ -1237,7 +1237,7 @@ msgstr "Pinnwand"
msgid "Introductions" msgid "Introductions"
msgstr "Kontaktanfragen" msgstr "Kontaktanfragen"
#: ../../mod/notifications.php:100 ../../mod/message.php:102 #: ../../mod/notifications.php:100 ../../mod/message.php:104
#: ../../include/nav.php:128 #: ../../include/nav.php:128
msgid "Messages" msgid "Messages"
msgstr "Nachrichten" msgstr "Nachrichten"
@ -1277,7 +1277,7 @@ msgid "if applicable"
msgstr "falls anwendbar" msgstr "falls anwendbar"
#: ../../mod/notifications.php:157 ../../mod/notifications.php:204 #: ../../mod/notifications.php:157 ../../mod/notifications.php:204
#: ../../mod/admin.php:642 #: ../../mod/admin.php:645
msgid "Approve" msgid "Approve"
msgstr "Genehmigen" msgstr "Genehmigen"
@ -1478,12 +1478,12 @@ msgid "View all contacts"
msgstr "Alle Kontakte anzeigen" msgstr "Alle Kontakte anzeigen"
#: ../../mod/contacts.php:290 ../../mod/contacts.php:347 #: ../../mod/contacts.php:290 ../../mod/contacts.php:347
#: ../../mod/admin.php:646 #: ../../mod/admin.php:649
msgid "Unblock" msgid "Unblock"
msgstr "Entsperren" msgstr "Entsperren"
#: ../../mod/contacts.php:290 ../../mod/contacts.php:347 #: ../../mod/contacts.php:290 ../../mod/contacts.php:347
#: ../../mod/admin.php:645 #: ../../mod/admin.php:648
msgid "Block" msgid "Block"
msgstr "Sperren" msgstr "Sperren"
@ -1576,7 +1576,7 @@ msgstr "letzte Aktualisierung:"
msgid "Update public posts" msgid "Update public posts"
msgstr "Öffentliche Beiträge aktualisieren" msgstr "Öffentliche Beiträge aktualisieren"
#: ../../mod/contacts.php:344 ../../mod/admin.php:1117 #: ../../mod/contacts.php:344 ../../mod/admin.php:1120
msgid "Update now" msgid "Update now"
msgstr "Jetzt aktualisieren" msgstr "Jetzt aktualisieren"
@ -1669,7 +1669,7 @@ msgstr "du bist Fan von"
msgid "Edit contact" msgid "Edit contact"
msgstr "Kontakt bearbeiten" msgstr "Kontakt bearbeiten"
#: ../../mod/contacts.php:544 ../../view/theme/diabook/theme.php:67 #: ../../mod/contacts.php:544 ../../view/theme/diabook/theme.php:124
#: ../../include/nav.php:139 #: ../../include/nav.php:139
msgid "Contacts" msgid "Contacts"
msgstr "Kontakte" msgstr "Kontakte"
@ -1705,8 +1705,8 @@ msgstr "Anfrage zum Zurücksetzen des Passworts auf %s erhalten"
#: ../../mod/regmod.php:54 ../../mod/dfrn_confirm.php:742 #: ../../mod/regmod.php:54 ../../mod/dfrn_confirm.php:742
#: ../../addon/facebook/facebook.php:680 #: ../../addon/facebook/facebook.php:680
#: ../../addon/facebook/facebook.php:1170 #: ../../addon/facebook/facebook.php:1170
#: ../../addon/testdrive/testdrive.php:58 ../../include/items.php:2716 #: ../../addon/testdrive/testdrive.php:58 ../../include/items.php:2726
#: ../../boot.php:686 #: ../../boot.php:696
msgid "Administrator" msgid "Administrator"
msgstr "Administrator" msgstr "Administrator"
@ -1716,7 +1716,7 @@ msgid ""
"Password reset failed." "Password reset failed."
msgstr "Anfrage konnte nicht verifiziert werden. (Eventuell hast du bereits eine ähnliche Anfrage gestellt.) Zurücksetzen des Passworts gescheitert." msgstr "Anfrage konnte nicht verifiziert werden. (Eventuell hast du bereits eine ähnliche Anfrage gestellt.) Zurücksetzen des Passworts gescheitert."
#: ../../mod/lostpass.php:83 ../../boot.php:818 #: ../../mod/lostpass.php:83 ../../boot.php:828
msgid "Password Reset" msgid "Password Reset"
msgstr "Passwort zurücksetzen" msgstr "Passwort zurücksetzen"
@ -1788,8 +1788,9 @@ msgstr "Persönliche Daten exportieren"
msgid "Remove account" msgid "Remove account"
msgstr "Account entfernen" msgstr "Account entfernen"
#: ../../mod/settings.php:88 ../../mod/admin.php:732 ../../mod/admin.php:937 #: ../../mod/settings.php:88 ../../mod/admin.php:735 ../../mod/admin.php:940
#: ../../addon/mathjax/mathjax.php:36 ../../include/nav.php:137 #: ../../addon/mathjax/mathjax.php:36 ../../view/theme/diabook/theme.php:638
#: ../../view/theme/diabook/theme.php:768 ../../include/nav.php:137
msgid "Settings" msgid "Settings"
msgstr "Einstellungen" msgstr "Einstellungen"
@ -2015,7 +2016,7 @@ msgstr "Maximal 100 Beiträge"
msgid "Don't show emoticons" msgid "Don't show emoticons"
msgstr "Keine Smilies anzeigen" msgstr "Keine Smilies anzeigen"
#: ../../mod/settings.php:821 ../../mod/admin.php:180 ../../mod/admin.php:618 #: ../../mod/settings.php:821 ../../mod/admin.php:180 ../../mod/admin.php:621
msgid "Normal Account" msgid "Normal Account"
msgstr "Normaler Account" msgstr "Normaler Account"
@ -2023,7 +2024,7 @@ msgstr "Normaler Account"
msgid "This account is a normal personal profile" msgid "This account is a normal personal profile"
msgstr "Dieser Account ist ein normales persönliches Profil" msgstr "Dieser Account ist ein normales persönliches Profil"
#: ../../mod/settings.php:825 ../../mod/admin.php:181 ../../mod/admin.php:619 #: ../../mod/settings.php:825 ../../mod/admin.php:181 ../../mod/admin.php:622
msgid "Soapbox Account" msgid "Soapbox Account"
msgstr "Sandkasten-Account" msgstr "Sandkasten-Account"
@ -2031,7 +2032,7 @@ msgstr "Sandkasten-Account"
msgid "Automatically approve all connection/friend requests as read-only fans" msgid "Automatically approve all connection/friend requests as read-only fans"
msgstr "Kontaktanfragen werden automatisch als Nurlese-Fans akzeptiert" msgstr "Kontaktanfragen werden automatisch als Nurlese-Fans akzeptiert"
#: ../../mod/settings.php:829 ../../mod/admin.php:182 ../../mod/admin.php:620 #: ../../mod/settings.php:829 ../../mod/admin.php:182 ../../mod/admin.php:623
msgid "Community/Celebrity Account" msgid "Community/Celebrity Account"
msgstr "Gemeinschafts/Promi-Account" msgstr "Gemeinschafts/Promi-Account"
@ -2040,7 +2041,7 @@ msgid ""
"Automatically approve all connection/friend requests as read-write fans" "Automatically approve all connection/friend requests as read-write fans"
msgstr "Kontaktanfragen werden automatisch als Lese-und-Schreib-Fans akzeptiert" msgstr "Kontaktanfragen werden automatisch als Lese-und-Schreib-Fans akzeptiert"
#: ../../mod/settings.php:833 ../../mod/admin.php:183 ../../mod/admin.php:621 #: ../../mod/settings.php:833 ../../mod/admin.php:183 ../../mod/admin.php:624
msgid "Automatic Friend Account" msgid "Automatic Friend Account"
msgstr "Automatischer Freundesaccount" msgstr "Automatischer Freundesaccount"
@ -2366,7 +2367,7 @@ msgstr "Private Nachrichten an diese Person könnten an die Öffentlichkeit gela
msgid "Invalid contact." msgid "Invalid contact."
msgstr "Ungültiger Kontakt." msgstr "Ungültiger Kontakt."
#: ../../mod/notes.php:44 ../../boot.php:1499 #: ../../mod/notes.php:44 ../../boot.php:1509
msgid "Personal Notes" msgid "Personal Notes"
msgstr "Persönliche Notizen" msgstr "Persönliche Notizen"
@ -2382,7 +2383,7 @@ msgstr "Speichern"
msgid "Number of daily wall messages for %s exceeded. Message failed." msgid "Number of daily wall messages for %s exceeded. Message failed."
msgstr "Maximale Anzahl der täglichen Pinnwand Nachrichten für %s ist überschritten. Zustellung fehlgeschlagen." msgstr "Maximale Anzahl der täglichen Pinnwand Nachrichten für %s ist überschritten. Zustellung fehlgeschlagen."
#: ../../mod/wallmessage.php:56 ../../mod/message.php:59 #: ../../mod/wallmessage.php:56 ../../mod/message.php:65
msgid "No recipient selected." msgid "No recipient selected."
msgstr "Kein Empfänger gewählt." msgstr "Kein Empfänger gewählt."
@ -2390,15 +2391,15 @@ msgstr "Kein Empfänger gewählt."
msgid "Unable to check your home location." msgid "Unable to check your home location."
msgstr "Konnte deinen Heimatort nicht bestimmen." msgstr "Konnte deinen Heimatort nicht bestimmen."
#: ../../mod/wallmessage.php:62 ../../mod/message.php:66 #: ../../mod/wallmessage.php:62 ../../mod/message.php:72
msgid "Message could not be sent." msgid "Message could not be sent."
msgstr "Nachricht konnte nicht gesendet werden." msgstr "Nachricht konnte nicht gesendet werden."
#: ../../mod/wallmessage.php:65 ../../mod/message.php:69 #: ../../mod/wallmessage.php:65 ../../mod/message.php:75
msgid "Message collection failure." msgid "Message collection failure."
msgstr "Konnte Nachrichten nicht abrufen." msgstr "Konnte Nachrichten nicht abrufen."
#: ../../mod/wallmessage.php:68 ../../mod/message.php:72 #: ../../mod/wallmessage.php:68 ../../mod/message.php:78
msgid "Message sent." msgid "Message sent."
msgstr "Nachricht gesendet." msgstr "Nachricht gesendet."
@ -2406,12 +2407,12 @@ msgstr "Nachricht gesendet."
msgid "No recipient." msgid "No recipient."
msgstr "Kein Empfänger." msgstr "Kein Empfänger."
#: ../../mod/wallmessage.php:124 ../../mod/message.php:169 #: ../../mod/wallmessage.php:124 ../../mod/message.php:171
#: ../../include/conversation.php:918 #: ../../include/conversation.php:921
msgid "Please enter a link URL:" msgid "Please enter a link URL:"
msgstr "Bitte gib die URL des Links ein:" msgstr "Bitte gib die URL des Links ein:"
#: ../../mod/wallmessage.php:131 ../../mod/message.php:177 #: ../../mod/wallmessage.php:131 ../../mod/message.php:199
msgid "Send Private Message" msgid "Send Private Message"
msgstr "Private Nachricht senden" msgstr "Private Nachricht senden"
@ -2422,18 +2423,18 @@ msgid ""
"your site allow private mail from unknown senders." "your site allow private mail from unknown senders."
msgstr "Wenn du möchtest, dass %s dir antworten kann, überprüfe deine Privatsphären-Einstellungen und erlaube private Nachrichten von unbekannten Absendern." msgstr "Wenn du möchtest, dass %s dir antworten kann, überprüfe deine Privatsphären-Einstellungen und erlaube private Nachrichten von unbekannten Absendern."
#: ../../mod/wallmessage.php:133 ../../mod/message.php:178 #: ../../mod/wallmessage.php:133 ../../mod/message.php:200
#: ../../mod/message.php:370 #: ../../mod/message.php:397
msgid "To:" msgid "To:"
msgstr "An:" msgstr "An:"
#: ../../mod/wallmessage.php:134 ../../mod/message.php:179 #: ../../mod/wallmessage.php:134 ../../mod/message.php:205
#: ../../mod/message.php:371 #: ../../mod/message.php:399
msgid "Subject:" msgid "Subject:"
msgstr "Betreff:" msgstr "Betreff:"
#: ../../mod/wallmessage.php:140 ../../mod/message.php:183 #: ../../mod/wallmessage.php:140 ../../mod/message.php:209
#: ../../mod/message.php:374 ../../mod/invite.php:113 #: ../../mod/message.php:402 ../../mod/invite.php:113
msgid "Your message:" msgid "Your message:"
msgstr "Deine Nachricht:" msgstr "Deine Nachricht:"
@ -2615,9 +2616,9 @@ msgstr "Ungültiger Profil-Bezeichner"
msgid "Profile Visibility Editor" msgid "Profile Visibility Editor"
msgstr "Editor für die Profil-Sichtbarkeit" msgstr "Editor für die Profil-Sichtbarkeit"
#: ../../mod/profperm.php:103 ../../view/theme/diabook/theme.php:66 #: ../../mod/profperm.php:103 ../../view/theme/diabook/theme.php:123
#: ../../include/profile_advanced.php:7 ../../include/profile_advanced.php:74 #: ../../include/profile_advanced.php:7 ../../include/profile_advanced.php:74
#: ../../include/nav.php:50 ../../boot.php:1478 #: ../../include/nav.php:50 ../../boot.php:1488
msgid "Profile" msgid "Profile"
msgstr "Profil" msgstr "Profil"
@ -2766,7 +2767,7 @@ msgstr "Mitgliedschaft auf dieser Seite ist nur nach vorheriger Einladung mögli
msgid "Your invitation ID: " msgid "Your invitation ID: "
msgstr "ID deiner Einladung: " msgstr "ID deiner Einladung: "
#: ../../mod/register.php:553 ../../mod/admin.php:403 #: ../../mod/register.php:553 ../../mod/admin.php:405
msgid "Registration" msgid "Registration"
msgstr "Registrierung" msgstr "Registrierung"
@ -2789,7 +2790,7 @@ msgstr "Wähle einen Spitznamen für dein Profil. Dieser muss mit einem Buchstab
msgid "Choose a nickname: " msgid "Choose a nickname: "
msgstr "Spitznamen wählen: " msgstr "Spitznamen wählen: "
#: ../../mod/register.php:567 ../../include/nav.php:81 ../../boot.php:784 #: ../../mod/register.php:567 ../../include/nav.php:81 ../../boot.php:794
msgid "Register" msgid "Register"
msgstr "Registrieren" msgstr "Registrieren"
@ -2801,8 +2802,8 @@ msgstr "Personen Suche"
#: ../../addon/facebook/facebook.php:1564 #: ../../addon/facebook/facebook.php:1564
#: ../../addon/communityhome/communityhome.php:158 #: ../../addon/communityhome/communityhome.php:158
#: ../../addon/communityhome/communityhome.php:167 #: ../../addon/communityhome/communityhome.php:167
#: ../../view/theme/diabook/theme.php:452 #: ../../view/theme/diabook/theme.php:560
#: ../../view/theme/diabook/theme.php:461 ../../include/diaspora.php:1654 #: ../../view/theme/diabook/theme.php:569 ../../include/diaspora.php:1654
#: ../../include/conversation.php:48 ../../include/conversation.php:57 #: ../../include/conversation.php:48 ../../include/conversation.php:57
#: ../../include/conversation.php:121 ../../include/conversation.php:130 #: ../../include/conversation.php:121 ../../include/conversation.php:130
msgid "status" msgid "status"
@ -2810,7 +2811,7 @@ msgstr "Status"
#: ../../mod/like.php:144 ../../addon/facebook/facebook.php:1568 #: ../../mod/like.php:144 ../../addon/facebook/facebook.php:1568
#: ../../addon/communityhome/communityhome.php:172 #: ../../addon/communityhome/communityhome.php:172
#: ../../view/theme/diabook/theme.php:466 ../../include/diaspora.php:1670 #: ../../view/theme/diabook/theme.php:574 ../../include/diaspora.php:1670
#: ../../include/conversation.php:65 #: ../../include/conversation.php:65
#, php-format #, php-format
msgid "%1$s likes %2$s's %3$s" msgid "%1$s likes %2$s's %3$s"
@ -2822,8 +2823,8 @@ msgid "%1$s doesn't like %2$s's %3$s"
msgstr "%1$s mag %2$ss %3$s nicht" msgstr "%1$s mag %2$ss %3$s nicht"
#: ../../mod/notice.php:15 ../../mod/viewsrc.php:15 ../../mod/admin.php:156 #: ../../mod/notice.php:15 ../../mod/viewsrc.php:15 ../../mod/admin.php:156
#: ../../mod/admin.php:681 ../../mod/admin.php:880 ../../mod/display.php:37 #: ../../mod/admin.php:684 ../../mod/admin.php:883 ../../mod/display.php:37
#: ../../mod/display.php:142 ../../include/items.php:3074 #: ../../mod/display.php:142 ../../include/items.php:3084
msgid "Item not found." msgid "Item not found."
msgstr "Beitrag nicht gefunden." msgstr "Beitrag nicht gefunden."
@ -2831,8 +2832,8 @@ msgstr "Beitrag nicht gefunden."
msgid "Access denied." msgid "Access denied."
msgstr "Zugriff verweigert." msgstr "Zugriff verweigert."
#: ../../mod/fbrowser.php:23 ../../view/theme/diabook/theme.php:68 #: ../../mod/fbrowser.php:23 ../../view/theme/diabook/theme.php:125
#: ../../include/nav.php:51 ../../boot.php:1484 #: ../../include/nav.php:51 ../../boot.php:1494
msgid "Photos" msgid "Photos"
msgstr "Bilder" msgstr "Bilder"
@ -2973,71 +2974,71 @@ msgstr "Dies wird deinen Account endgültig löschen. Es gibt keine Möglichkeit
msgid "Please enter your password for verification:" msgid "Please enter your password for verification:"
msgstr "Bitte gib dein Passwort zur Verifikation ein:" msgstr "Bitte gib dein Passwort zur Verifikation ein:"
#: ../../mod/message.php:22 ../../include/nav.php:131 #: ../../mod/message.php:9 ../../include/nav.php:131
msgid "New Message" msgid "New Message"
msgstr "Neue Nachricht" msgstr "Neue Nachricht"
#: ../../mod/message.php:63 #: ../../mod/message.php:69
msgid "Unable to locate contact information." msgid "Unable to locate contact information."
msgstr "Konnte die Kontaktinformationen nicht finden." msgstr "Konnte die Kontaktinformationen nicht finden."
#: ../../mod/message.php:117 #: ../../mod/message.php:119
msgid "Message deleted." msgid "Message deleted."
msgstr "Nachricht gelöscht." msgstr "Nachricht gelöscht."
#: ../../mod/message.php:147 #: ../../mod/message.php:149
msgid "Conversation removed." msgid "Conversation removed."
msgstr "Unterhaltung gelöscht." msgstr "Unterhaltung gelöscht."
#: ../../mod/message.php:219 #: ../../mod/message.php:245
msgid "No messages." msgid "No messages."
msgstr "Keine Nachrichten." msgstr "Keine Nachrichten."
#: ../../mod/message.php:226 #: ../../mod/message.php:252
#, php-format #, php-format
msgid "Unknown sender - %s" msgid "Unknown sender - %s"
msgstr "'Unbekannter Absender - %s" msgstr "'Unbekannter Absender - %s"
#: ../../mod/message.php:229 #: ../../mod/message.php:255
#, php-format #, php-format
msgid "You and %s" msgid "You and %s"
msgstr "Du und %s" msgstr "Du und %s"
#: ../../mod/message.php:232 #: ../../mod/message.php:258
#, php-format #, php-format
msgid "%s and You" msgid "%s and You"
msgstr "%s und Du" msgstr "%s und Du"
#: ../../mod/message.php:242 ../../mod/message.php:363 #: ../../mod/message.php:268 ../../mod/message.php:390
msgid "Delete conversation" msgid "Delete conversation"
msgstr "Unterhaltung löschen" msgstr "Unterhaltung löschen"
#: ../../mod/message.php:245 #: ../../mod/message.php:271
msgid "D, d M Y - g:i A" msgid "D, d M Y - g:i A"
msgstr "D, d. M Y - g:i A" msgstr "D, d. M Y - g:i A"
#: ../../mod/message.php:247 #: ../../mod/message.php:273
#, php-format #, php-format
msgid "%d message" msgid "%d message"
msgid_plural "%d messages" msgid_plural "%d messages"
msgstr[0] "%d Nachricht" msgstr[0] "%d Nachricht"
msgstr[1] "%d Nachrichten" msgstr[1] "%d Nachrichten"
#: ../../mod/message.php:282 #: ../../mod/message.php:308
msgid "Message not available." msgid "Message not available."
msgstr "Nachricht nicht verfügbar." msgstr "Nachricht nicht verfügbar."
#: ../../mod/message.php:347 #: ../../mod/message.php:373
msgid "Delete message" msgid "Delete message"
msgstr "Nachricht löschen" msgstr "Nachricht löschen"
#: ../../mod/message.php:365 #: ../../mod/message.php:392
msgid "" msgid ""
"No secure communications available. You <strong>may</strong> be able to " "No secure communications available. You <strong>may</strong> be able to "
"respond from the sender's profile page." "respond from the sender's profile page."
msgstr "Sichere Kommunikation ist nicht verfügbar. <strong>Eventuell</strong> kannst du auf der Profilseite des Absenders antworten." msgstr "Sichere Kommunikation ist nicht verfügbar. <strong>Eventuell</strong> kannst du auf der Profilseite des Absenders antworten."
#: ../../mod/message.php:369 #: ../../mod/message.php:396
msgid "Send Reply" msgid "Send Reply"
msgstr "Antwort senden" msgstr "Antwort senden"
@ -3054,19 +3055,19 @@ msgstr "Keine Freunde zum Anzeigen."
msgid "Theme settings updated." msgid "Theme settings updated."
msgstr "Themen Einstellungen aktualisiert." msgstr "Themen Einstellungen aktualisiert."
#: ../../mod/admin.php:96 ../../mod/admin.php:401 #: ../../mod/admin.php:96 ../../mod/admin.php:403
msgid "Site" msgid "Site"
msgstr "Seite" msgstr "Seite"
#: ../../mod/admin.php:97 ../../mod/admin.php:636 ../../mod/admin.php:648 #: ../../mod/admin.php:97 ../../mod/admin.php:639 ../../mod/admin.php:651
msgid "Users" msgid "Users"
msgstr "Nutzer" msgstr "Nutzer"
#: ../../mod/admin.php:98 ../../mod/admin.php:730 ../../mod/admin.php:772 #: ../../mod/admin.php:98 ../../mod/admin.php:733 ../../mod/admin.php:775
msgid "Plugins" msgid "Plugins"
msgstr "Plugins" msgstr "Plugins"
#: ../../mod/admin.php:99 ../../mod/admin.php:935 ../../mod/admin.php:971 #: ../../mod/admin.php:99 ../../mod/admin.php:938 ../../mod/admin.php:974
msgid "Themes" msgid "Themes"
msgstr "Themen" msgstr "Themen"
@ -3078,7 +3079,7 @@ msgstr "DB Updates"
msgid "Software Update" msgid "Software Update"
msgstr "Software Update" msgstr "Software Update"
#: ../../mod/admin.php:115 ../../mod/admin.php:1058 #: ../../mod/admin.php:115 ../../mod/admin.php:1061
msgid "Logs" msgid "Logs"
msgstr "Protokolle" msgstr "Protokolle"
@ -3086,9 +3087,9 @@ msgstr "Protokolle"
msgid "User registrations waiting for confirmation" msgid "User registrations waiting for confirmation"
msgstr "Nutzeranmeldungen die auf Bestätigung warten" msgstr "Nutzeranmeldungen die auf Bestätigung warten"
#: ../../mod/admin.php:195 ../../mod/admin.php:400 ../../mod/admin.php:635 #: ../../mod/admin.php:195 ../../mod/admin.php:402 ../../mod/admin.php:638
#: ../../mod/admin.php:729 ../../mod/admin.php:771 ../../mod/admin.php:934 #: ../../mod/admin.php:732 ../../mod/admin.php:774 ../../mod/admin.php:937
#: ../../mod/admin.php:970 ../../mod/admin.php:1057 #: ../../mod/admin.php:973 ../../mod/admin.php:1060
msgid "Administration" msgid "Administration"
msgstr "Administration" msgstr "Administration"
@ -3112,497 +3113,507 @@ msgstr "Version"
msgid "Active plugins" msgid "Active plugins"
msgstr "Aktive Plugins" msgstr "Aktive Plugins"
#: ../../mod/admin.php:339 #: ../../mod/admin.php:341
msgid "Site settings updated." msgid "Site settings updated."
msgstr "Seiteneinstellungen aktualisiert." msgstr "Seiteneinstellungen aktualisiert."
#: ../../mod/admin.php:387 #: ../../mod/admin.php:389
msgid "Closed" msgid "Closed"
msgstr "Geschlossen" msgstr "Geschlossen"
#: ../../mod/admin.php:388 #: ../../mod/admin.php:390
msgid "Requires approval" msgid "Requires approval"
msgstr "Bedarf der Zustimmung" msgstr "Bedarf der Zustimmung"
#: ../../mod/admin.php:389 #: ../../mod/admin.php:391
msgid "Open" msgid "Open"
msgstr "Offen" msgstr "Offen"
#: ../../mod/admin.php:393 #: ../../mod/admin.php:395
msgid "No SSL policy, links will track page SSL state" msgid "No SSL policy, links will track page SSL state"
msgstr "Keine SSL Richtlinie, Links werden das verwendete Protokoll beibehalten" msgstr "Keine SSL Richtlinie, Links werden das verwendete Protokoll beibehalten"
#: ../../mod/admin.php:394 #: ../../mod/admin.php:396
msgid "Force all links to use SSL" msgid "Force all links to use SSL"
msgstr "SSL für alle Links erzwingen" msgstr "SSL für alle Links erzwingen"
#: ../../mod/admin.php:395 #: ../../mod/admin.php:397
msgid "Self-signed certificate, use SSL for local links only (discouraged)" msgid "Self-signed certificate, use SSL for local links only (discouraged)"
msgstr "Selbst-unterzeichnetes Zertifikat, SSL nur für lokale Links verwenden (nicht empfohlen)" msgstr "Selbst-unterzeichnetes Zertifikat, SSL nur für lokale Links verwenden (nicht empfohlen)"
#: ../../mod/admin.php:404 #: ../../mod/admin.php:406
msgid "File upload" msgid "File upload"
msgstr "Datei hochladen" msgstr "Datei hochladen"
#: ../../mod/admin.php:405 #: ../../mod/admin.php:407
msgid "Policies" msgid "Policies"
msgstr "Regeln" msgstr "Regeln"
#: ../../mod/admin.php:406 #: ../../mod/admin.php:408
msgid "Advanced" msgid "Advanced"
msgstr "Erweitert" msgstr "Erweitert"
#: ../../mod/admin.php:410 ../../addon/statusnet/statusnet.php:544 #: ../../mod/admin.php:412 ../../addon/statusnet/statusnet.php:544
msgid "Site name" msgid "Site name"
msgstr "Seitenname" msgstr "Seitenname"
#: ../../mod/admin.php:411 #: ../../mod/admin.php:413
msgid "Banner/Logo" msgid "Banner/Logo"
msgstr "Banner/Logo" msgstr "Banner/Logo"
#: ../../mod/admin.php:412 #: ../../mod/admin.php:414
msgid "System language" msgid "System language"
msgstr "Systemsprache" msgstr "Systemsprache"
#: ../../mod/admin.php:413 #: ../../mod/admin.php:415
msgid "System theme" msgid "System theme"
msgstr "Systemweites Thema" msgstr "Systemweites Thema"
#: ../../mod/admin.php:413 #: ../../mod/admin.php:415
msgid "" msgid ""
"Default system theme - may be over-ridden by user profiles - <a href='#' " "Default system theme - may be over-ridden by user profiles - <a href='#' "
"id='cnftheme'>change theme settings</a>" "id='cnftheme'>change theme settings</a>"
msgstr "Vorgabe für das System-Theme - kann von Benutzerprofilen überschrieben werden - <a href='#' id='cnftheme'>Theme-Einstellungen ändern</a>" msgstr "Vorgabe für das System-Theme - kann von Benutzerprofilen überschrieben werden - <a href='#' id='cnftheme'>Theme-Einstellungen ändern</a>"
#: ../../mod/admin.php:414 #: ../../mod/admin.php:416
msgid "SSL link policy" msgid "SSL link policy"
msgstr "Regeln für SSL Links" msgstr "Regeln für SSL Links"
#: ../../mod/admin.php:414 #: ../../mod/admin.php:416
msgid "Determines whether generated links should be forced to use SSL" msgid "Determines whether generated links should be forced to use SSL"
msgstr "Bestimmt, ob generierte Links SSL verwenden müssen" msgstr "Bestimmt, ob generierte Links SSL verwenden müssen"
#: ../../mod/admin.php:415 #: ../../mod/admin.php:417
msgid "Maximum image size" msgid "Maximum image size"
msgstr "Maximale Größe von Bildern" msgstr "Maximale Größe von Bildern"
#: ../../mod/admin.php:415 #: ../../mod/admin.php:417
msgid "" msgid ""
"Maximum size in bytes of uploaded images. Default is 0, which means no " "Maximum size in bytes of uploaded images. Default is 0, which means no "
"limits." "limits."
msgstr "Maximale Upload-Größe von Bildern in Bytes. Standard ist 0, d.h. ohne Limit." msgstr "Maximale Upload-Größe von Bildern in Bytes. Standard ist 0, d.h. ohne Limit."
#: ../../mod/admin.php:417 #: ../../mod/admin.php:419
msgid "Register policy" msgid "Register policy"
msgstr "Registrierungsmethode" msgstr "Registrierungsmethode"
#: ../../mod/admin.php:418 #: ../../mod/admin.php:420
msgid "Register text" msgid "Register text"
msgstr "Registrierungstext" msgstr "Registrierungstext"
#: ../../mod/admin.php:418 #: ../../mod/admin.php:420
msgid "Will be displayed prominently on the registration page." msgid "Will be displayed prominently on the registration page."
msgstr "Wird gut sichtbar auf der Registrierungs-Seite angezeigt." msgstr "Wird gut sichtbar auf der Registrierungs-Seite angezeigt."
#: ../../mod/admin.php:419 #: ../../mod/admin.php:421
msgid "Accounts abandoned after x days" msgid "Accounts abandoned after x days"
msgstr "Accounts gelten nach x Tagen als unbenutzt" msgstr "Accounts gelten nach x Tagen als unbenutzt"
#: ../../mod/admin.php:419 #: ../../mod/admin.php:421
msgid "" msgid ""
"Will not waste system resources polling external sites for abandonded " "Will not waste system resources polling external sites for abandonded "
"accounts. Enter 0 for no time limit." "accounts. Enter 0 for no time limit."
msgstr "Verschwende keine System-Ressourcen auf das Pollen externer Seiten, wenn Accounts nicht mehr benutzt werden. 0 eingeben für kein Limit." msgstr "Verschwende keine System-Ressourcen auf das Pollen externer Seiten, wenn Accounts nicht mehr benutzt werden. 0 eingeben für kein Limit."
#: ../../mod/admin.php:420 #: ../../mod/admin.php:422
msgid "Allowed friend domains" msgid "Allowed friend domains"
msgstr "Erlaubte Domains für Kontakte" msgstr "Erlaubte Domains für Kontakte"
#: ../../mod/admin.php:420 #: ../../mod/admin.php:422
msgid "" msgid ""
"Comma separated list of domains which are allowed to establish friendships " "Comma separated list of domains which are allowed to establish friendships "
"with this site. Wildcards are accepted. Empty to allow any domains" "with this site. Wildcards are accepted. Empty to allow any domains"
msgstr "Liste der Domains, die für Freundschaften erlaubt sind, durch Kommas getrennt. Platzhalter werden akzeptiert. Leer lassen, um alle Domains zu erlauben." msgstr "Liste der Domains, die für Freundschaften erlaubt sind, durch Kommas getrennt. Platzhalter werden akzeptiert. Leer lassen, um alle Domains zu erlauben."
#: ../../mod/admin.php:421 #: ../../mod/admin.php:423
msgid "Allowed email domains" msgid "Allowed email domains"
msgstr "Erlaubte Domains für Emails" msgstr "Erlaubte Domains für Emails"
#: ../../mod/admin.php:421 #: ../../mod/admin.php:423
msgid "" msgid ""
"Comma separated list of domains which are allowed in email addresses for " "Comma separated list of domains which are allowed in email addresses for "
"registrations to this site. Wildcards are accepted. Empty to allow any " "registrations to this site. Wildcards are accepted. Empty to allow any "
"domains" "domains"
msgstr "Liste der Domains, die für E-Mail-Adressen bei der Registrierung erlaubt sind, durch Kommas getrennt. Platzhalter werden akzeptiert. Leer lassen, um alle Domains zu erlauben." msgstr "Liste der Domains, die für E-Mail-Adressen bei der Registrierung erlaubt sind, durch Kommas getrennt. Platzhalter werden akzeptiert. Leer lassen, um alle Domains zu erlauben."
#: ../../mod/admin.php:422 #: ../../mod/admin.php:424
msgid "Block public" msgid "Block public"
msgstr "Öffentlichen Zugriff blockieren" msgstr "Öffentlichen Zugriff blockieren"
#: ../../mod/admin.php:422 #: ../../mod/admin.php:424
msgid "" msgid ""
"Check to block public access to all otherwise public personal pages on this " "Check to block public access to all otherwise public personal pages on this "
"site unless you are currently logged in." "site unless you are currently logged in."
msgstr "Klicken, um öffentlichen Zugriff auf sonst öffentliche Profile zu blockieren, wenn man nicht eingeloggt ist." msgstr "Klicken, um öffentlichen Zugriff auf sonst öffentliche Profile zu blockieren, wenn man nicht eingeloggt ist."
#: ../../mod/admin.php:423 #: ../../mod/admin.php:425
msgid "Force publish" msgid "Force publish"
msgstr "Erzwinge Veröffentlichung" msgstr "Erzwinge Veröffentlichung"
#: ../../mod/admin.php:423 #: ../../mod/admin.php:425
msgid "" msgid ""
"Check to force all profiles on this site to be listed in the site directory." "Check to force all profiles on this site to be listed in the site directory."
msgstr "Klicken, um Anzeige aller Profile dieses Servers im Verzeichnis zu erzwingen." msgstr "Klicken, um Anzeige aller Profile dieses Servers im Verzeichnis zu erzwingen."
#: ../../mod/admin.php:424 #: ../../mod/admin.php:426
msgid "Global directory update URL" msgid "Global directory update URL"
msgstr "URL für Updates beim weltweiten Verzeichnis" msgstr "URL für Updates beim weltweiten Verzeichnis"
#: ../../mod/admin.php:424 #: ../../mod/admin.php:426
msgid "" msgid ""
"URL to update the global directory. If this is not set, the global directory" "URL to update the global directory. If this is not set, the global directory"
" is completely unavailable to the application." " is completely unavailable to the application."
msgstr "URL für Update des globalen Verzeichnisses. Wenn nichts eingetragen ist, bleibt das globale Verzeichnis unerreichbar." msgstr "URL für Update des globalen Verzeichnisses. Wenn nichts eingetragen ist, bleibt das globale Verzeichnis unerreichbar."
#: ../../mod/admin.php:426 #: ../../mod/admin.php:428
msgid "Block multiple registrations" msgid "Block multiple registrations"
msgstr "Unterbinde Mehrfachregistrierung" msgstr "Unterbinde Mehrfachregistrierung"
#: ../../mod/admin.php:426 #: ../../mod/admin.php:428
msgid "Disallow users to register additional accounts for use as pages." msgid "Disallow users to register additional accounts for use as pages."
msgstr "Benutzern nicht erlauben, weitere Accounts als zusätzliche Profile anzulegen." msgstr "Benutzern nicht erlauben, weitere Accounts als zusätzliche Profile anzulegen."
#: ../../mod/admin.php:427 #: ../../mod/admin.php:429
msgid "OpenID support" msgid "OpenID support"
msgstr "OpenID Unterstützung" msgstr "OpenID Unterstützung"
#: ../../mod/admin.php:427 #: ../../mod/admin.php:429
msgid "OpenID support for registration and logins." msgid "OpenID support for registration and logins."
msgstr "OpenID-Unterstützung für Registrierung und Login." msgstr "OpenID-Unterstützung für Registrierung und Login."
#: ../../mod/admin.php:428 #: ../../mod/admin.php:430
msgid "Fullname check" msgid "Fullname check"
msgstr "Namen auf Vollständigkeit überprüfen" msgstr "Namen auf Vollständigkeit überprüfen"
#: ../../mod/admin.php:428 #: ../../mod/admin.php:430
msgid "" msgid ""
"Force users to register with a space between firstname and lastname in Full " "Force users to register with a space between firstname and lastname in Full "
"name, as an antispam measure" "name, as an antispam measure"
msgstr "Leerzeichen zwischen Vor- und Nachname im vollständigen Namen erzwingen, um SPAM zu vermeiden." msgstr "Leerzeichen zwischen Vor- und Nachname im vollständigen Namen erzwingen, um SPAM zu vermeiden."
#: ../../mod/admin.php:429 #: ../../mod/admin.php:431
msgid "UTF-8 Regular expressions" msgid "UTF-8 Regular expressions"
msgstr "UTF-8 Reguläre Ausdrücke" msgstr "UTF-8 Reguläre Ausdrücke"
#: ../../mod/admin.php:429 #: ../../mod/admin.php:431
msgid "Use PHP UTF8 regular expressions" msgid "Use PHP UTF8 regular expressions"
msgstr "PHP UTF8 Ausdrücke verwenden" msgstr "PHP UTF8 Ausdrücke verwenden"
#: ../../mod/admin.php:430 #: ../../mod/admin.php:432
msgid "Show Community Page" msgid "Show Community Page"
msgstr "Gemeinschaftsseite anzeigen" msgstr "Gemeinschaftsseite anzeigen"
#: ../../mod/admin.php:430 #: ../../mod/admin.php:432
msgid "" msgid ""
"Display a Community page showing all recent public postings on this site." "Display a Community page showing all recent public postings on this site."
msgstr "Zeige die Gemeinschaftsseite mit allen öffentlichen Beiträgen auf diesem Server." msgstr "Zeige die Gemeinschaftsseite mit allen öffentlichen Beiträgen auf diesem Server."
#: ../../mod/admin.php:431 #: ../../mod/admin.php:433
msgid "Enable OStatus support" msgid "Enable OStatus support"
msgstr "OStatus Unterstützung aktivieren" msgstr "OStatus Unterstützung aktivieren"
#: ../../mod/admin.php:431 #: ../../mod/admin.php:433
msgid "" msgid ""
"Provide built-in OStatus (identi.ca, status.net, etc.) compatibility. All " "Provide built-in OStatus (identi.ca, status.net, etc.) compatibility. All "
"communications in OStatus are public, so privacy warnings will be " "communications in OStatus are public, so privacy warnings will be "
"occasionally displayed." "occasionally displayed."
msgstr "Biete die eingebaute OStatus (identi.ca, status.net, etc.) Unterstützung an. Jede Kommunikation in OStatus ist öffentlich, so Privatsphäre Warnungen werden bei Bedarf angezeigt." msgstr "Biete die eingebaute OStatus (identi.ca, status.net, etc.) Unterstützung an. Jede Kommunikation in OStatus ist öffentlich, so Privatsphäre Warnungen werden bei Bedarf angezeigt."
#: ../../mod/admin.php:432 #: ../../mod/admin.php:434
msgid "Enable Diaspora support" msgid "Enable Diaspora support"
msgstr "Diaspora-Support aktivieren" msgstr "Diaspora-Support aktivieren"
#: ../../mod/admin.php:432 #: ../../mod/admin.php:434
msgid "Provide built-in Diaspora network compatibility." msgid "Provide built-in Diaspora network compatibility."
msgstr "Verwende die eingebaute Diaspora-Verknüpfung." msgstr "Verwende die eingebaute Diaspora-Verknüpfung."
#: ../../mod/admin.php:433 #: ../../mod/admin.php:435
msgid "Only allow Friendica contacts" msgid "Only allow Friendica contacts"
msgstr "Nur Friendica-Kontakte erlauben" msgstr "Nur Friendica-Kontakte erlauben"
#: ../../mod/admin.php:433 #: ../../mod/admin.php:435
msgid "" msgid ""
"All contacts must use Friendica protocols. All other built-in communication " "All contacts must use Friendica protocols. All other built-in communication "
"protocols disabled." "protocols disabled."
msgstr "Alle Kontakte müssen das Friendica Protokoll nutzen. Alle anderen Kommunikationsprotokolle werden deaktiviert." msgstr "Alle Kontakte müssen das Friendica Protokoll nutzen. Alle anderen Kommunikationsprotokolle werden deaktiviert."
#: ../../mod/admin.php:434 #: ../../mod/admin.php:436
msgid "Verify SSL" msgid "Verify SSL"
msgstr "SSL Überprüfen" msgstr "SSL Überprüfen"
#: ../../mod/admin.php:434 #: ../../mod/admin.php:436
msgid "" msgid ""
"If you wish, you can turn on strict certificate checking. This will mean you" "If you wish, you can turn on strict certificate checking. This will mean you"
" cannot connect (at all) to self-signed SSL sites." " cannot connect (at all) to self-signed SSL sites."
msgstr "Wenn gewollt, kann man hier eine strenge Zertifikat Kontrolle einstellen. Das bedeutet, dass man zu keinen Seiten mit selbst unterzeichnetem SSL eine Verbindung herstellen kann." msgstr "Wenn gewollt, kann man hier eine strenge Zertifikat Kontrolle einstellen. Das bedeutet, dass man zu keinen Seiten mit selbst unterzeichnetem SSL eine Verbindung herstellen kann."
#: ../../mod/admin.php:435 #: ../../mod/admin.php:437
msgid "Proxy user" msgid "Proxy user"
msgstr "Proxy Nutzer" msgstr "Proxy Nutzer"
#: ../../mod/admin.php:436 #: ../../mod/admin.php:438
msgid "Proxy URL" msgid "Proxy URL"
msgstr "Proxy URL" msgstr "Proxy URL"
#: ../../mod/admin.php:437 #: ../../mod/admin.php:439
msgid "Network timeout" msgid "Network timeout"
msgstr "Netzwerk Wartezeit" msgstr "Netzwerk Wartezeit"
#: ../../mod/admin.php:437 #: ../../mod/admin.php:439
msgid "Value is in seconds. Set to 0 for unlimited (not recommended)." msgid "Value is in seconds. Set to 0 for unlimited (not recommended)."
msgstr "Der Wert ist in Sekunden. Setze 0 für unbegrenzt (nicht empfohlen)." msgstr "Der Wert ist in Sekunden. Setze 0 für unbegrenzt (nicht empfohlen)."
#: ../../mod/admin.php:438 #: ../../mod/admin.php:440
msgid "Delivery interval" msgid "Delivery interval"
msgstr "Zustellungsintervall" msgstr "Zustellungsintervall"
#: ../../mod/admin.php:438 #: ../../mod/admin.php:440
msgid "" msgid ""
"Delay background delivery processes by this many seconds to reduce system " "Delay background delivery processes by this many seconds to reduce system "
"load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 " "load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 "
"for large dedicated servers." "for large dedicated servers."
msgstr "Verzögere im Hintergrund laufende Auslieferungsprozesse um die angegebene Anzahl an Sekunden um die Systemlast zu verringern. Empfehlungen: 4-5 für Shared-Hosts, 2-3 für VPS, 0-1 für große dedizierte Server." msgstr "Verzögere im Hintergrund laufende Auslieferungsprozesse um die angegebene Anzahl an Sekunden um die Systemlast zu verringern. Empfehlungen: 4-5 für Shared-Hosts, 2-3 für VPS, 0-1 für große dedizierte Server."
#: ../../mod/admin.php:439 #: ../../mod/admin.php:441
msgid "Poll interval"
msgstr "Abfrage Intervall"
#: ../../mod/admin.php:441
msgid ""
"Delay background polling processes by this many seconds to reduce system "
"load. If 0, use delivery interval."
msgstr "Verzögere Hintergrundprozesse um diese Anzahl an Sekunden um die Systemlast zu reduzieren. Bei 0 Sekunden wird das Auslieferungsintervall verwendet."
#: ../../mod/admin.php:442
msgid "Maximum Load Average" msgid "Maximum Load Average"
msgstr "Maximum Load Average" msgstr "Maximum Load Average"
#: ../../mod/admin.php:439 #: ../../mod/admin.php:442
msgid "" msgid ""
"Maximum system load before delivery and poll processes are deferred - " "Maximum system load before delivery and poll processes are deferred - "
"default 50." "default 50."
msgstr "" msgstr "Maximale Systemlast bevor Verteil- und Empfangsprozesse verschoben werden - Standard 50"
#: ../../mod/admin.php:453 #: ../../mod/admin.php:456
msgid "Update has been marked successful" msgid "Update has been marked successful"
msgstr "Update wurde als erfolgreich markiert" msgstr "Update wurde als erfolgreich markiert"
#: ../../mod/admin.php:463 #: ../../mod/admin.php:466
#, php-format #, php-format
msgid "Executing %s failed. Check system logs." msgid "Executing %s failed. Check system logs."
msgstr "Ausführung von %s schlug fehl. Systemprotokolle prüfen." msgstr "Ausführung von %s schlug fehl. Systemprotokolle prüfen."
#: ../../mod/admin.php:466 #: ../../mod/admin.php:469
#, php-format #, php-format
msgid "Update %s was successfully applied." msgid "Update %s was successfully applied."
msgstr "Update %s war erfolgreich." msgstr "Update %s war erfolgreich."
#: ../../mod/admin.php:470 #: ../../mod/admin.php:473
#, php-format #, php-format
msgid "Update %s did not return a status. Unknown if it succeeded." msgid "Update %s did not return a status. Unknown if it succeeded."
msgstr "Update %s hat keinen Status zurückgegeben. Unbekannter Status." msgstr "Update %s hat keinen Status zurückgegeben. Unbekannter Status."
#: ../../mod/admin.php:473 #: ../../mod/admin.php:476
#, php-format #, php-format
msgid "Update function %s could not be found." msgid "Update function %s could not be found."
msgstr "Updatefunktion %s konnte nicht gefunden werden." msgstr "Updatefunktion %s konnte nicht gefunden werden."
#: ../../mod/admin.php:488 #: ../../mod/admin.php:491
msgid "No failed updates." msgid "No failed updates."
msgstr "Keine fehlgeschlagenen Updates." msgstr "Keine fehlgeschlagenen Updates."
#: ../../mod/admin.php:492 #: ../../mod/admin.php:495
msgid "Failed Updates" msgid "Failed Updates"
msgstr "Fehlgeschlagene Updates" msgstr "Fehlgeschlagene Updates"
#: ../../mod/admin.php:493 #: ../../mod/admin.php:496
msgid "" msgid ""
"This does not include updates prior to 1139, which did not return a status." "This does not include updates prior to 1139, which did not return a status."
msgstr "Ohne Updates vor 1139, da diese keinen Status zurückgegeben haben." msgstr "Ohne Updates vor 1139, da diese keinen Status zurückgegeben haben."
#: ../../mod/admin.php:494 #: ../../mod/admin.php:497
msgid "Mark success (if update was manually applied)" msgid "Mark success (if update was manually applied)"
msgstr "Als erfolgreich markieren (falls das Update manuell installiert wurde)" msgstr "Als erfolgreich markieren (falls das Update manuell installiert wurde)"
#: ../../mod/admin.php:495 #: ../../mod/admin.php:498
msgid "Attempt to execute this update step automatically" msgid "Attempt to execute this update step automatically"
msgstr "Versuchen, diesen Schritt automatisch auszuführen" msgstr "Versuchen, diesen Schritt automatisch auszuführen"
#: ../../mod/admin.php:520 #: ../../mod/admin.php:523
#, php-format #, php-format
msgid "%s user blocked/unblocked" msgid "%s user blocked/unblocked"
msgid_plural "%s users blocked/unblocked" msgid_plural "%s users blocked/unblocked"
msgstr[0] "%s Benutzer geblockt/freigegeben" msgstr[0] "%s Benutzer geblockt/freigegeben"
msgstr[1] "%s Benutzer geblockt/freigegeben" msgstr[1] "%s Benutzer geblockt/freigegeben"
#: ../../mod/admin.php:527 #: ../../mod/admin.php:530
#, php-format #, php-format
msgid "%s user deleted" msgid "%s user deleted"
msgid_plural "%s users deleted" msgid_plural "%s users deleted"
msgstr[0] "%s Nutzer gelöscht" msgstr[0] "%s Nutzer gelöscht"
msgstr[1] "%s Nutzer gelöscht" msgstr[1] "%s Nutzer gelöscht"
#: ../../mod/admin.php:566 #: ../../mod/admin.php:569
#, php-format #, php-format
msgid "User '%s' deleted" msgid "User '%s' deleted"
msgstr "Nutzer '%s' gelöscht" msgstr "Nutzer '%s' gelöscht"
#: ../../mod/admin.php:574 #: ../../mod/admin.php:577
#, php-format #, php-format
msgid "User '%s' unblocked" msgid "User '%s' unblocked"
msgstr "Nutzer '%s' entsperrt" msgstr "Nutzer '%s' entsperrt"
#: ../../mod/admin.php:574 #: ../../mod/admin.php:577
#, php-format #, php-format
msgid "User '%s' blocked" msgid "User '%s' blocked"
msgstr "Nutzer '%s' gesperrt" msgstr "Nutzer '%s' gesperrt"
#: ../../mod/admin.php:638 #: ../../mod/admin.php:641
msgid "select all" msgid "select all"
msgstr "Alle auswählen" msgstr "Alle auswählen"
#: ../../mod/admin.php:639 #: ../../mod/admin.php:642
msgid "User registrations waiting for confirm" msgid "User registrations waiting for confirm"
msgstr "Neuanmeldungen, die auf deine Bestätigung warten" msgstr "Neuanmeldungen, die auf deine Bestätigung warten"
#: ../../mod/admin.php:640 #: ../../mod/admin.php:643
msgid "Request date" msgid "Request date"
msgstr "Anfrage Datum" msgstr "Anfrage Datum"
#: ../../mod/admin.php:640 ../../mod/admin.php:649 #: ../../mod/admin.php:643 ../../mod/admin.php:652
#: ../../include/contact_selectors.php:79 #: ../../include/contact_selectors.php:79
msgid "Email" msgid "Email"
msgstr "Email" msgstr "Email"
#: ../../mod/admin.php:641 #: ../../mod/admin.php:644
msgid "No registrations." msgid "No registrations."
msgstr "Keine Neuanmeldungen." msgstr "Keine Neuanmeldungen."
#: ../../mod/admin.php:643 #: ../../mod/admin.php:646
msgid "Deny" msgid "Deny"
msgstr "Verwehren" msgstr "Verwehren"
#: ../../mod/admin.php:649 #: ../../mod/admin.php:652
msgid "Register date" msgid "Register date"
msgstr "Anmeldedatum" msgstr "Anmeldedatum"
#: ../../mod/admin.php:649 #: ../../mod/admin.php:652
msgid "Last login" msgid "Last login"
msgstr "Letzte Anmeldung" msgstr "Letzte Anmeldung"
#: ../../mod/admin.php:649 #: ../../mod/admin.php:652
msgid "Last item" msgid "Last item"
msgstr "Letzter Beitrag" msgstr "Letzter Beitrag"
#: ../../mod/admin.php:649 #: ../../mod/admin.php:652
msgid "Account" msgid "Account"
msgstr "Nutzerkonto" msgstr "Nutzerkonto"
#: ../../mod/admin.php:651 #: ../../mod/admin.php:654
msgid "" msgid ""
"Selected users will be deleted!\\n\\nEverything these users had posted on " "Selected users will be deleted!\\n\\nEverything these users had posted on "
"this site will be permanently deleted!\\n\\nAre you sure?" "this site will be permanently deleted!\\n\\nAre you sure?"
msgstr "Die markierten Nutzer werden gelöscht!\\n\\nAlle Beiträge, die diese Nutzer auf dieser Seite veröffentlicht haben, werden permanent gelöscht!\\n\\nBist du sicher?" msgstr "Die markierten Nutzer werden gelöscht!\\n\\nAlle Beiträge, die diese Nutzer auf dieser Seite veröffentlicht haben, werden permanent gelöscht!\\n\\nBist du sicher?"
#: ../../mod/admin.php:652 #: ../../mod/admin.php:655
msgid "" msgid ""
"The user {0} will be deleted!\\n\\nEverything this user has posted on this " "The user {0} will be deleted!\\n\\nEverything this user has posted on this "
"site will be permanently deleted!\\n\\nAre you sure?" "site will be permanently deleted!\\n\\nAre you sure?"
msgstr "Der Nutzer {0} wird gelöscht!\\n\\nAlles was dieser Nutzer auf dieser Seite veröffentlicht hat, wird permanent gelöscht!\\n\\nBist du sicher?" msgstr "Der Nutzer {0} wird gelöscht!\\n\\nAlles was dieser Nutzer auf dieser Seite veröffentlicht hat, wird permanent gelöscht!\\n\\nBist du sicher?"
#: ../../mod/admin.php:693 #: ../../mod/admin.php:696
#, php-format #, php-format
msgid "Plugin %s disabled." msgid "Plugin %s disabled."
msgstr "Plugin %s deaktiviert." msgstr "Plugin %s deaktiviert."
#: ../../mod/admin.php:697 #: ../../mod/admin.php:700
#, php-format #, php-format
msgid "Plugin %s enabled." msgid "Plugin %s enabled."
msgstr "Plugin %s aktiviert." msgstr "Plugin %s aktiviert."
#: ../../mod/admin.php:707 ../../mod/admin.php:905 #: ../../mod/admin.php:710 ../../mod/admin.php:908
msgid "Disable" msgid "Disable"
msgstr "Ausschalten" msgstr "Ausschalten"
#: ../../mod/admin.php:709 ../../mod/admin.php:907 #: ../../mod/admin.php:712 ../../mod/admin.php:910
msgid "Enable" msgid "Enable"
msgstr "Einschalten" msgstr "Einschalten"
#: ../../mod/admin.php:731 ../../mod/admin.php:936 #: ../../mod/admin.php:734 ../../mod/admin.php:939
msgid "Toggle" msgid "Toggle"
msgstr "Umschalten" msgstr "Umschalten"
#: ../../mod/admin.php:739 ../../mod/admin.php:946 #: ../../mod/admin.php:742 ../../mod/admin.php:949
msgid "Author: " msgid "Author: "
msgstr "Autor:" msgstr "Autor:"
#: ../../mod/admin.php:740 ../../mod/admin.php:947 #: ../../mod/admin.php:743 ../../mod/admin.php:950
msgid "Maintainer: " msgid "Maintainer: "
msgstr "Betreuer:" msgstr "Betreuer:"
#: ../../mod/admin.php:869 #: ../../mod/admin.php:872
msgid "No themes found." msgid "No themes found."
msgstr "Keine Themen gefunden." msgstr "Keine Themen gefunden."
#: ../../mod/admin.php:928 #: ../../mod/admin.php:931
msgid "Screenshot" msgid "Screenshot"
msgstr "Bildschirmfoto" msgstr "Bildschirmfoto"
#: ../../mod/admin.php:976 #: ../../mod/admin.php:979
msgid "[Experimental]" msgid "[Experimental]"
msgstr "[Experimentell]" msgstr "[Experimentell]"
#: ../../mod/admin.php:977 #: ../../mod/admin.php:980
msgid "[Unsupported]" msgid "[Unsupported]"
msgstr "[Nicht unterstützt]" msgstr "[Nicht unterstützt]"
#: ../../mod/admin.php:1004 #: ../../mod/admin.php:1007
msgid "Log settings updated." msgid "Log settings updated."
msgstr "Protokolleinstellungen aktualisiert." msgstr "Protokolleinstellungen aktualisiert."
#: ../../mod/admin.php:1060 #: ../../mod/admin.php:1063
msgid "Clear" msgid "Clear"
msgstr "löschen" msgstr "löschen"
#: ../../mod/admin.php:1066 #: ../../mod/admin.php:1069
msgid "Debugging" msgid "Debugging"
msgstr "Protokoll führen" msgstr "Protokoll führen"
#: ../../mod/admin.php:1067 #: ../../mod/admin.php:1070
msgid "Log file" msgid "Log file"
msgstr "Protokolldatei" msgstr "Protokolldatei"
#: ../../mod/admin.php:1067 #: ../../mod/admin.php:1070
msgid "" msgid ""
"Must be writable by web server. Relative to your Friendica top-level " "Must be writable by web server. Relative to your Friendica top-level "
"directory." "directory."
msgstr "Webserver muss Schreibrechte besitzen. Abhängig vom Friendica-Installationsverzeichnis." msgstr "Webserver muss Schreibrechte besitzen. Abhängig vom Friendica-Installationsverzeichnis."
#: ../../mod/admin.php:1068 #: ../../mod/admin.php:1071
msgid "Log level" msgid "Log level"
msgstr "Protokoll-Level" msgstr "Protokoll-Level"
#: ../../mod/admin.php:1118 ../../view/theme/diabook/theme.php:599 #: ../../mod/admin.php:1121
msgid "Close" msgid "Close"
msgstr "Schließen" msgstr "Schließen"
#: ../../mod/admin.php:1124 #: ../../mod/admin.php:1127
msgid "FTP Host" msgid "FTP Host"
msgstr "FTP Host" msgstr "FTP Host"
#: ../../mod/admin.php:1125 #: ../../mod/admin.php:1128
msgid "FTP Path" msgid "FTP Path"
msgstr "FTP Pfad" msgstr "FTP Pfad"
#: ../../mod/admin.php:1126 #: ../../mod/admin.php:1129
msgid "FTP User" msgid "FTP User"
msgstr "FTP Nutzername" msgstr "FTP Nutzername"
#: ../../mod/admin.php:1127 #: ../../mod/admin.php:1130
msgid "FTP Password" msgid "FTP Password"
msgstr "FTP Passwort" msgstr "FTP Passwort"
#: ../../mod/profile.php:21 ../../boot.php:949 #: ../../mod/profile.php:21 ../../boot.php:959
msgid "Requested profile is not available." msgid "Requested profile is not available."
msgstr "Das angefragte Profil ist nicht vorhanden." msgstr "Das angefragte Profil ist nicht vorhanden."
@ -3677,48 +3688,58 @@ msgstr "Account wurde nicht gefunden und OpenID Registrierung auf diesem Server
msgid "Login failed." msgid "Login failed."
msgstr "Annmeldung fehlgeschlagen." msgstr "Annmeldung fehlgeschlagen."
#: ../../mod/follow.php:27 #: ../../mod/follow.php:30
msgid "Connect URL missing." msgid "Connect URL missing."
msgstr "Connect-URL fehlt" msgstr "Connect-URL fehlt"
#: ../../mod/follow.php:47 #: ../../mod/follow.php:56
msgid "" msgid ""
"This site is not configured to allow communications with other networks." "This site is not configured to allow communications with other networks."
msgstr "Diese Seite ist so konfiguriert, dass keine Kommunikation mit anderen Netzwerken erfolgen kann." msgstr "Diese Seite ist so konfiguriert, dass keine Kommunikation mit anderen Netzwerken erfolgen kann."
#: ../../mod/follow.php:48 ../../mod/follow.php:63 #: ../../mod/follow.php:57 ../../mod/follow.php:72
msgid "No compatible communication protocols or feeds were discovered." msgid "No compatible communication protocols or feeds were discovered."
msgstr "Es wurden keine kompatiblen Kommunikationsprotokolle oder Feeds gefunden." msgstr "Es wurden keine kompatiblen Kommunikationsprotokolle oder Feeds gefunden."
#: ../../mod/follow.php:61 #: ../../mod/follow.php:70
msgid "The profile address specified does not provide adequate information." msgid "The profile address specified does not provide adequate information."
msgstr "Die angegebene Profiladresse liefert unzureichende Informationen." msgstr "Die angegebene Profiladresse liefert unzureichende Informationen."
#: ../../mod/follow.php:65 #: ../../mod/follow.php:74
msgid "An author or name was not found." msgid "An author or name was not found."
msgstr "Es wurde kein Autor oder Name gefunden." msgstr "Es wurde kein Autor oder Name gefunden."
#: ../../mod/follow.php:67 #: ../../mod/follow.php:76
msgid "No browser URL could be matched to this address." msgid "No browser URL could be matched to this address."
msgstr "Zu dieser Adresse konnte keine passende Browser URL gefunden werden." msgstr "Zu dieser Adresse konnte keine passende Browser URL gefunden werden."
#: ../../mod/follow.php:74 #: ../../mod/follow.php:78
msgid ""
"Unable to match @-style Identity Address with a known protocol or email "
"contact."
msgstr "Konnte die @-Adresse mit keinem der bekannten Protokolle oder Email-Kontakte abgleichen."
#: ../../mod/follow.php:79
msgid "Use mailto: in front of address to force email check."
msgstr "Verwende mailto: vor der Email Adresse um eine Überprüfung der Email Adresse zu erzwingen."
#: ../../mod/follow.php:85
msgid "" msgid ""
"The profile address specified belongs to a network which has been disabled " "The profile address specified belongs to a network which has been disabled "
"on this site." "on this site."
msgstr "Die Adresse dieses Profils gehört zu einem Netzwerk, mit dem die Kommunikation auf dieser Seite ausgeschaltet wurde." msgstr "Die Adresse dieses Profils gehört zu einem Netzwerk, mit dem die Kommunikation auf dieser Seite ausgeschaltet wurde."
#: ../../mod/follow.php:79 #: ../../mod/follow.php:90
msgid "" msgid ""
"Limited profile. This person will be unable to receive direct/personal " "Limited profile. This person will be unable to receive direct/personal "
"notifications from you." "notifications from you."
msgstr "Eingeschränktes Profil. Diese Person wird keine direkten/privaten Nachrichten von dir erhalten können." msgstr "Eingeschränktes Profil. Diese Person wird keine direkten/privaten Nachrichten von dir erhalten können."
#: ../../mod/follow.php:149 #: ../../mod/follow.php:160
msgid "Unable to retrieve contact information." msgid "Unable to retrieve contact information."
msgstr "Konnte die Kontaktinformationen nicht empfangen." msgstr "Konnte die Kontaktinformationen nicht empfangen."
#: ../../mod/follow.php:195 #: ../../mod/follow.php:206
msgid "following" msgid "following"
msgstr "folgen" msgstr "folgen"
@ -4000,27 +4021,27 @@ msgstr "Alter: "
msgid "Edit/Manage Profiles" msgid "Edit/Manage Profiles"
msgstr "Verwalte/Editiere Profile" msgstr "Verwalte/Editiere Profile"
#: ../../mod/profiles.php:621 ../../boot.php:1058 #: ../../mod/profiles.php:621 ../../boot.php:1068
msgid "Change profile photo" msgid "Change profile photo"
msgstr "Profilbild ändern" msgstr "Profilbild ändern"
#: ../../mod/profiles.php:622 ../../boot.php:1059 #: ../../mod/profiles.php:622 ../../boot.php:1069
msgid "Create New Profile" msgid "Create New Profile"
msgstr "Neues Profil anlegen" msgstr "Neues Profil anlegen"
#: ../../mod/profiles.php:633 ../../boot.php:1069 #: ../../mod/profiles.php:633 ../../boot.php:1079
msgid "Profile Image" msgid "Profile Image"
msgstr "Profilbild" msgstr "Profilbild"
#: ../../mod/profiles.php:635 ../../boot.php:1072 #: ../../mod/profiles.php:635 ../../boot.php:1082
msgid "visible to everybody" msgid "visible to everybody"
msgstr "sichtbar für jeden" msgstr "sichtbar für jeden"
#: ../../mod/profiles.php:636 ../../boot.php:1073 #: ../../mod/profiles.php:636 ../../boot.php:1083
msgid "Edit visibility" msgid "Edit visibility"
msgstr "Sichtbarkeit bearbeiten" msgstr "Sichtbarkeit bearbeiten"
#: ../../mod/filer.php:29 ../../include/conversation.php:922 #: ../../mod/filer.php:29 ../../include/conversation.php:925
msgid "Save to Folder:" msgid "Save to Folder:"
msgstr "In diesen Ordner verschieben:" msgstr "In diesen Ordner verschieben:"
@ -4068,7 +4089,7 @@ msgstr "Hinzufügen"
msgid "No entries." msgid "No entries."
msgstr "Keine Einträge" msgstr "Keine Einträge"
#: ../../mod/suggest.php:38 ../../view/theme/diabook/theme.php:513 #: ../../mod/suggest.php:38 ../../view/theme/diabook/theme.php:621
#: ../../include/contact_widgets.php:34 #: ../../include/contact_widgets.php:34
msgid "Friend Suggestions" msgid "Friend Suggestions"
msgstr "Kontaktvorschläge" msgstr "Kontaktvorschläge"
@ -4083,7 +4104,7 @@ msgstr "Keine Vorschläge. Falls der Server frisch aufgesetzt wurde, versuche es
msgid "Ignore/Hide" msgid "Ignore/Hide"
msgstr "Ignorieren/Verbergen" msgstr "Ignorieren/Verbergen"
#: ../../mod/directory.php:47 ../../view/theme/diabook/theme.php:511 #: ../../mod/directory.php:47 ../../view/theme/diabook/theme.php:619
msgid "Global Directory" msgid "Global Directory"
msgstr "Weltweites Verzeichnis" msgstr "Weltweites Verzeichnis"
@ -4312,13 +4333,13 @@ msgstr "Veröffentliche standardmäßig bei Facebook"
msgid "" msgid ""
"Facebook friend linking has been disabled on this site. The following " "Facebook friend linking has been disabled on this site. The following "
"settings will have no effect." "settings will have no effect."
msgstr "" msgstr "Das verlinken von Facebook-Kontakten wurde auf dieser Seite deaktiviert. Die folgenden Einstellungen haben keinen Effekt."
#: ../../addon/facebook/facebook.php:571 #: ../../addon/facebook/facebook.php:571
msgid "" msgid ""
"Facebook friend linking has been disabled on this site. If you disable it, " "Facebook friend linking has been disabled on this site. If you disable it, "
"you will be unable to re-enable it." "you will be unable to re-enable it."
msgstr "" msgstr "Das verlinken von Facebook-Kontakten wurde auf dieser Seite deaktiviert. Wenn du es ausgeschaltet hast, kannst du es nicht wieder aktivieren."
#: ../../addon/facebook/facebook.php:574 #: ../../addon/facebook/facebook.php:574
msgid "Link all your Facebook friends and conversations on this website" msgid "Link all your Facebook friends and conversations on this website"
@ -4611,7 +4632,7 @@ msgstr "Verwende /expression/ um reguläre Ausdrücke zu verwenden"
msgid "NSFW Settings saved." msgid "NSFW Settings saved."
msgstr "NSFW-Einstellungen gespeichert" msgstr "NSFW-Einstellungen gespeichert"
#: ../../addon/nsfw/nsfw.php:120 #: ../../addon/nsfw/nsfw.php:121
#, php-format #, php-format
msgid "%s - Click to open/close" msgid "%s - Click to open/close"
msgstr "%s Zum Öffnen/Schließen klicken" msgstr "%s Zum Öffnen/Schließen klicken"
@ -4621,8 +4642,8 @@ msgid "Forums"
msgstr "Foren" msgstr "Foren"
#: ../../addon/page/page.php:63 ../../addon/showmore/showmore.php:87 #: ../../addon/page/page.php:63 ../../addon/showmore/showmore.php:87
#: ../../include/contact_widgets.php:187 ../../include/conversation.php:466 #: ../../include/contact_widgets.php:188 ../../include/conversation.php:469
#: ../../boot.php:507 #: ../../boot.php:517
msgid "show more" msgid "show more"
msgstr "mehr anzeigen" msgstr "mehr anzeigen"
@ -4638,7 +4659,7 @@ msgstr "Aktiviere Planeten Plugin"
#: ../../addon/communityhome/communityhome.php:34 #: ../../addon/communityhome/communityhome.php:34
#: ../../addon/communityhome/twillingham/communityhome.php:28 #: ../../addon/communityhome/twillingham/communityhome.php:28
#: ../../addon/communityhome/twillingham/communityhome.php:34 #: ../../addon/communityhome/twillingham/communityhome.php:34
#: ../../include/nav.php:64 ../../boot.php:805 #: ../../include/nav.php:64 ../../boot.php:815
msgid "Login" msgid "Login"
msgstr "Anmeldung" msgstr "Anmeldung"
@ -4666,7 +4687,7 @@ msgid "Latest likes"
msgstr "Neueste Favoriten" msgstr "Neueste Favoriten"
#: ../../addon/communityhome/communityhome.php:155 #: ../../addon/communityhome/communityhome.php:155
#: ../../view/theme/diabook/theme.php:449 ../../include/text.php:1303 #: ../../view/theme/diabook/theme.php:557 ../../include/text.php:1303
#: ../../include/conversation.php:45 ../../include/conversation.php:118 #: ../../include/conversation.php:45 ../../include/conversation.php:118
msgid "event" msgid "event"
msgstr "Veranstaltung" msgstr "Veranstaltung"
@ -4819,7 +4840,7 @@ msgid "Post to Drupal by default"
msgstr "Veröffentliche öffentliche Beiträge standardmäßig bei Drupal" msgstr "Veröffentliche öffentliche Beiträge standardmäßig bei Drupal"
#: ../../addon/drpost/drpost.php:184 ../../addon/wppost/wppost.php:190 #: ../../addon/drpost/drpost.php:184 ../../addon/wppost/wppost.php:190
#: ../../addon/blogger/blogger.php:172 ../../addon/posterous/posterous.php:177 #: ../../addon/blogger/blogger.php:172 ../../addon/posterous/posterous.php:192
msgid "Post from Friendica" msgid "Post from Friendica"
msgstr "Beitrag via Friendica" msgstr "Beitrag via Friendica"
@ -5533,32 +5554,40 @@ msgstr "Blogger-API-URL"
msgid "Post to Blogger by default" msgid "Post to Blogger by default"
msgstr "Standardmäßig auf Blogger posten" msgstr "Standardmäßig auf Blogger posten"
#: ../../addon/posterous/posterous.php:36 #: ../../addon/posterous/posterous.php:37
msgid "Post to Posterous" msgid "Post to Posterous"
msgstr "Nach Posterous senden" msgstr "Nach Posterous senden"
#: ../../addon/posterous/posterous.php:67 #: ../../addon/posterous/posterous.php:70
msgid "Posterous Post Settings" msgid "Posterous Post Settings"
msgstr "Posterous Beitrags-Einstellungen" msgstr "Posterous Beitrags-Einstellungen"
#: ../../addon/posterous/posterous.php:69 #: ../../addon/posterous/posterous.php:72
msgid "Enable Posterous Post Plugin" msgid "Enable Posterous Post Plugin"
msgstr "Posterous-Plugin aktivieren" msgstr "Posterous-Plugin aktivieren"
#: ../../addon/posterous/posterous.php:74 #: ../../addon/posterous/posterous.php:77
msgid "Posterous login" msgid "Posterous login"
msgstr "Posterous-Anmeldename" msgstr "Posterous-Anmeldename"
#: ../../addon/posterous/posterous.php:79 #: ../../addon/posterous/posterous.php:82
msgid "Posterous password" msgid "Posterous password"
msgstr "Posterous-Passwort" msgstr "Posterous-Passwort"
#: ../../addon/posterous/posterous.php:84 #: ../../addon/posterous/posterous.php:87
msgid "Posterous site ID"
msgstr "Posterous site ID"
#: ../../addon/posterous/posterous.php:92
msgid "Posterous API token"
msgstr "Posterous API token"
#: ../../addon/posterous/posterous.php:97
msgid "Post to Posterous by default" msgid "Post to Posterous by default"
msgstr "Veröffentliche öffentliche Beiträge standardmäßig bei Posterous" msgstr "Veröffentliche öffentliche Beiträge standardmäßig bei Posterous"
#: ../../view/theme/cleanzero/config.php:82 #: ../../view/theme/cleanzero/config.php:82
#: ../../view/theme/diabook/config.php:97 #: ../../view/theme/diabook/config.php:192
#: ../../view/theme/quattro/config.php:54 ../../view/theme/dispy/config.php:72 #: ../../view/theme/quattro/config.php:54 ../../view/theme/dispy/config.php:72
msgid "Theme settings" msgid "Theme settings"
msgstr "Themen Einstellungen" msgstr "Themen Einstellungen"
@ -5568,7 +5597,8 @@ msgid "Set resize level for images in posts and comments (width and height)"
msgstr "Wähle das Vergrößerungsmaß für Bilder in Beiträgen und Kommentaren (Höhe und Breite)" msgstr "Wähle das Vergrößerungsmaß für Bilder in Beiträgen und Kommentaren (Höhe und Breite)"
#: ../../view/theme/cleanzero/config.php:84 #: ../../view/theme/cleanzero/config.php:84
#: ../../view/theme/diabook/config.php:98 ../../view/theme/dispy/config.php:73 #: ../../view/theme/diabook/config.php:193
#: ../../view/theme/dispy/config.php:73
msgid "Set font-size for posts and comments" msgid "Set font-size for posts and comments"
msgstr "Schriftgröße für Beiträge und Kommentare festlegen" msgstr "Schriftgröße für Beiträge und Kommentare festlegen"
@ -5581,105 +5611,177 @@ msgstr "Theme Breite festlegen"
msgid "Color scheme" msgid "Color scheme"
msgstr "Farbschema" msgstr "Farbschema"
#: ../../view/theme/diabook/theme.php:65 ../../include/nav.php:49 #: ../../view/theme/diabook/theme.php:122 ../../include/nav.php:49
#: ../../include/nav.php:115 #: ../../include/nav.php:115
msgid "Your posts and conversations" msgid "Your posts and conversations"
msgstr "Deine Beiträge und Unterhaltungen" msgstr "Deine Beiträge und Unterhaltungen"
#: ../../view/theme/diabook/theme.php:66 ../../include/nav.php:50 #: ../../view/theme/diabook/theme.php:123 ../../include/nav.php:50
msgid "Your profile page" msgid "Your profile page"
msgstr "Deine Profilseite" msgstr "Deine Profilseite"
#: ../../view/theme/diabook/theme.php:67 #: ../../view/theme/diabook/theme.php:124
msgid "Your contacts" msgid "Your contacts"
msgstr "Deine Kontakte" msgstr "Deine Kontakte"
#: ../../view/theme/diabook/theme.php:68 ../../include/nav.php:51 #: ../../view/theme/diabook/theme.php:125 ../../include/nav.php:51
msgid "Your photos" msgid "Your photos"
msgstr "Deine Fotos" msgstr "Deine Fotos"
#: ../../view/theme/diabook/theme.php:69 ../../include/nav.php:52 #: ../../view/theme/diabook/theme.php:126 ../../include/nav.php:52
msgid "Your events" msgid "Your events"
msgstr "Deine Ereignisse" msgstr "Deine Ereignisse"
#: ../../view/theme/diabook/theme.php:70 ../../include/nav.php:53 #: ../../view/theme/diabook/theme.php:127 ../../include/nav.php:53
msgid "Personal notes" msgid "Personal notes"
msgstr "Persönliche Notizen" msgstr "Persönliche Notizen"
#: ../../view/theme/diabook/theme.php:70 ../../include/nav.php:53 #: ../../view/theme/diabook/theme.php:127 ../../include/nav.php:53
msgid "Your personal photos" msgid "Your personal photos"
msgstr "Deine privaten Fotos" msgstr "Deine privaten Fotos"
#: ../../view/theme/diabook/theme.php:72 #: ../../view/theme/diabook/theme.php:129
#: ../../view/theme/diabook/theme.php:530 #: ../../view/theme/diabook/theme.php:638
#: ../../view/theme/diabook/theme.php:742
#: ../../view/theme/diabook/config.php:201
msgid "Community Pages" msgid "Community Pages"
msgstr "Foren" msgstr "Foren"
#: ../../view/theme/diabook/theme.php:377 #: ../../view/theme/diabook/theme.php:485
#: ../../view/theme/diabook/theme.php:744
#: ../../view/theme/diabook/config.php:203
msgid "Community Profiles" msgid "Community Profiles"
msgstr "Community-Profile" msgstr "Community-Profile"
#: ../../view/theme/diabook/theme.php:398 #: ../../view/theme/diabook/theme.php:506
#: ../../view/theme/diabook/theme.php:749
#: ../../view/theme/diabook/config.php:208
msgid "Last users" msgid "Last users"
msgstr "Letzte Nutzer" msgstr "Letzte Nutzer"
#: ../../view/theme/diabook/theme.php:427 #: ../../view/theme/diabook/theme.php:535
#: ../../view/theme/diabook/theme.php:751
#: ../../view/theme/diabook/config.php:210
msgid "Last likes" msgid "Last likes"
msgstr "Zuletzt gemocht" msgstr "Zuletzt gemocht"
#: ../../view/theme/diabook/theme.php:472 #: ../../view/theme/diabook/theme.php:580
#: ../../view/theme/diabook/theme.php:750
#: ../../view/theme/diabook/config.php:209
msgid "Last photos" msgid "Last photos"
msgstr "Letzte Fotos" msgstr "Letzte Fotos"
#: ../../view/theme/diabook/theme.php:509 #: ../../view/theme/diabook/theme.php:617
#: ../../view/theme/diabook/theme.php:747
#: ../../view/theme/diabook/config.php:206
msgid "Find Friends" msgid "Find Friends"
msgstr "Freunde finden" msgstr "Freunde finden"
#: ../../view/theme/diabook/theme.php:510 #: ../../view/theme/diabook/theme.php:618
msgid "Local Directory" msgid "Local Directory"
msgstr "Lokales Verzeichnis" msgstr "Lokales Verzeichnis"
#: ../../view/theme/diabook/theme.php:512 ../../include/contact_widgets.php:35 #: ../../view/theme/diabook/theme.php:620 ../../include/contact_widgets.php:35
msgid "Similar Interests" msgid "Similar Interests"
msgstr "Ähnliche Interessen" msgstr "Ähnliche Interessen"
#: ../../view/theme/diabook/theme.php:514 ../../include/contact_widgets.php:37 #: ../../view/theme/diabook/theme.php:622 ../../include/contact_widgets.php:37
msgid "Invite Friends" msgid "Invite Friends"
msgstr "Freunde einladen" msgstr "Freunde einladen"
#: ../../view/theme/diabook/theme.php:565 #: ../../view/theme/diabook/theme.php:673
msgid "Earth View" #: ../../view/theme/diabook/theme.php:743
msgstr "Earth View" #: ../../view/theme/diabook/config.php:202
msgid "Earth Layers"
msgstr "Earth Layers"
#: ../../view/theme/diabook/theme.php:573 #: ../../view/theme/diabook/theme.php:678
msgid "Set zoomfactor for Earth Layers"
msgstr "Zoomfaktor der Earth Layer"
#: ../../view/theme/diabook/theme.php:679
#: ../../view/theme/diabook/config.php:199
msgid "Set longitude (X) for Earth Layers"
msgstr "Longitude (X) der Earth Layer"
#: ../../view/theme/diabook/theme.php:680
#: ../../view/theme/diabook/config.php:200
msgid "Set latitude (Y) for Earth Layers"
msgstr "Latitude (Y) der Earth Layer"
#: ../../view/theme/diabook/theme.php:693
#: ../../view/theme/diabook/theme.php:745
#: ../../view/theme/diabook/config.php:204
msgid "Help or @NewHere ?" msgid "Help or @NewHere ?"
msgstr "Hilfe oder @NewHere" msgstr "Hilfe oder @NewHere"
#: ../../view/theme/diabook/theme.php:580 #: ../../view/theme/diabook/theme.php:700
#: ../../view/theme/diabook/theme.php:746
#: ../../view/theme/diabook/config.php:205
msgid "Connect Services" msgid "Connect Services"
msgstr "Verbinde Dienste" msgstr "Verbinde Dienste"
#: ../../view/theme/diabook/theme.php:587 #: ../../view/theme/diabook/theme.php:707
#: ../../view/theme/diabook/theme.php:748
msgid "Last Tweets" msgid "Last Tweets"
msgstr "Neueste Tweets" msgstr "Neueste Tweets"
#: ../../view/theme/diabook/theme.php:591 #: ../../view/theme/diabook/theme.php:710
#: ../../view/theme/diabook/config.php:102 #: ../../view/theme/diabook/config.php:197
msgid "Set twitter search term" msgid "Set twitter search term"
msgstr "" msgstr "Twitter Suchbegriff"
#: ../../view/theme/diabook/config.php:99 ../../view/theme/dispy/config.php:74 #: ../../view/theme/diabook/theme.php:730
#: ../../view/theme/diabook/theme.php:731
#: ../../view/theme/diabook/theme.php:732
#: ../../view/theme/diabook/theme.php:733
#: ../../view/theme/diabook/theme.php:734
#: ../../view/theme/diabook/theme.php:735
#: ../../view/theme/diabook/theme.php:736
#: ../../view/theme/diabook/theme.php:737
#: ../../view/theme/diabook/theme.php:738
#: ../../view/theme/diabook/theme.php:739 ../../include/acl_selectors.php:288
msgid "don't show"
msgstr "nicht zeigen"
#: ../../view/theme/diabook/theme.php:730
#: ../../view/theme/diabook/theme.php:731
#: ../../view/theme/diabook/theme.php:732
#: ../../view/theme/diabook/theme.php:733
#: ../../view/theme/diabook/theme.php:734
#: ../../view/theme/diabook/theme.php:735
#: ../../view/theme/diabook/theme.php:736
#: ../../view/theme/diabook/theme.php:737
#: ../../view/theme/diabook/theme.php:738
#: ../../view/theme/diabook/theme.php:739 ../../include/acl_selectors.php:287
msgid "show"
msgstr "zeigen"
#: ../../view/theme/diabook/theme.php:740
msgid "Show/hide boxes at right-hand column:"
msgstr "Rahmen auf der rechten Seite anzeigen/verbergen"
#: ../../view/theme/diabook/config.php:194
#: ../../view/theme/dispy/config.php:74
msgid "Set line-height for posts and comments" msgid "Set line-height for posts and comments"
msgstr "Liniengröße für Beiträge und Kommantare festlegen" msgstr "Liniengröße für Beiträge und Kommantare festlegen"
#: ../../view/theme/diabook/config.php:100 #: ../../view/theme/diabook/config.php:195
msgid "Set resolution for middle column" msgid "Set resolution for middle column"
msgstr "Auflösung für die Mittelspalte setzen" msgstr "Auflösung für die Mittelspalte setzen"
#: ../../view/theme/diabook/config.php:101 #: ../../view/theme/diabook/config.php:196
msgid "Set color scheme" msgid "Set color scheme"
msgstr "Wähle Farbschema" msgstr "Wähle Farbschema"
#: ../../view/theme/diabook/config.php:198
msgid "Set zoomfactor for Earth Layer"
msgstr "Zoomfaktor der Earth Layer"
#: ../../view/theme/diabook/config.php:207
msgid "Last tweets"
msgstr "Neueste Tweets"
#: ../../view/theme/quattro/config.php:55 #: ../../view/theme/quattro/config.php:55
msgid "Alignment" msgid "Alignment"
msgstr "Ausrichtung" msgstr "Ausrichtung"
@ -5696,7 +5798,7 @@ msgstr "Mitte"
msgid "Set colour scheme" msgid "Set colour scheme"
msgstr "Farbschema wählen" msgstr "Farbschema wählen"
#: ../../include/profile_advanced.php:17 ../../boot.php:1094 #: ../../include/profile_advanced.php:17 ../../boot.php:1104
msgid "Gender:" msgid "Gender:"
msgstr "Geschlecht:" msgstr "Geschlecht:"
@ -5709,7 +5811,7 @@ msgid "j F"
msgstr "j F" msgstr "j F"
#: ../../include/profile_advanced.php:30 ../../include/datetime.php:448 #: ../../include/profile_advanced.php:30 ../../include/datetime.php:448
#: ../../include/items.php:1403 #: ../../include/items.php:1413
msgid "Birthday:" msgid "Birthday:"
msgstr "Geburtstag:" msgstr "Geburtstag:"
@ -5717,11 +5819,11 @@ msgstr "Geburtstag:"
msgid "Age:" msgid "Age:"
msgstr "Alter:" msgstr "Alter:"
#: ../../include/profile_advanced.php:37 ../../boot.php:1097 #: ../../include/profile_advanced.php:37 ../../boot.php:1107
msgid "Status:" msgid "Status:"
msgstr "Status:" msgstr "Status:"
#: ../../include/profile_advanced.php:45 ../../boot.php:1099 #: ../../include/profile_advanced.php:45 ../../boot.php:1109
msgid "Homepage:" msgid "Homepage:"
msgstr "Homepage:" msgstr "Homepage:"
@ -6085,11 +6187,11 @@ msgstr "Beginnt:"
msgid "Finishes:" msgid "Finishes:"
msgstr "Endet:" msgstr "Endet:"
#: ../../include/delivery.php:445 ../../include/notifier.php:652 #: ../../include/delivery.php:452 ../../include/notifier.php:652
msgid "(no subject)" msgid "(no subject)"
msgstr "(kein Betreff)" msgstr "(kein Betreff)"
#: ../../include/delivery.php:452 ../../include/enotify.php:23 #: ../../include/delivery.php:459 ../../include/enotify.php:23
#: ../../include/notifier.php:659 #: ../../include/notifier.php:659
msgid "noreply" msgid "noreply"
msgstr "noreply" msgstr "noreply"
@ -6305,7 +6407,7 @@ msgstr "Neue Gruppe erstellen"
msgid "Contacts not in any group" msgid "Contacts not in any group"
msgstr "Kontakte in keiner Gruppe" msgstr "Kontakte in keiner Gruppe"
#: ../../include/nav.php:46 ../../boot.php:804 #: ../../include/nav.php:46 ../../boot.php:814
msgid "Logout" msgid "Logout"
msgstr "Abmelden" msgstr "Abmelden"
@ -6313,7 +6415,7 @@ msgstr "Abmelden"
msgid "End this session" msgid "End this session"
msgstr "Diese Sitzung beenden" msgstr "Diese Sitzung beenden"
#: ../../include/nav.php:49 ../../boot.php:1472 #: ../../include/nav.php:49 ../../boot.php:1482
msgid "Status" msgid "Status"
msgstr "Status" msgstr "Status"
@ -6393,11 +6495,11 @@ msgstr "Verwalten"
msgid "Manage other pages" msgid "Manage other pages"
msgstr "Andere Seiten verwalten" msgstr "Andere Seiten verwalten"
#: ../../include/nav.php:138 ../../boot.php:1052 #: ../../include/nav.php:138 ../../boot.php:1062
msgid "Profiles" msgid "Profiles"
msgstr "Profile" msgstr "Profile"
#: ../../include/nav.php:138 ../../boot.php:1052 #: ../../include/nav.php:138 ../../boot.php:1062
msgid "Manage/edit profiles" msgid "Manage/edit profiles"
msgstr "Profile verwalten/editieren" msgstr "Profile verwalten/editieren"
@ -6563,7 +6665,7 @@ msgstr "Sekunden"
msgid "%1$d %2$s ago" msgid "%1$d %2$s ago"
msgstr "%1$d %2$s her" msgstr "%1$d %2$s her"
#: ../../include/onepoll.php:402 #: ../../include/onepoll.php:406
msgid "From: " msgid "From: "
msgstr "Von: " msgstr "Von: "
@ -6588,14 +6690,6 @@ msgstr "[kein Betreff]"
msgid "Visible to everybody" msgid "Visible to everybody"
msgstr "Für jeden sichtbar" msgstr "Für jeden sichtbar"
#: ../../include/acl_selectors.php:287
msgid "show"
msgstr "zeigen"
#: ../../include/acl_selectors.php:288
msgid "don't show"
msgstr "nicht zeigen"
#: ../../include/enotify.php:14 #: ../../include/enotify.php:14
msgid "Friendica Notification" msgid "Friendica Notification"
msgstr "Friendica-Benachrichtigung" msgstr "Friendica-Benachrichtigung"
@ -6784,11 +6878,11 @@ msgstr "Foto:"
msgid "Please visit %s to approve or reject the suggestion." msgid "Please visit %s to approve or reject the suggestion."
msgstr "Bitte besuche %s, um den Vorschlag zu akzeptieren oder abzulehnen." msgstr "Bitte besuche %s, um den Vorschlag zu akzeptieren oder abzulehnen."
#: ../../include/items.php:2714 #: ../../include/items.php:2724
msgid "A new person is sharing with you at " msgid "A new person is sharing with you at "
msgstr "Eine neue Person teilt mit dir auf " msgstr "Eine neue Person teilt mit dir auf "
#: ../../include/items.php:2714 #: ../../include/items.php:2724
msgid "You have a new follower at " msgid "You have a new follower at "
msgstr "Du hast einen neuen Kontakt auf " msgstr "Du hast einen neuen Kontakt auf "
@ -6823,30 +6917,30 @@ msgstr "Das Sicherheits-Merkmal war nicht korrekt. Das passiert meistens wenn da
msgid "stopped following" msgid "stopped following"
msgstr "wird nicht mehr gefolgt" msgstr "wird nicht mehr gefolgt"
#: ../../include/Contact.php:203 ../../include/conversation.php:817 #: ../../include/Contact.php:203 ../../include/conversation.php:820
msgid "View Status" msgid "View Status"
msgstr "Pinnwand anschauen" msgstr "Pinnwand anschauen"
#: ../../include/Contact.php:204 ../../include/conversation.php:818 #: ../../include/Contact.php:204 ../../include/conversation.php:821
msgid "View Profile" msgid "View Profile"
msgstr "Profil anschauen" msgstr "Profil anschauen"
#: ../../include/Contact.php:205 ../../include/conversation.php:819 #: ../../include/Contact.php:205 ../../include/conversation.php:822
msgid "View Photos" msgid "View Photos"
msgstr "Bilder anschauen" msgstr "Bilder anschauen"
#: ../../include/Contact.php:206 ../../include/Contact.php:219 #: ../../include/Contact.php:206 ../../include/Contact.php:219
#: ../../include/conversation.php:820 #: ../../include/conversation.php:823
msgid "Network Posts" msgid "Network Posts"
msgstr "Netzwerk-Beiträge" msgstr "Netzwerk-Beiträge"
#: ../../include/Contact.php:207 ../../include/Contact.php:219 #: ../../include/Contact.php:207 ../../include/Contact.php:219
#: ../../include/conversation.php:821 #: ../../include/conversation.php:824
msgid "Edit Contact" msgid "Edit Contact"
msgstr "Kontakt bearbeiten" msgstr "Kontakt bearbeiten"
#: ../../include/Contact.php:208 ../../include/Contact.php:219 #: ../../include/Contact.php:208 ../../include/Contact.php:219
#: ../../include/conversation.php:822 #: ../../include/conversation.php:825
msgid "Send PM" msgid "Send PM"
msgstr "Private Nachricht senden" msgstr "Private Nachricht senden"
@ -6859,309 +6953,309 @@ msgstr "Nachricht/Beitrag"
msgid "%1$s marked %2$s's %3$s as favorite" msgid "%1$s marked %2$s's %3$s as favorite"
msgstr "%1$s hat %2$s\\s %3$s als Favorit markiert" msgstr "%1$s hat %2$s\\s %3$s als Favorit markiert"
#: ../../include/conversation.php:317 ../../include/conversation.php:583 #: ../../include/conversation.php:320 ../../include/conversation.php:586
msgid "Select" msgid "Select"
msgstr "Auswählen" msgstr "Auswählen"
#: ../../include/conversation.php:334 ../../include/conversation.php:676 #: ../../include/conversation.php:337 ../../include/conversation.php:679
#: ../../include/conversation.php:677 #: ../../include/conversation.php:680
#, php-format #, php-format
msgid "View %s's profile @ %s" msgid "View %s's profile @ %s"
msgstr "Das Profil von %s auf %s betrachten." msgstr "Das Profil von %s auf %s betrachten."
#: ../../include/conversation.php:344 ../../include/conversation.php:688 #: ../../include/conversation.php:347 ../../include/conversation.php:691
#, php-format #, php-format
msgid "%s from %s" msgid "%s from %s"
msgstr "%s von %s" msgstr "%s von %s"
#: ../../include/conversation.php:359 #: ../../include/conversation.php:362
msgid "View in context" msgid "View in context"
msgstr "Im Zusammenhang betrachten" msgstr "Im Zusammenhang betrachten"
#: ../../include/conversation.php:465 #: ../../include/conversation.php:468
#, php-format #, php-format
msgid "%d comment" msgid "%d comment"
msgid_plural "%d comments" msgid_plural "%d comments"
msgstr[0] "%d Kommentar" msgstr[0] "%d Kommentar"
msgstr[1] "%d Kommentare" msgstr[1] "%d Kommentare"
#: ../../include/conversation.php:529 #: ../../include/conversation.php:532
msgid "like" msgid "like"
msgstr "mag ich" msgstr "mag ich"
#: ../../include/conversation.php:530 #: ../../include/conversation.php:533
msgid "dislike" msgid "dislike"
msgstr "mag ich nicht" msgstr "mag ich nicht"
#: ../../include/conversation.php:532 #: ../../include/conversation.php:535
msgid "Share this" msgid "Share this"
msgstr "Teile dieses" msgstr "Teile dieses"
#: ../../include/conversation.php:532 #: ../../include/conversation.php:535
msgid "share" msgid "share"
msgstr "Teilen" msgstr "Teilen"
#: ../../include/conversation.php:556 #: ../../include/conversation.php:559
msgid "Bold" msgid "Bold"
msgstr "Fett" msgstr "Fett"
#: ../../include/conversation.php:557 #: ../../include/conversation.php:560
msgid "Italic" msgid "Italic"
msgstr "Kursiv" msgstr "Kursiv"
#: ../../include/conversation.php:558 #: ../../include/conversation.php:561
msgid "Underline" msgid "Underline"
msgstr "Unterstrichen" msgstr "Unterstrichen"
#: ../../include/conversation.php:559 #: ../../include/conversation.php:562
msgid "Quote" msgid "Quote"
msgstr "Zitat" msgstr "Zitat"
#: ../../include/conversation.php:560 #: ../../include/conversation.php:563
msgid "Code" msgid "Code"
msgstr "Code" msgstr "Code"
#: ../../include/conversation.php:561 #: ../../include/conversation.php:564
msgid "Image" msgid "Image"
msgstr "Bild" msgstr "Bild"
#: ../../include/conversation.php:562 #: ../../include/conversation.php:565
msgid "Link" msgid "Link"
msgstr "Verweis" msgstr "Verweis"
#: ../../include/conversation.php:563 #: ../../include/conversation.php:566
msgid "Video" msgid "Video"
msgstr "Video" msgstr "Video"
#: ../../include/conversation.php:596 #: ../../include/conversation.php:599
msgid "add star" msgid "add star"
msgstr "markieren" msgstr "markieren"
#: ../../include/conversation.php:597 #: ../../include/conversation.php:600
msgid "remove star" msgid "remove star"
msgstr "Markierung entfernen" msgstr "Markierung entfernen"
#: ../../include/conversation.php:598 #: ../../include/conversation.php:601
msgid "toggle star status" msgid "toggle star status"
msgstr "Markierung umschalten" msgstr "Markierung umschalten"
#: ../../include/conversation.php:601 #: ../../include/conversation.php:604
msgid "starred" msgid "starred"
msgstr "markiert" msgstr "markiert"
#: ../../include/conversation.php:602 #: ../../include/conversation.php:605
msgid "add tag" msgid "add tag"
msgstr "Tag hinzufügen" msgstr "Tag hinzufügen"
#: ../../include/conversation.php:606 #: ../../include/conversation.php:609
msgid "save to folder" msgid "save to folder"
msgstr "In Ordner speichern" msgstr "In Ordner speichern"
#: ../../include/conversation.php:678 #: ../../include/conversation.php:681
msgid "to" msgid "to"
msgstr "zu" msgstr "zu"
#: ../../include/conversation.php:679 #: ../../include/conversation.php:682
msgid "Wall-to-Wall" msgid "Wall-to-Wall"
msgstr "Wall-to-Wall" msgstr "Wall-to-Wall"
#: ../../include/conversation.php:680 #: ../../include/conversation.php:683
msgid "via Wall-To-Wall:" msgid "via Wall-To-Wall:"
msgstr "via Wall-To-Wall:" msgstr "via Wall-To-Wall:"
#: ../../include/conversation.php:725 #: ../../include/conversation.php:728
msgid "Delete Selected Items" msgid "Delete Selected Items"
msgstr "Lösche die markierten Beiträge" msgstr "Lösche die markierten Beiträge"
#: ../../include/conversation.php:876 #: ../../include/conversation.php:879
#, php-format #, php-format
msgid "%s likes this." msgid "%s likes this."
msgstr "%s mag das." msgstr "%s mag das."
#: ../../include/conversation.php:876 #: ../../include/conversation.php:879
#, php-format #, php-format
msgid "%s doesn't like this." msgid "%s doesn't like this."
msgstr "%s mag das nicht." msgstr "%s mag das nicht."
#: ../../include/conversation.php:880 #: ../../include/conversation.php:883
#, php-format #, php-format
msgid "<span %1$s>%2$d people</span> like this." msgid "<span %1$s>%2$d people</span> like this."
msgstr "<span %1$s>%2$d Leute</span> mögen das." msgstr "<span %1$s>%2$d Leute</span> mögen das."
#: ../../include/conversation.php:882 #: ../../include/conversation.php:885
#, php-format #, php-format
msgid "<span %1$s>%2$d people</span> don't like this." msgid "<span %1$s>%2$d people</span> don't like this."
msgstr "<span %1$s>%2$d Leute</span> mögen das nicht." msgstr "<span %1$s>%2$d Leute</span> mögen das nicht."
#: ../../include/conversation.php:888 #: ../../include/conversation.php:891
msgid "and" msgid "and"
msgstr "und" msgstr "und"
#: ../../include/conversation.php:891 #: ../../include/conversation.php:894
#, php-format #, php-format
msgid ", and %d other people" msgid ", and %d other people"
msgstr " und %d andere" msgstr " und %d andere"
#: ../../include/conversation.php:892 #: ../../include/conversation.php:895
#, php-format #, php-format
msgid "%s like this." msgid "%s like this."
msgstr "%s mögen das." msgstr "%s mögen das."
#: ../../include/conversation.php:892 #: ../../include/conversation.php:895
#, php-format #, php-format
msgid "%s don't like this." msgid "%s don't like this."
msgstr "%s mögen das nicht." msgstr "%s mögen das nicht."
#: ../../include/conversation.php:917 #: ../../include/conversation.php:920
msgid "Visible to <strong>everybody</strong>" msgid "Visible to <strong>everybody</strong>"
msgstr "Für <strong>jedermann</strong> sichtbar" msgstr "Für <strong>jedermann</strong> sichtbar"
#: ../../include/conversation.php:919 #: ../../include/conversation.php:922
msgid "Please enter a video link/URL:" msgid "Please enter a video link/URL:"
msgstr "Bitte Link/URL zum Video einfügen:" msgstr "Bitte Link/URL zum Video einfügen:"
#: ../../include/conversation.php:920 #: ../../include/conversation.php:923
msgid "Please enter an audio link/URL:" msgid "Please enter an audio link/URL:"
msgstr "Bitte Link/URL zum Audio einfügen:" msgstr "Bitte Link/URL zum Audio einfügen:"
#: ../../include/conversation.php:921 #: ../../include/conversation.php:924
msgid "Tag term:" msgid "Tag term:"
msgstr "Tag:" msgstr "Tag:"
#: ../../include/conversation.php:923 #: ../../include/conversation.php:926
msgid "Where are you right now?" msgid "Where are you right now?"
msgstr "Wo hältst du dich jetzt gerade auf?" msgstr "Wo hältst du dich jetzt gerade auf?"
#: ../../include/conversation.php:966 #: ../../include/conversation.php:969
msgid "upload photo" msgid "upload photo"
msgstr "Bild hochladen" msgstr "Bild hochladen"
#: ../../include/conversation.php:968 #: ../../include/conversation.php:971
msgid "attach file" msgid "attach file"
msgstr "Datei anhängen" msgstr "Datei anhängen"
#: ../../include/conversation.php:970 #: ../../include/conversation.php:973
msgid "web link" msgid "web link"
msgstr "Weblink" msgstr "Weblink"
#: ../../include/conversation.php:971 #: ../../include/conversation.php:974
msgid "Insert video link" msgid "Insert video link"
msgstr "Video-Adresse einfügen" msgstr "Video-Adresse einfügen"
#: ../../include/conversation.php:972 #: ../../include/conversation.php:975
msgid "video link" msgid "video link"
msgstr "Video-Link" msgstr "Video-Link"
#: ../../include/conversation.php:973 #: ../../include/conversation.php:976
msgid "Insert audio link" msgid "Insert audio link"
msgstr "Audio-Adresse einfügen" msgstr "Audio-Adresse einfügen"
#: ../../include/conversation.php:974 #: ../../include/conversation.php:977
msgid "audio link" msgid "audio link"
msgstr "Audio-Link" msgstr "Audio-Link"
#: ../../include/conversation.php:976 #: ../../include/conversation.php:979
msgid "set location" msgid "set location"
msgstr "Ort setzen" msgstr "Ort setzen"
#: ../../include/conversation.php:978 #: ../../include/conversation.php:981
msgid "clear location" msgid "clear location"
msgstr "Ort löschen" msgstr "Ort löschen"
#: ../../include/conversation.php:985 #: ../../include/conversation.php:988
msgid "permissions" msgid "permissions"
msgstr "Zugriffsrechte" msgstr "Zugriffsrechte"
#: ../../boot.php:505 #: ../../boot.php:515
msgid "Delete this item?" msgid "Delete this item?"
msgstr "Diesen Beitrag löschen?" msgstr "Diesen Beitrag löschen?"
#: ../../boot.php:508 #: ../../boot.php:518
msgid "show fewer" msgid "show fewer"
msgstr "weniger anzeigen" msgstr "weniger anzeigen"
#: ../../boot.php:681 #: ../../boot.php:691
#, php-format #, php-format
msgid "Update %s failed. See error logs." msgid "Update %s failed. See error logs."
msgstr "Update %s fehlgeschlagen. Bitte Fehlerprotokoll überprüfen." msgstr "Update %s fehlgeschlagen. Bitte Fehlerprotokoll überprüfen."
#: ../../boot.php:683 #: ../../boot.php:693
#, php-format #, php-format
msgid "Update Error at %s" msgid "Update Error at %s"
msgstr "Updatefehler bei %s" msgstr "Updatefehler bei %s"
#: ../../boot.php:783 #: ../../boot.php:793
msgid "Create a New Account" msgid "Create a New Account"
msgstr "Neuen Account erstellen" msgstr "Neuen Account erstellen"
#: ../../boot.php:807 #: ../../boot.php:817
msgid "Nickname or Email address: " msgid "Nickname or Email address: "
msgstr "Spitzname oder Email-Adresse: " msgstr "Spitzname oder Email-Adresse: "
#: ../../boot.php:808 #: ../../boot.php:818
msgid "Password: " msgid "Password: "
msgstr "Passwort: " msgstr "Passwort: "
#: ../../boot.php:811 #: ../../boot.php:821
msgid "Or login using OpenID: " msgid "Or login using OpenID: "
msgstr "Oder melde dich mit deiner OpenID an: " msgstr "Oder melde dich mit deiner OpenID an: "
#: ../../boot.php:817 #: ../../boot.php:827
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "Passwort vergessen?" msgstr "Passwort vergessen?"
#: ../../boot.php:984 #: ../../boot.php:994
msgid "Edit profile" msgid "Edit profile"
msgstr "Profil bearbeiten" msgstr "Profil bearbeiten"
#: ../../boot.php:1044 #: ../../boot.php:1054
msgid "Message" msgid "Message"
msgstr "Nachricht" msgstr "Nachricht"
#: ../../boot.php:1160 ../../boot.php:1236 #: ../../boot.php:1170 ../../boot.php:1246
msgid "g A l F d" msgid "g A l F d"
msgstr "l, d. F G \\U\\h\\r" msgstr "l, d. F G \\U\\h\\r"
#: ../../boot.php:1161 ../../boot.php:1237 #: ../../boot.php:1171 ../../boot.php:1247
msgid "F d" msgid "F d"
msgstr "d. F" msgstr "d. F"
#: ../../boot.php:1206 ../../boot.php:1277 #: ../../boot.php:1216 ../../boot.php:1287
msgid "[today]" msgid "[today]"
msgstr "[heute]" msgstr "[heute]"
#: ../../boot.php:1218 #: ../../boot.php:1228
msgid "Birthday Reminders" msgid "Birthday Reminders"
msgstr "Geburtstagserinnerungen" msgstr "Geburtstagserinnerungen"
#: ../../boot.php:1219 #: ../../boot.php:1229
msgid "Birthdays this week:" msgid "Birthdays this week:"
msgstr "Geburtstage diese Woche:" msgstr "Geburtstage diese Woche:"
#: ../../boot.php:1270 #: ../../boot.php:1280
msgid "[No description]" msgid "[No description]"
msgstr "[keine Beschreibung]" msgstr "[keine Beschreibung]"
#: ../../boot.php:1288 #: ../../boot.php:1298
msgid "Event Reminders" msgid "Event Reminders"
msgstr "Veranstaltungserinnerungen" msgstr "Veranstaltungserinnerungen"
#: ../../boot.php:1289 #: ../../boot.php:1299
msgid "Events this week:" msgid "Events this week:"
msgstr "Veranstaltungen diese Woche" msgstr "Veranstaltungen diese Woche"
#: ../../boot.php:1475 #: ../../boot.php:1485
msgid "Status Messages and Posts" msgid "Status Messages and Posts"
msgstr "Statusnachrichten und Beiträge" msgstr "Statusnachrichten und Beiträge"
#: ../../boot.php:1481 #: ../../boot.php:1491
msgid "Profile Details" msgid "Profile Details"
msgstr "Profildetails" msgstr "Profildetails"
#: ../../boot.php:1496 #: ../../boot.php:1506
msgid "Events and Calendar" msgid "Events and Calendar"
msgstr "Ereignisse und Kalender" msgstr "Ereignisse und Kalender"
#: ../../boot.php:1502 #: ../../boot.php:1512
msgid "Only You Can See This" msgid "Only You Can See This"
msgstr "Nur Du Kannst Das Sehen" msgstr "Nur Du Kannst Das Sehen"

View file

@ -751,8 +751,10 @@ $a->strings["Network timeout"] = "Netzwerk Wartezeit";
$a->strings["Value is in seconds. Set to 0 for unlimited (not recommended)."] = "Der Wert ist in Sekunden. Setze 0 für unbegrenzt (nicht empfohlen)."; $a->strings["Value is in seconds. Set to 0 for unlimited (not recommended)."] = "Der Wert ist in Sekunden. Setze 0 für unbegrenzt (nicht empfohlen).";
$a->strings["Delivery interval"] = "Zustellungsintervall"; $a->strings["Delivery interval"] = "Zustellungsintervall";
$a->strings["Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers."] = "Verzögere im Hintergrund laufende Auslieferungsprozesse um die angegebene Anzahl an Sekunden um die Systemlast zu verringern. Empfehlungen: 4-5 für Shared-Hosts, 2-3 für VPS, 0-1 für große dedizierte Server."; $a->strings["Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers."] = "Verzögere im Hintergrund laufende Auslieferungsprozesse um die angegebene Anzahl an Sekunden um die Systemlast zu verringern. Empfehlungen: 4-5 für Shared-Hosts, 2-3 für VPS, 0-1 für große dedizierte Server.";
$a->strings["Poll interval"] = "Abfrage Intervall";
$a->strings["Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval."] = "Verzögere Hintergrundprozesse um diese Anzahl an Sekunden um die Systemlast zu reduzieren. Bei 0 Sekunden wird das Auslieferungsintervall verwendet.";
$a->strings["Maximum Load Average"] = "Maximum Load Average"; $a->strings["Maximum Load Average"] = "Maximum Load Average";
$a->strings["Maximum system load before delivery and poll processes are deferred - default 50."] = ""; $a->strings["Maximum system load before delivery and poll processes are deferred - default 50."] = "Maximale Systemlast bevor Verteil- und Empfangsprozesse verschoben werden - Standard 50";
$a->strings["Update has been marked successful"] = "Update wurde als erfolgreich markiert"; $a->strings["Update has been marked successful"] = "Update wurde als erfolgreich markiert";
$a->strings["Executing %s failed. Check system logs."] = "Ausführung von %s schlug fehl. Systemprotokolle prüfen."; $a->strings["Executing %s failed. Check system logs."] = "Ausführung von %s schlug fehl. Systemprotokolle prüfen.";
$a->strings["Update %s was successfully applied."] = "Update %s war erfolgreich."; $a->strings["Update %s was successfully applied."] = "Update %s war erfolgreich.";
@ -831,6 +833,8 @@ $a->strings["No compatible communication protocols or feeds were discovered."] =
$a->strings["The profile address specified does not provide adequate information."] = "Die angegebene Profiladresse liefert unzureichende Informationen."; $a->strings["The profile address specified does not provide adequate information."] = "Die angegebene Profiladresse liefert unzureichende Informationen.";
$a->strings["An author or name was not found."] = "Es wurde kein Autor oder Name gefunden."; $a->strings["An author or name was not found."] = "Es wurde kein Autor oder Name gefunden.";
$a->strings["No browser URL could be matched to this address."] = "Zu dieser Adresse konnte keine passende Browser URL gefunden werden."; $a->strings["No browser URL could be matched to this address."] = "Zu dieser Adresse konnte keine passende Browser URL gefunden werden.";
$a->strings["Unable to match @-style Identity Address with a known protocol or email contact."] = "Konnte die @-Adresse mit keinem der bekannten Protokolle oder Email-Kontakte abgleichen.";
$a->strings["Use mailto: in front of address to force email check."] = "Verwende mailto: vor der Email Adresse um eine Überprüfung der Email Adresse zu erzwingen.";
$a->strings["The profile address specified belongs to a network which has been disabled on this site."] = "Die Adresse dieses Profils gehört zu einem Netzwerk, mit dem die Kommunikation auf dieser Seite ausgeschaltet wurde."; $a->strings["The profile address specified belongs to a network which has been disabled on this site."] = "Die Adresse dieses Profils gehört zu einem Netzwerk, mit dem die Kommunikation auf dieser Seite ausgeschaltet wurde.";
$a->strings["Limited profile. This person will be unable to receive direct/personal notifications from you."] = "Eingeschränktes Profil. Diese Person wird keine direkten/privaten Nachrichten von dir erhalten können."; $a->strings["Limited profile. This person will be unable to receive direct/personal notifications from you."] = "Eingeschränktes Profil. Diese Person wird keine direkten/privaten Nachrichten von dir erhalten können.";
$a->strings["Unable to retrieve contact information."] = "Konnte die Kontaktinformationen nicht empfangen."; $a->strings["Unable to retrieve contact information."] = "Konnte die Kontaktinformationen nicht empfangen.";
@ -972,8 +976,8 @@ $a->strings["Install Facebook connector for this account."] = "Facebook-Connecto
$a->strings["Remove Facebook connector"] = "Facebook-Connector entfernen"; $a->strings["Remove Facebook connector"] = "Facebook-Connector entfernen";
$a->strings["Re-authenticate [This is necessary whenever your Facebook password is changed.]"] = "Neu authentifizieren [Das ist immer dann nötig, wenn Du Dein Facebook-Passwort geändert hast.]"; $a->strings["Re-authenticate [This is necessary whenever your Facebook password is changed.]"] = "Neu authentifizieren [Das ist immer dann nötig, wenn Du Dein Facebook-Passwort geändert hast.]";
$a->strings["Post to Facebook by default"] = "Veröffentliche standardmäßig bei Facebook"; $a->strings["Post to Facebook by default"] = "Veröffentliche standardmäßig bei Facebook";
$a->strings["Facebook friend linking has been disabled on this site. The following settings will have no effect."] = ""; $a->strings["Facebook friend linking has been disabled on this site. The following settings will have no effect."] = "Das verlinken von Facebook-Kontakten wurde auf dieser Seite deaktiviert. Die folgenden Einstellungen haben keinen Effekt.";
$a->strings["Facebook friend linking has been disabled on this site. If you disable it, you will be unable to re-enable it."] = ""; $a->strings["Facebook friend linking has been disabled on this site. If you disable it, you will be unable to re-enable it."] = "Das verlinken von Facebook-Kontakten wurde auf dieser Seite deaktiviert. Wenn du es ausgeschaltet hast, kannst du es nicht wieder aktivieren.";
$a->strings["Link all your Facebook friends and conversations on this website"] = "All meine Facebook-Kontakte und -Konversationen hier auf diese Website importieren"; $a->strings["Link all your Facebook friends and conversations on this website"] = "All meine Facebook-Kontakte und -Konversationen hier auf diese Website importieren";
$a->strings["Facebook conversations consist of your <em>profile wall</em> and your friend <em>stream</em>."] = "Facebook-Konversationen bestehen aus deinen Beiträgen auf deiner<em>Pinnwand</em>, sowie den Beiträgen deiner Freunde <em>Stream</em>."; $a->strings["Facebook conversations consist of your <em>profile wall</em> and your friend <em>stream</em>."] = "Facebook-Konversationen bestehen aus deinen Beiträgen auf deiner<em>Pinnwand</em>, sowie den Beiträgen deiner Freunde <em>Stream</em>.";
$a->strings["On this website, your Facebook friend stream is only visible to you."] = "Hier auf dieser Webseite kannst nur du die Beiträge Deiner Facebook-Freunde (Stream) sehen."; $a->strings["On this website, your Facebook friend stream is only visible to you."] = "Hier auf dieser Webseite kannst nur du die Beiträge Deiner Facebook-Freunde (Stream) sehen.";
@ -1255,6 +1259,8 @@ $a->strings["Posterous Post Settings"] = "Posterous Beitrags-Einstellungen";
$a->strings["Enable Posterous Post Plugin"] = "Posterous-Plugin aktivieren"; $a->strings["Enable Posterous Post Plugin"] = "Posterous-Plugin aktivieren";
$a->strings["Posterous login"] = "Posterous-Anmeldename"; $a->strings["Posterous login"] = "Posterous-Anmeldename";
$a->strings["Posterous password"] = "Posterous-Passwort"; $a->strings["Posterous password"] = "Posterous-Passwort";
$a->strings["Posterous site ID"] = "Posterous site ID";
$a->strings["Posterous API token"] = "Posterous API token";
$a->strings["Post to Posterous by default"] = "Veröffentliche öffentliche Beiträge standardmäßig bei Posterous"; $a->strings["Post to Posterous by default"] = "Veröffentliche öffentliche Beiträge standardmäßig bei Posterous";
$a->strings["Theme settings"] = "Themen Einstellungen"; $a->strings["Theme settings"] = "Themen Einstellungen";
$a->strings["Set resize level for images in posts and comments (width and height)"] = "Wähle das Vergrößerungsmaß für Bilder in Beiträgen und Kommentaren (Höhe und Breite)"; $a->strings["Set resize level for images in posts and comments (width and height)"] = "Wähle das Vergrößerungsmaß für Bilder in Beiträgen und Kommentaren (Höhe und Breite)";
@ -1277,14 +1283,22 @@ $a->strings["Find Friends"] = "Freunde finden";
$a->strings["Local Directory"] = "Lokales Verzeichnis"; $a->strings["Local Directory"] = "Lokales Verzeichnis";
$a->strings["Similar Interests"] = "Ähnliche Interessen"; $a->strings["Similar Interests"] = "Ähnliche Interessen";
$a->strings["Invite Friends"] = "Freunde einladen"; $a->strings["Invite Friends"] = "Freunde einladen";
$a->strings["Earth View"] = "Earth View"; $a->strings["Earth Layers"] = "Earth Layers";
$a->strings["Set zoomfactor for Earth Layers"] = "Zoomfaktor der Earth Layer";
$a->strings["Set longitude (X) for Earth Layers"] = "Longitude (X) der Earth Layer";
$a->strings["Set latitude (Y) for Earth Layers"] = "Latitude (Y) der Earth Layer";
$a->strings["Help or @NewHere ?"] = "Hilfe oder @NewHere"; $a->strings["Help or @NewHere ?"] = "Hilfe oder @NewHere";
$a->strings["Connect Services"] = "Verbinde Dienste"; $a->strings["Connect Services"] = "Verbinde Dienste";
$a->strings["Last Tweets"] = "Neueste Tweets"; $a->strings["Last Tweets"] = "Neueste Tweets";
$a->strings["Set twitter search term"] = ""; $a->strings["Set twitter search term"] = "Twitter Suchbegriff";
$a->strings["don't show"] = "nicht zeigen";
$a->strings["show"] = "zeigen";
$a->strings["Show/hide boxes at right-hand column:"] = "Rahmen auf der rechten Seite anzeigen/verbergen";
$a->strings["Set line-height for posts and comments"] = "Liniengröße für Beiträge und Kommantare festlegen"; $a->strings["Set line-height for posts and comments"] = "Liniengröße für Beiträge und Kommantare festlegen";
$a->strings["Set resolution for middle column"] = "Auflösung für die Mittelspalte setzen"; $a->strings["Set resolution for middle column"] = "Auflösung für die Mittelspalte setzen";
$a->strings["Set color scheme"] = "Wähle Farbschema"; $a->strings["Set color scheme"] = "Wähle Farbschema";
$a->strings["Set zoomfactor for Earth Layer"] = "Zoomfaktor der Earth Layer";
$a->strings["Last tweets"] = "Neueste Tweets";
$a->strings["Alignment"] = "Ausrichtung"; $a->strings["Alignment"] = "Ausrichtung";
$a->strings["Left"] = "Links"; $a->strings["Left"] = "Links";
$a->strings["Center"] = "Mitte"; $a->strings["Center"] = "Mitte";
@ -1514,8 +1528,6 @@ $a->strings["Image/photo"] = "Bild/Foto";
$a->strings["Cannot locate DNS info for database server '%s'"] = "Kann die DNS Informationen für den Datenbanken Server '%s' nicht ermitteln."; $a->strings["Cannot locate DNS info for database server '%s'"] = "Kann die DNS Informationen für den Datenbanken Server '%s' nicht ermitteln.";
$a->strings["[no subject]"] = "[kein Betreff]"; $a->strings["[no subject]"] = "[kein Betreff]";
$a->strings["Visible to everybody"] = "Für jeden sichtbar"; $a->strings["Visible to everybody"] = "Für jeden sichtbar";
$a->strings["show"] = "zeigen";
$a->strings["don't show"] = "nicht zeigen";
$a->strings["Friendica Notification"] = "Friendica-Benachrichtigung"; $a->strings["Friendica Notification"] = "Friendica-Benachrichtigung";
$a->strings["Thank You,"] = "Danke,"; $a->strings["Thank You,"] = "Danke,";
$a->strings["%s Administrator"] = "der Administrator von %s"; $a->strings["%s Administrator"] = "der Administrator von %s";

View file

@ -45,3 +45,17 @@ nav #site-location {
-moz-border-radius: 3px; -moz-border-radius: 3px;
box-shadow: 3px 3px 10px 0 #000000; box-shadow: 3px 3px 10px 0 #000000;
} }
#sidebar-page-list img {
border-radius: 3px;
-moz-border-radius: 3px;
box-shadow: 3px 3px 10px -2px #000000;
}
.contact-entry-photo img, .profile-match-photo img, #photo-photo img, .directory-photo-img {
border-radius: 3px;
-moz-border-radius: 3px;
box-shadow: 3px 3px 10px 0 #000000;
}