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');
define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_VERSION', '3.0.1341' );
define ( 'FRIENDICA_VERSION', '3.0.1343' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
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);

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

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) {
var t = this;
// Internet Explorer has built-in automatic linking
if (tinyMCE.isIE)
return;
// Add a key down handler
ed.onKeyDown.add(function(ed, e) {
ed.onKeyDown.addToTop(function(ed, e) {
if (e.keyCode == 13)
return t.handleEnter(ed);
});
// Internet Explorer has built-in automatic linking for most cases
if (tinyMCE.isIE)
return;
ed.onKeyPress.add(function(ed, e) {
if (e.which == 41)
return t.handleEclipse(ed);
@ -61,7 +61,7 @@
// We need at least five characters to form a URL,
// 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) {
// During testing, the caret is placed inbetween two text nodes.
// The previous text node contains the URL.
@ -124,6 +124,12 @@
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();
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;
// Use fixed position if it exists
if (tinymce.isIE6)
if (tinymce.isIE6 || document.compatMode == 'BackCompat')
posCss = 'absolute;top:' + vp.y;
else
posCss = 'fixed;top:0';

File diff suppressed because one or more lines are too long

View file

@ -261,12 +261,96 @@
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()
endElement = selection.getEnd();
// Disable all key presses in contentEditable=false except delete or backspace
nonEditableParent = getNonEditableParent(startElement) || getNonEditableParent(endElement);
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();
// Arrow left/right select the element and collapse left/right
@ -298,6 +382,7 @@
positionCaretOnElement(nonEditableParent, true);
} else {
dom.remove(nonEditableParent);
return;
}
} else {
removeCaretContainer(caretContainer);
@ -315,23 +400,31 @@
positionCaretOnElement(nonEditableParent, false);
} else {
dom.remove(nonEditableParent);
return;
}
} else {
removeCaretContainer(caretContainer);
}
}
}
if ((keyCode == VK.BACKSPACE || keyCode == VK.DELETE) && !canDelete(keyCode == VK.BACKSPACE)) {
e.preventDefault();
return false;
}
}
}
};
ed.onMouseDown.addToTop(function(ed, e){
// prevent collapsing selection to caret when clicking in a non-editable section
ed.onMouseDown.addToTop(function(ed, e) {
var node = ed.selection.getNode();
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.onKeyDown.addToTop(handleKey);
ed.onKeyUp.addToTop(moveSelection);
@ -341,6 +434,31 @@
init : function(ed, url) {
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")) + " ";
nonEditClass = " " + tinymce.trim(ed.getParam("noneditable_noneditable_class", "mceNonEditable")) + " ";
@ -354,24 +472,8 @@
handleContentEditableSelection(ed);
if (nonEditableRegExps) {
ed.onBeforeSetContent.add(function(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() {
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;
});
ed.selection.onBeforeSetContent.add(convertRegExpsToNonEditable);
ed.onBeforeSetContent.add(convertRegExpsToNonEditable);
}
// 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
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
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;
function find(d) {
el = DOM.select(':input:enabled,*[tabindex]');
el = DOM.select(':input:enabled,*[tabindex]:not(iframe)');
function canSelectRecursive(e) {
return e.nodeName==="BODY" || (e.type != 'hidden' &&

View file

@ -137,7 +137,7 @@ function updateAction() {
do {
if (cell == tdElm)
break;
col += cell.getAttribute("colspan");
col += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
} while ((cell = nextCell(cell)) != null);
for (var i=0; i<rows.length; i++) {
@ -152,7 +152,7 @@ function updateAction() {
cell = updateCell(cell, true);
break;
}
curr += cell.getAttribute("colspan");
curr += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
} 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, address, pre {margin-left: 3px}
section, article, address, hgroup, aside {margin: 1em 0 0 3px}
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, figure {margin-left: 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)}
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==)}
hgroup {background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7)}
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() {
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">
<input type="submit" id="insert" name="insert" value="{#apply}" />
<div id="preview"></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>
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();"/>
<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>
</form>
</body>

File diff suppressed because one or more lines are too long

View file

@ -69,6 +69,16 @@
each(previewStyles.split(' '), function(name) {
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
if (name == 'font-size') {
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.
// 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);
if (!DOM.boxModel)
@ -925,7 +935,7 @@
},
_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', {
'name': ed.getLang('advanced.toolbar'),
@ -941,6 +951,7 @@
// Create toolbar and add the controls
for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {
toolbarsExist = true;
tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i});
if (s['theme_advanced_buttons' + i + '_add'])
@ -954,6 +965,9 @@
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(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));
DOM.setHTML(n, h.join(''));
@ -1112,7 +1126,7 @@
}
if (c = cm.get('formatselect')) {
p = getParent(DOM.isBlock);
p = getParent(ed.dom.isBlock);
if (p)
c.select(p.nodeName.toLowerCase());
@ -1210,7 +1224,7 @@
return;
// Handle prefix
if (tinymce.isIE && n.scopeName !== 'HTML')
if (tinymce.isIE && n.scopeName !== 'HTML' && n.scopeName)
na = n.scopeName + ':' + na;
// Remove internal prefix
@ -1271,7 +1285,7 @@
if (v) {
ti += 'class: ' + v + ' ';
if (DOM.isBlock(n) || na == 'img' || na == 'span')
if (ed.dom.isBlock(n) || na == 'img' || na == 'span')
na += '.' + v;
}
}

View file

@ -104,10 +104,12 @@ var ImageDialog = {
},
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) {
st = tinyMCEPopup.dom.parseStyle(this.styleVal);
tinymce.each(tinyMCEPopup.dom.parseStyle(this.styleVal), function(value, key) {
st[key] = value;
});
// Handle align
v = getSelectValue(f, 'align');

View file

@ -94,11 +94,12 @@ h3 {font-size:14px;}
#plugintable, #about #plugintable td {border:1px solid #919B9C;}
#plugintable {width:96%; margin-top:10px;}
#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 #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
#colorpicker #light div {overflow:hidden;}
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
#colorpicker .panel_wrapper div.current {height:175px;}
#colorpicker #namedcolors {width:150px;}
#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 */
.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 .mceNoIcons a .mceText {padding-left:10px}
.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 .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 */
.highcontrastSkin .mce_p span.mceText {}
.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 {width:96%; margin-top:10px;}
#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 #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
#colorpicker #light div {overflow:hidden;}
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
#colorpicker .panel_wrapper div.current {height:175px;}
#colorpicker #namedcolors {width:150px;}
#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}
/* 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 a .mceText {padding-left:10px}
.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 .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 */
.o2k7Skin .mce_formatPreview a {font-size:10px}
.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) {
var whiteSpaceRe = /^\s*|\s*$/g,
undefined, isRegExpBroken = 'B'.replace(/A(.)|B/, '$1') === '$1';
undef, isRegExpBroken = 'B'.replace(/A(.)|B/, '$1') === '$1';
var tinymce = {
majorVersion : '3',
minorVersion : '5b2',
minorVersion : '5.0.1',
releaseDate : '2012-03-15',
releaseDate : '2012-05-10',
_init : function() {
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
nl = d.getElementsByTagName('base');
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
if (/^https?:\/\/[^\/]+$/.test(v))
v += '/';
@ -103,7 +105,7 @@
is : function(o, t) {
if (!t)
return o !== undefined;
return o !== undef;
if (t == 'array' && (o.hasOwnProperty && o instanceof Array))
return true;
@ -137,7 +139,7 @@
s = s || o;
if (o.length !== undefined) {
if (o.length !== undef) {
// Indexed arrays, needed for Safari
for (n=0, l = o.length; n < l; n++) {
if (cb.call(s, o[n], n, o) === false)
@ -191,19 +193,23 @@
return -1;
},
extend : function(o, e) {
var i, l, a = arguments;
extend : function(obj, ext) {
var i, l, name, args = arguments, value;
for (i = 1, l = a.length; i < l; i++) {
e = a[i];
for (i = 1, l = args.length; i < l; i++) {
ext = args[i];
for (name in ext) {
if (ext.hasOwnProperty(name)) {
value = ext[name];
tinymce.each(e, function(v, n) {
if (v !== undefined)
o[n] = v;
});
if (value !== undef) {
obj[name] = value;
}
}
}
}
return o;
return obj;
},
@ -346,12 +352,9 @@
},
addUnload : function(f, s) {
var t = this;
var t = this, unload;
f = {func : f, scope : s || this};
if (!t.unloads) {
function unload() {
unload = function() {
var li = t.unloads, o, n;
if (li) {
@ -382,8 +385,6 @@
function fakeUnload() {
var d = document;
// Is there things still loading, then do some magic
if (d.readyState == 'interactive') {
function stop() {
// Prevent memory leak
d.detachEvent('onstop', stop);
@ -395,6 +396,8 @@
d = 0;
};
// Is there things still loading, then do some magic
if (d.readyState == 'interactive') {
// Fire unload when the currently loading page is stopped
if (d)
d.attachEvent('onstop', stop);
@ -409,6 +412,9 @@
}
};
f = {func : f, scope : s || this};
if (!t.unloads) {
// Attach unload handler
if (win.attachEvent) {
win.attachEvent('onunload', unload);
@ -439,7 +445,11 @@
},
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) {
@ -465,7 +475,7 @@
var val = replace, args = arguments, i;
for (i = 0; i < args.length - 2; i++) {
if (args[i] === undefined) {
if (args[i] === undef) {
val = val.replace(new RegExp('\\$' + i, 'g'), '');
} else {
val = val.replace(new RegExp('\\$' + i, 'g'), args[i]);
@ -496,52 +506,64 @@
tinymce.create('tinymce.util.Dispatcher', {
scope : null,
listeners : null,
inDispatch: false,
Dispatcher : function(s) {
this.scope = s || this;
Dispatcher : function(scope) {
this.scope = scope || this;
this.listeners = [];
},
add : function(cb, s) {
this.listeners.push({cb : cb, scope : s || this.scope});
add : function(callback, scope) {
this.listeners.push({cb : callback, scope : scope || this.scope});
return cb;
return callback;
},
addToTop : function(cb, s) {
this.listeners.unshift({cb : cb, scope : s || this.scope});
addToTop : function(callback, 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) {
var l = this.listeners, o = null;
remove : function(callback) {
var listeners = this.listeners, output = null;
tinymce.each(l, function(c, i) {
if (cb == c.cb) {
o = cb;
l.splice(i, 1);
tinymce.each(listeners, function(listener, i) {
if (callback == listener.cb) {
output = listener;
listeners.splice(i, 1);
return false;
}
});
return o;
return output;
},
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
// And this is also more efficient
for (i = 0; i<li.length; i++) {
c = li[i];
s = c.cb.apply(c.scope, a.length > 0 ? a : [c.scope]);
for (i = 0; i < listeners.length; i++) {
listener = listeners[i];
returnValue = listener.cb.apply(listener.scope, args.length > 0 ? args : [listener.scope]);
if (s === false)
if (returnValue === false)
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;
// 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;
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;
});
if (b = s.base_uri) {
b = s.base_uri;
if (b) {
if (!t.protocol)
t.protocol = b.protocol;
if (!t.userInfo)
t.userInfo = b.userInfo;
if (!t.port && t.host == 'mce_host')
if (!t.port && t.host === 'mce_host')
t.port = b.port;
if (!t.host || t.host == 'mce_host')
if (!t.host || t.host === 'mce_host')
t.host = b.host;
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)
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);
// Add query
@ -649,7 +678,7 @@ tinymce.create('tinymce.util.Dispatcher', {
},
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);
},
@ -680,7 +709,7 @@ tinymce.create('tinymce.util.Dispatcher', {
}
}
if (bp == 1)
if (bp === 1)
return path;
for (i = 0, l = base.length - (bp - 1); i < l; i++)
@ -715,11 +744,11 @@ tinymce.create('tinymce.util.Dispatcher', {
// Merge relURLParts chunks
for (i = path.length - 1, o = []; i >= 0; i--) {
// Ignore empty or .
if (path[i].length == 0 || path[i] == ".")
if (path[i].length === 0 || path[i] === ".")
continue;
// Is parent
if (path[i] == '..') {
if (path[i] === '..') {
nb++;
continue;
}
@ -830,7 +859,7 @@ tinymce.create('tinymce.util.Dispatcher', {
if (b == -1) {
b = c.indexOf(p);
if (b != 0)
if (b !== 0)
return null;
} else
b += 2;
@ -863,7 +892,7 @@ tinymce.create('tinymce.util.Dispatcher', {
(function() {
function serialize(o, quote) {
var i, v, t;
var i, v, t, name;
quote = quote || '"';
@ -901,9 +930,9 @@ tinymce.create('tinymce.util.Dispatcher', {
v = '{';
for (i in o) {
if (o.hasOwnProperty(i)) {
v += typeof o[i] != 'function' ? (v.length > 1 ? ',' + quote : quote) + i + quote +':' + serialize(o[i], quote) : '';
for (name in o) {
if (o.hasOwnProperty(name)) {
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) {
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
o.scope = o.scope || this;
o.success_scope = o.success_scope || o.scope;
@ -964,18 +1005,6 @@ tinymce.create('static tinymce.util.XHR', {
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
if (!o.async)
return ready();
@ -1055,13 +1084,13 @@ tinymce.create('static tinymce.util.XHR', {
modifierPressed: function (e) {
return e.shiftKey || e.ctrlKey || e.altKey;
}
}
};
})(tinymce);
(function(tinymce) {
var VK = tinymce.VK, BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE;
tinymce.util.Quirks = function(editor) {
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 {
editor.getDoc().execCommand(cmd, false, state);
} catch (ex) {
@ -1069,19 +1098,10 @@ tinymce.create('static tinymce.util.XHR', {
}
}
function cleanupStylesWhenDeleting(ed) {
var dom = ed.dom, selection = ed.selection;
function cleanupStylesWhenDeleting() {
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();
// Find root block
@ -1096,7 +1116,7 @@ tinymce.create('static tinymce.util.XHR', {
node = blockElm.firstChild;
// 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;
if (node && node.nodeName === 'SPAN') {
@ -1105,7 +1125,7 @@ tinymce.create('static tinymce.util.XHR', {
}
// 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
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
@ -1121,55 +1141,120 @@ tinymce.create('static tinymce.util.XHR', {
// Restore the selection
selection.moveToBookmark(bm);
});
}
});
};
function emptyEditorWhenDeleting(ed) {
function serializeRng(rng) {
var body = ed.dom.create("body");
var contents = rng.cloneContents();
body.appendChild(contents);
return ed.selection.serializer.serialize(body, {format: 'html'});
editor.onKeyDown.add(function(editor, e) {
var isDelete;
isDelete = e.keyCode == DELETE;
if (!e.isDefaultPrevented() && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
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) {
var selection = serializeRng(rng);
return container;
};
var allRng = ed.dom.createRng();
allRng.selectNode(ed.getBody());
function isAtStartEndOfBody(rng, start) {
var container, offset, root, childNode, prefix = start ? 'start' : 'end', isAfter;
var allSelection = serializeRng(allRng);
return selection === allSelection;
container = rng[prefix + 'Container'];
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) {
var keyCode = e.keyCode;
if (keyCode == DELETE || keyCode == BACKSPACE) {
var rng = ed.selection.getRng(true);
if (!rng.collapsed && allContentsSelected(rng)) {
ed.setContent('', {format : 'raw'});
ed.nodeChanged();
// Check if start/end is in the middle of text
if (container.nodeType == 3 && ((start && offset > 0) || (!start && offset < container.nodeValue.length))) {
return false;
}
// Walk up the DOM tree to see if the endpoint is at the beginning/end of body
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();
}
}
});
};
function inputMethodFocus(ed) {
ed.dom.bind(ed.getDoc(), 'focusin', function() {
ed.selection.setRng(ed.selection.getRng());
function inputMethodFocus() {
if (!editor.settings.content_editable) {
// 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) {
ed.onKeyDown.add(function(ed, e) {
if (e.keyCode === BACKSPACE) {
if (ed.selection.isCollapsed() && ed.selection.getRng(true).startOffset === 0) {
var node = ed.selection.getNode();
function removeHrOnBackspace() {
editor.onKeyDown.add(function(editor, e) {
if (!e.isDefaultPrevented() && e.keyCode === BACKSPACE) {
if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
var node = selection.getNode();
var previousSibling = node.previousSibling;
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "hr") {
ed.dom.remove(previousSibling);
dom.remove(previousSibling);
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
// wouldn't get proper focus if the user clicked on the HTML element
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") {
var body = ed.getBody();
var body = editor.getBody();
// Blur the body it's focused but not correctly focused
body.blur();
@ -1197,33 +1282,33 @@ tinymce.create('static tinymce.util.XHR', {
}
};
function selectControlElements(ed) {
ed.onClick.add(function(ed, e) {
function selectControlElements() {
editor.onClick.add(function(editor, e) {
e = e.target;
// Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250
// WebKit can't even do simple things like selecting an image
// Needs tobe the setBaseAndExtend or it will fail to select floated images
if (/^(IMG|HR)$/.test(e.nodeName))
ed.selection.getSel().setBaseAndExtent(e, 0, e, 1);
if (/^(IMG|HR)$/.test(e.nodeName)) {
selection.getSel().setBaseAndExtent(e, 0, e, 1);
}
if (e.nodeName == 'A' && ed.dom.hasClass(e, 'mceItemAnchor'))
ed.selection.select(e);
if (e.nodeName == 'A' && dom.hasClass(e, 'mceItemAnchor')) {
selection.select(e);
}
ed.nodeChanged();
editor.nodeChanged();
});
};
function removeStylesWhenDeletingAccrossBlockElements(ed) {
var selection = ed.selection, dom = ed.dom;
function removeStylesWhenDeletingAccrossBlockElements() {
function getAttributeApplyFunction() {
var template = dom.getAttribs(selection.getStart().cloneNode(false));
return function() {
var target = selection.getStart();
if (target !== ed.getBody()) {
if (target !== editor.getBody()) {
dom.setAttrib(target, "style", null);
tinymce.each(template, function(attr) {
@ -1237,91 +1322,68 @@ tinymce.create('static tinymce.util.XHR', {
return !selection.isCollapsed() && selection.getStart() != selection.getEnd();
}
function blockEvent(ed, e) {
function blockEvent(editor, e) {
e.preventDefault();
return false;
}
ed.onKeyPress.add(function(ed, e) {
editor.onKeyPress.add(function(editor, e) {
var applyAttributes;
if ((e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) {
applyAttributes = getAttributeApplyFunction();
ed.getDoc().execCommand('delete', false, null);
editor.getDoc().execCommand('delete', false, null);
applyAttributes();
e.preventDefault();
return false;
}
});
dom.bind(ed.getDoc(), 'cut', function(e) {
dom.bind(editor.getDoc(), 'cut', function(e) {
var applyAttributes;
if (isSelectionAcrossElements()) {
applyAttributes = getAttributeApplyFunction();
ed.onKeyUp.addToTop(blockEvent);
editor.onKeyUp.addToTop(blockEvent);
setTimeout(function() {
applyAttributes();
ed.onKeyUp.remove(blockEvent);
editor.onKeyUp.remove(blockEvent);
}, 0);
}
});
}
/*
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) {
function selectionChangeNodeChanged() {
var lastRng, selectionTimer;
ed.dom.bind(ed.getDoc(), 'selectionchange', function() {
dom.bind(editor.getDoc(), 'selectionchange', function() {
if (selectionTimer) {
clearTimeout(selectionTimer);
selectionTimer = 0;
}
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
if (!lastRng || !tinymce.dom.RangeUtils.compareRanges(rng, lastRng)) {
ed.nodeChanged();
editor.nodeChanged();
lastRng = rng;
}
}, 50);
});
}
function ensureBodyHasRoleApplication(ed) {
function ensureBodyHasRoleApplication() {
document.body.setAttribute("role", "application");
}
function disableBackspaceIntoATable(ed) {
ed.onKeyDown.add(function(ed, e) {
if (e.keyCode === BACKSPACE) {
if (ed.selection.isCollapsed() && ed.selection.getRng(true).startOffset === 0) {
var previousSibling = ed.selection.getNode().previousSibling;
function disableBackspaceIntoATable() {
editor.onKeyDown.add(function(editor, e) {
if (!e.isDefaultPrevented() && e.keyCode === BACKSPACE) {
if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
var previousSibling = selection.getNode().previousSibling;
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "table") {
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;
// 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
// avoid the caret from getting stuck at the BR elements while pressing the right arrow key
setEditorCommandState(editor, 'RespectVisibilityInDesign', true);
editor.dom.addClass(editor.getBody(), 'mceHideBrInPre');
setEditorCommandState('RespectVisibilityInDesign', true);
dom.addClass(editor.getBody(), 'mceHideBrInPre');
// Adds a \n before all BR elements in PRE to get them visual
editor.parser.addNodeFilter('pre', function(nodes, name) {
@ -1382,43 +1444,210 @@ tinymce.create('static tinymce.util.XHR', {
});
}
tinymce.create('tinymce.util.Quirks', {
Quirks: function(ed) {
function removePreSerializedStylesWhenSelectingControls() {
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
disableBackspaceIntoATable(ed);
disableBackspaceIntoATable();
removeBlockQuoteOnBackSpace();
emptyEditorWhenDeleting();
// WebKit
if (tinymce.isWebKit) {
cleanupStylesWhenDeleting(ed);
emptyEditorWhenDeleting(ed);
inputMethodFocus(ed);
selectControlElements(ed);
keepInlineElementOnDeleteBackspace();
cleanupStylesWhenDeleting();
inputMethodFocus();
selectControlElements();
// iOS
if (tinymce.isIDevice) {
selectionChangeNodeChanged(ed);
selectionChangeNodeChanged();
}
}
// IE
if (tinymce.isIE) {
removeHrOnBackspace(ed);
emptyEditorWhenDeleting(ed);
ensureBodyHasRoleApplication(ed);
//removeStylesOnPTagsInheritedFromHeadingTag(ed)
addNewLinesBeforeBrInPre(ed);
removeHrOnBackspace();
ensureBodyHasRoleApplication();
addNewLinesBeforeBrInPre();
removePreSerializedStylesWhenSelectingControls();
deleteImageOnBackSpace();
}
// Gecko
if (tinymce.isGecko) {
removeHrOnBackspace(ed);
focusBody(ed);
removeStylesWhenDeletingAccrossBlockElements(ed);
removeHrOnBackspace();
focusBody();
removeStylesWhenDeletingAccrossBlockElements();
setGeckoEditingOptions();
addBrAfterLastLinks();
removeGhostSelection();
}
}
});
})(tinymce);
};
(function(tinymce) {
var namedEntities, baseEntities, reverseEntities,
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,' +
'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,' +
'811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro'
, 32);
'811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);
tinymce.html = tinymce.html || {};
@ -1723,8 +1951,28 @@ tinymce.html.Styles = function(settings, schema) {
str = str.replace(/\\([\'\";:])/g, "$1");
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) {
// Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing
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);
// Convert URLs and force them into url('value') format
value = value.replace(urlOrStrRegExp, function(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, "\\'") + "')";
});
value = value.replace(urlOrStrRegExp, processUrl);
styles[name] = isEncoded ? decode(value, true) : value;
}
@ -1934,7 +2163,8 @@ tinymce.html.Styles = function(settings, schema) {
'span[A][B]' +
'ins[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][]' +
'iframe[A|name|src|height|width|sandbox|seamless][]' +
'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);
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 ' +
'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/.
function patternToRegExp(str) {
@ -2173,7 +2403,7 @@ tinymce.html.Styles = function(settings, schema) {
function addValidElements(valid_elements) {
var ei, el, ai, al, yl, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder,
prefix, outputName, globalAttributes, globalAttributesOrder, transElement, key, childKey, value,
elementRuleRegExp = /^([#+-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/,
elementRuleRegExp = /^([#+\-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/,
attrRuleRegExp = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,
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
tokenRegExp = new RegExp('<(?:' +
'(?:!--([\\w\\W]*?)-->)|' + // Comment
@ -2553,7 +2824,7 @@ tinymce.html.Styles = function(settings, schema) {
'(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE
'(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI
'(?:\\/([^>]+)>)|' + // End element
'(?:([A-Za-z0-9\-\:]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element
'(?:([A-Za-z0-9\\-\\:]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element
')', 'g');
attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g;
@ -2620,46 +2891,7 @@ tinymce.html.Styles = function(settings, schema) {
attrList = [];
attrList.map = {};
attribsValue.replace(attrRegExp, function(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
});
});
attribsValue.replace(attrRegExp, parseAttribute);
} else {
attrList = [];
attrList.map = {};
@ -3281,7 +3513,7 @@ tinymce.html.Styles = function(settings, schema) {
self.parse = function(html, args) {
var parser, rootNode, node, nodes, i, l, fi, fl, list, name, validate,
blockElements, startWhiteSpaceRegExp, invalidChildren = [], isInWhiteSpacePreservedElement,
endWhiteSpaceRegExp, allWhiteSpaceRegExp, whiteSpaceElements, children, nonEmptyElements, rootBlockName;
endWhiteSpaceRegExp, allWhiteSpaceRegExp, isAllWhiteSpaceRegExp, whiteSpaceElements, children, nonEmptyElements, rootBlockName;
args = args || {};
matchedNodes = {};
@ -3296,6 +3528,7 @@ tinymce.html.Styles = function(settings, schema) {
startWhiteSpaceRegExp = /^[ \t\r\n]+/;
endWhiteSpaceRegExp = /[ \t\r\n]+$/;
allWhiteSpaceRegExp = /[ \t\r\n]+/g;
isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/;
function addRootBlocks() {
var node = rootNode.firstChild, next, rootBlockNode;
@ -3448,10 +3681,12 @@ tinymce.html.Styles = function(settings, schema) {
if (elementRule) {
if (blockElements[name]) {
if (!isInWhiteSpacePreservedElement) {
// Trim whitespace at beginning of block
for (textNode = node.firstChild; textNode && textNode.type === 3; ) {
// Trim whitespace of the first node in a block
textNode = node.firstChild;
if (textNode && textNode.type === 3) {
text = textNode.value.replace(startWhiteSpaceRegExp, '');
// Any characters left after trim or should we remove it
if (text.length > 0) {
textNode.value = text;
textNode = textNode.next;
@ -3460,12 +3695,27 @@ tinymce.html.Styles = function(settings, schema) {
textNode.remove();
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
for (textNode = node.lastChild; textNode && textNode.type === 3; ) {
textNode = sibling;
}
}
// Trim whitespace of the last node in a block
textNode = node.lastChild;
if (textNode && textNode.type === 3) {
text = textNode.value.replace(endWhiteSpaceRegExp, '');
// Any characters left after trim or should we remove it
if (text.length > 0) {
textNode.value = text;
textNode = textNode.prev;
@ -3474,6 +3724,19 @@ tinymce.html.Styles = function(settings, schema) {
textNode.remove();
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
if (settings.remove_trailing_brs) {
self.addNodeFilter('br', function(nodes, name) {
var i, l = nodes.length, node, blockElements = schema.getBlockElements(),
nonEmptyElements = schema.getNonEmptyElements(), parent, prev, prevName;
var i, l = nodes.length, node, blockElements = tinymce.extend({}, schema.getBlockElements()),
nonEmptyElements = schema.getNonEmptyElements(), parent, lastParent, prev, prevName;
// Remove brs from body element as well
blockElements.body = 1;
@ -3590,7 +3853,7 @@ tinymce.html.Styles = function(settings, schema) {
parent = node.parent;
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
prev = node.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);
};
self.remove = function(target, events, func) {
self.remove = function(target, events, func, scope) {
if (!target) {
return self;
}
// Old API supported direct ID assignment
if (typeof(target) === "string") {
target = document.getElementById(target);
@ -4322,7 +4629,7 @@ tinymce.dom = {};
// Old API supported multiple targets
if (target instanceof Array) {
var i = target;
var i = target.length;
while (i--) {
self.remove(target[i], events, func, scope);
@ -4379,6 +4686,46 @@ tinymce.dom = {};
namespace = 0;
})(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) {
// Shorten names
var each = tinymce.each,
@ -4568,8 +4915,8 @@ tinymce.dom = {};
h = 0;
return {
w : parseInt(w) || e.offsetWidth || e.clientWidth,
h : parseInt(h) || e.offsetHeight || e.clientHeight
w : parseInt(w, 10) || e.offsetWidth || e.clientWidth,
h : parseInt(h, 10) || e.offsetHeight || e.clientHeight
};
},
@ -5093,7 +5440,7 @@ tinymce.dom = {};
if (!u)
u = '';
head = t.select('head')[0];
head = d.getElementsByTagName('head')[0];
each(u.split(','), function(u) {
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);
function hex(s) {
s = parseInt(s).toString(16);
s = parseInt(s, 10).toString(16);
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.
// eg. "<p><span>a</span> <span>b</span></p>" should keep space between a and b
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;
} else if (type == 1) {
// If the only child is a bookmark then move it up
@ -5683,6 +6030,25 @@ tinymce.dom = {};
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) {
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
offset = 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;
}
@ -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
offset = 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;
}
@ -6681,7 +7047,7 @@ tinymce.dom = {};
var rng = selection.getRng(), start, end, bookmark = {};
function getIndexes(node) {
var node, parent, root, children, i, indexes = [];
var parent, root, children, i, indexes = [];
parent = node.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 (startContainer == endContainer && startContainer.nodeType == 1) {
// 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>';
ieRng.moveToElementText(startContainer.lastChild);
ieRng.select();
dom.doc.selection.clear();
startContainer.innerHTML = '';
return;
} else {
startOffset = dom.nodeIndex(startContainer);
startContainer = startContainer.parentNode;
}
}
if (startOffset == endOffset - 1) {
@ -6885,29 +7256,33 @@ tinymce.dom = {};
/*
* Sizzle CSS Selector Engine - v1.0
* Copyright 2009, The Dojo Foundation
* Sizzle CSS Selector Engine
* Copyright, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
* More information: http://sizzlejs.com/
*/
(function(){
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
expando = "sizcache",
done = 0,
toString = Object.prototype.toString,
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
// optimization where it does not always call our comparision
// function. If that is the case, discard the hasDuplicate value.
// Thus far that includes Google Chrome.
[0, 0].sort(function(){
[0, 0].sort(function() {
baseHasDuplicate = false;
return 0;
});
var Sizzle = function(selector, context, results, seed) {
var Sizzle = function( selector, context, results, seed ) {
results = results || [];
context = context || document;
@ -6921,13 +7296,16 @@ var Sizzle = function(selector, context, results, seed) {
return results;
}
var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context),
soFar = selector, ret, cur, pop, i;
var m, set, checkSet, extra, ret, cur, pop, i,
prune = true,
contextXML = Sizzle.isXML( context ),
parts = [],
soFar = selector;
// Reset the position of the chunker regexp (start from head)
do {
chunker.exec("");
m = chunker.exec(soFar);
chunker.exec( "" );
m = chunker.exec( soFar );
if ( m ) {
soFar = m[3];
@ -6942,8 +7320,10 @@ var Sizzle = function(selector, context, results, seed) {
} while ( m );
if ( parts.length > 1 && origPOS.exec( selector ) ) {
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
set = posProcess( parts[0] + parts[1], context );
set = posProcess( parts[0] + parts[1], context, seed );
} else {
set = Expr.relative[ parts[0] ] ?
[ context ] :
@ -6956,26 +7336,34 @@ var Sizzle = function(selector, context, results, seed) {
selector += parts.shift();
}
set = posProcess( selector, set );
set = posProcess( selector, set, seed );
}
}
} else {
// 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)
if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
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 ) {
ret = seed ?
{ expr: parts.pop(), set: makeArray(seed) } :
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 ) {
checkSet = makeArray(set);
checkSet = makeArray( set );
} else {
prune = false;
}
@ -6996,6 +7384,7 @@ var Sizzle = function(selector, context, results, seed) {
Expr.relative[ cur ]( checkSet, pop, contextXML );
}
} else {
checkSet = parts = [];
}
@ -7012,12 +7401,14 @@ var Sizzle = function(selector, context, results, seed) {
if ( toString.call(checkSet) === "[object Array]" ) {
if ( !prune ) {
results.push.apply( results, checkSet );
} else if ( context && context.nodeType === 1 ) {
for ( i = 0; checkSet[i] != null; i++ ) {
if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
results.push( set[i] );
}
}
} else {
for ( i = 0; checkSet[i] != null; i++ ) {
if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
@ -7025,6 +7416,7 @@ var Sizzle = function(selector, context, results, seed) {
}
}
}
} else {
makeArray( checkSet, results );
}
@ -7037,15 +7429,15 @@ var Sizzle = function(selector, context, results, seed) {
return results;
};
Sizzle.uniqueSort = function(results){
Sizzle.uniqueSort = function( results ) {
if ( sortOrder ) {
hasDuplicate = baseHasDuplicate;
results.sort(sortOrder);
results.sort( sortOrder );
if ( hasDuplicate ) {
for ( var i = 1; i < results.length; i++ ) {
if ( results[i] === results[i-1] ) {
results.splice(i--, 1);
if ( results[i] === results[ i - 1 ] ) {
results.splice( i--, 1 );
}
}
}
@ -7054,27 +7446,32 @@ Sizzle.uniqueSort = function(results){
return results;
};
Sizzle.matches = function(expr, set){
return Sizzle(expr, null, null, set);
Sizzle.matches = function( expr, set ) {
return Sizzle( expr, null, null, set );
};
Sizzle.find = function(expr, context, isXML){
var set;
Sizzle.matchesSelector = function( node, expr ) {
return Sizzle( expr, null, null, [node] ).length > 0;
};
Sizzle.find = function( expr, context, isXML ) {
var set, i, len, match, type, left;
if ( !expr ) {
return [];
}
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
var type = Expr.order[i], match;
for ( i = 0, len = Expr.order.length; i < len; i++ ) {
type = Expr.order[i];
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
var left = match[1];
match.splice(1,1);
left = match[1];
match.splice( 1, 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 );
if ( set != null ) {
expr = expr.replace( Expr.match[ type ], "" );
break;
@ -7084,20 +7481,29 @@ Sizzle.find = function(expr, context, isXML){
}
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){
var old = expr, result = [], curLoop = set, match, anyFound,
isXMLFilter = set && set[0] && Sizzle.isXML(set[0]);
Sizzle.filter = function( expr, set, inplace, not ) {
var match, anyFound,
type, found, item, filter, left,
i, pass,
old = expr,
result = [],
curLoop = set,
isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
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] ) {
var filter = Expr.filter[ type ], found, item, left = match[1];
filter = Expr.filter[ type ];
left = match[1];
anyFound = false;
match.splice(1,1);
@ -7115,23 +7521,26 @@ Sizzle.filter = function(expr, set, inplace, not){
if ( !match ) {
anyFound = found = true;
} else if ( match === true ) {
continue;
}
}
if ( match ) {
for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
for ( i = 0; (item = curLoop[i]) != null; i++ ) {
if ( item ) {
found = filter( item, match, i, curLoop );
var pass = not ^ !!found;
pass = not ^ found;
if ( inplace && found != null ) {
if ( pass ) {
anyFound = true;
} else {
curLoop[i] = false;
}
} else if ( pass ) {
result.push( item );
anyFound = true;
@ -7160,6 +7569,7 @@ Sizzle.filter = function(expr, set, inplace, not){
if ( expr === old ) {
if ( anyFound == null ) {
Sizzle.error( expr );
} else {
break;
}
@ -7172,35 +7582,78 @@ Sizzle.filter = function(expr, set, inplace, not){
};
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 = {
order: [ "ID", "NAME", "TAG" ],
match: {
ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
CLASS: /\.((?:[\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\*\-]|\\.)+)/,
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*)\))?(?=[^\-]|$)/,
PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
},
leftMatch: {},
attrMap: {
"class": "className",
"for": "htmlFor"
},
attrHandle: {
href: function(elem){
return elem.getAttribute("href");
href: function( elem ) {
return elem.getAttribute( "href" );
},
type: function( elem ) {
return elem.getAttribute( "type" );
}
},
relative: {
"+": function(checkSet, part){
var isPartStr = typeof part === "string",
isTag = isPartStr && !/\W/.test(part),
isTag = isPartStr && !rNonWord.test( part ),
isPartStrNotTag = isPartStr && !isTag;
if ( isTag ) {
@ -7221,23 +7674,29 @@ var Expr = Sizzle.selectors = {
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();
for ( ; i < l; i++ ) {
elem = checkSet[i];
if ( elem ) {
var parent = elem.parentNode;
checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
}
}
} else {
for ( ; i < l; i++ ) {
elem = checkSet[i];
if ( elem ) {
checkSet[i] = isPartStr ?
elem.parentNode :
@ -7250,39 +7709,50 @@ var Expr = Sizzle.selectors = {
}
}
},
"": 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();
nodeCheck = part;
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();
nodeCheck = part;
checkFn = dirNodeCheck;
}
checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
}
},
find: {
ID: function(match, context, isXML){
ID: function( match, context, isXML ) {
if ( typeof context.getElementById !== "undefined" && !isXML ) {
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" ) {
var ret = [], results = context.getElementsByName(match[1]);
var ret = [],
results = context.getElementsByName( match[1] );
for ( var i = 0, l = results.length; i < l; i++ ) {
if ( results[i].getAttribute("name") === match[1] ) {
@ -7293,13 +7763,16 @@ var Expr = Sizzle.selectors = {
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: {
CLASS: function(match, curLoop, inplace, result, not, isXML){
match = " " + match[1].replace(/\\/g, "") + " ";
CLASS: function( match, curLoop, inplace, result, not, isXML ) {
match = " " + match[1].replace( rBackslash, "" ) + " ";
if ( isXML ) {
return match;
@ -7307,10 +7780,11 @@ var Expr = Sizzle.selectors = {
for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
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 ) {
result.push( elem );
}
} else if ( inplace ) {
curLoop[i] = false;
}
@ -7319,16 +7793,25 @@ var Expr = Sizzle.selectors = {
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[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'
var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
!/\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[3] = test[3] - 0;
}
else if ( match[2] ) {
Sizzle.error( match[0] );
}
// TODO: Move to normal caching system
match[0] = done++;
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] ) {
match[1] = Expr.attrMap[name];
}
// Handle if an un-quoted value was used
match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
if ( match[2] === "~=" ) {
match[4] = " " + match[4] + " ";
}
return match;
},
PSEUDO: function(match, curLoop, inplace, result, not){
PSEUDO: function( match, curLoop, inplace, result, not ) {
if ( match[1] === "not" ) {
// If we're dealing with a complex expression, or a simple one
if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
match[3] = Sizzle(match[3], null, null, curLoop);
} else {
var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
if ( !inplace ) {
result.push.apply( result, ret );
}
return false;
}
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
return true;
}
return match;
},
POS: function(match){
POS: function( match ) {
match.unshift( true );
return match;
}
},
filters: {
enabled: function(elem){
enabled: function( elem ) {
return elem.disabled === false && elem.type !== "hidden";
},
disabled: function(elem){
disabled: function( elem ) {
return elem.disabled === true;
},
checked: function(elem){
checked: function( elem ) {
return elem.checked === true;
},
selected: function(elem){
selected: function( elem ) {
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex;
}
return elem.selected === true;
},
parent: function(elem){
parent: function( elem ) {
return !!elem.firstChild;
},
empty: function(elem){
empty: function( elem ) {
return !elem.firstChild;
},
has: function(elem, i, match){
has: function( elem, i, match ) {
return !!Sizzle( match[3], elem ).length;
},
header: function(elem){
header: function( elem ) {
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: {
first: function(elem, i){
first: function( elem, i ) {
return i === 0;
},
last: function(elem, i, match, array){
last: function( elem, i, match, array ) {
return i === array.length - 1;
},
even: function(elem, i){
even: function( elem, i ) {
return i % 2 === 0;
},
odd: function(elem, i){
odd: function( elem, i ) {
return i % 2 === 1;
},
lt: function(elem, i, match){
lt: function( elem, i, match ) {
return i < match[3] - 0;
},
gt: function(elem, i, match){
gt: function( elem, i, match ) {
return i > match[3] - 0;
},
nth: function(elem, i, match){
nth: function( elem, i, match ) {
return match[3] - 0 === i;
},
eq: function(elem, i, match){
eq: function( elem, i, match ) {
return match[3] - 0 === i;
}
},
filter: {
PSEUDO: function(elem, match, i, array){
var name = match[1], filter = Expr.filters[ name ];
PSEUDO: function( elem, match, i, array ) {
var name = match[1],
filter = Expr.filters[ name ];
if ( filter ) {
return filter( elem, i, match, array );
} 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" ) {
var not = match[3];
@ -7481,72 +8019,96 @@ var Expr = Sizzle.selectors = {
}
return true;
} else {
Sizzle.error( "Syntax error, unrecognized expression: " + name );
Sizzle.error( name );
}
},
CHILD: function(elem, match){
var type = match[1], node = elem;
switch (type) {
case 'only':
case 'first':
CHILD: function( elem, match ) {
var first, last,
doneName, parent, cache,
count, diff,
type = match[1],
node = elem;
switch ( type ) {
case "only":
case "first":
while ( (node = node.previousSibling) ) {
if ( node.nodeType === 1 ) {
return false;
}
}
if ( type === "first" ) {
return true;
}
node = elem;
case 'last':
/* falls through */
case "last":
while ( (node = node.nextSibling) ) {
if ( node.nodeType === 1 ) {
return false;
}
}
return true;
case 'nth':
var first = match[2], last = match[3];
case "nth":
first = match[2];
last = match[3];
if ( first === 1 && last === 0 ) {
return true;
}
var doneName = match[0],
doneName = match[0];
parent = elem.parentNode;
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
var count = 0;
if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
count = 0;
for ( node = parent.firstChild; node; node = node.nextSibling ) {
if ( node.nodeType === 1 ) {
node.nodeIndex = ++count;
}
}
parent.sizcache = doneName;
parent[ expando ] = doneName;
}
var diff = elem.nodeIndex - last;
diff = elem.nodeIndex - last;
if ( first === 0 ) {
return diff === 0;
} else {
return ( diff % first === 0 && diff / first >= 0 );
}
}
},
ID: function(elem, match){
ID: function( elem, 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")) + " ")
.indexOf( match ) > -1;
},
ATTR: function(elem, match){
ATTR: function( elem, match ) {
var name = match[1],
result = Expr.attrHandle[ name ] ?
result = Sizzle.attr ?
Sizzle.attr( elem, name ) :
Expr.attrHandle[ name ] ?
Expr.attrHandle[ name ]( elem ) :
elem[ name ] != null ?
elem[ name ] :
@ -7557,6 +8119,8 @@ var Expr = Sizzle.selectors = {
return result == null ?
type === "!=" :
!type && Sizzle.attr ?
result != null :
type === "=" ?
value === check :
type === "*=" ?
@ -7575,8 +8139,10 @@ var Expr = Sizzle.selectors = {
value === check || value.substr(0, check.length + 1) === check + "-" :
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 ) {
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.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 );
if ( results ) {
@ -7614,17 +8183,20 @@ try {
Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
// Provide a fallback method if it does not work
} catch(e){
makeArray = function(array, results) {
var ret = results || [], i = 0;
} catch( e ) {
makeArray = function( array, results ) {
var i = 0,
ret = results || [];
if ( toString.call(array) === "[object Array]" ) {
Array.prototype.push.apply( ret, array );
} else {
if ( typeof array.length === "number" ) {
for ( var l = array.length; i < l; i++ ) {
ret.push( array[i] );
}
} else {
for ( ; array[i]; i++ ) {
ret.push( array[i] );
@ -7636,110 +8208,141 @@ try {
};
}
var sortOrder;
var sortOrder, siblingCheck;
if ( document.documentElement.compareDocumentPosition ) {
sortOrder = function( a, b ) {
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
if ( a == b ) {
if ( a === b ) {
hasDuplicate = true;
return 0;
}
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
return a.compareDocumentPosition ? -1 : 1;
}
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
if ( ret === 0 ) {
hasDuplicate = true;
}
return ret;
return a.compareDocumentPosition(b) & 4 ? -1 : 1;
};
} else if ( "sourceIndex" in document.documentElement ) {
} else {
sortOrder = function( a, b ) {
if ( !a.sourceIndex || !b.sourceIndex ) {
if ( a == b ) {
// The nodes are identical, we can exit early
if ( a === b ) {
hasDuplicate = true;
}
return a.sourceIndex ? -1 : 1;
return 0;
// 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;
if ( ret === 0 ) {
hasDuplicate = true;
}
return ret;
};
} else if ( document.createRange ) {
sortOrder = function( a, b ) {
if ( !a.ownerDocument || !b.ownerDocument ) {
if ( a == b ) {
hasDuplicate = true;
}
return a.ownerDocument ? -1 : 1;
var al, bl,
ap = [],
bp = [],
aup = a.parentNode,
bup = b.parentNode,
cur = aup;
// If the nodes are siblings (or identical) we can do a quick check
if ( aup === bup ) {
return siblingCheck( a, b );
// If no parents were found then the nodes are disconnected
} else if ( !aup ) {
return -1;
} else if ( !bup ) {
return 1;
}
var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
aRange.setStart(a, 0);
aRange.setEnd(a, 0);
bRange.setStart(b, 0);
bRange.setEnd(b, 0);
var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
if ( ret === 0 ) {
hasDuplicate = true;
// Otherwise they're somewhere else in the tree so we need
// to build up a full list of the parentNodes for comparison
while ( cur ) {
ap.unshift( cur );
cur = cur.parentNode;
}
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;
}
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
// querying by getElementById (and provide a workaround)
(function(){
// We're going to inject a fake input element with a specified name
var form = document.createElement("div"),
id = "script" + (new Date()).getTime();
id = "script" + (new Date()).getTime(),
root = document.documentElement;
form.innerHTML = "<a name='" + id + "'/>";
// Inject it into the root element, check its status, and remove it quickly
var root = document.documentElement;
root.insertBefore( form, root.firstChild );
// The workaround has to do additional checks after a getElementById
// Which slows things down for other browsers (hence the branching)
if ( document.getElementById( id ) ) {
Expr.find.ID = function(match, context, isXML){
Expr.find.ID = function( match, context, isXML ) {
if ( typeof context.getElementById !== "undefined" && !isXML ) {
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");
return elem.nodeType === 1 && node && node.nodeValue === match;
};
}
root.removeChild( form );
root = form = null; // release memory in IE
// release memory in IE
root = form = null;
})();
(function(){
@ -7752,8 +8355,8 @@ Sizzle.getText = function( elems ) {
// Make sure no comments are found
if ( div.getElementsByTagName("*").length > 0 ) {
Expr.find.TAG = function(match, context){
var results = context.getElementsByTagName(match[1]);
Expr.find.TAG = function( match, context ) {
var results = context.getElementsByTagName( match[1] );
// Filter out possible comments
if ( match[1] === "*" ) {
@ -7774,19 +8377,25 @@ Sizzle.getText = function( elems ) {
// Check to see if an attribute returns normalized href attributes
div.innerHTML = "<a href='#'></a>";
if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
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 ) {
(function(){
var oldSizzle = Sizzle, div = document.createElement("div");
var oldSizzle = Sizzle,
div = document.createElement("div"),
id = "__sizzle__";
div.innerHTML = "<p class='TEST'></p>";
// Safari can't handle uppercase or unicode characters when
@ -7795,15 +8404,86 @@ if ( document.querySelectorAll ) {
return;
}
Sizzle = function(query, context, extra, seed){
Sizzle = function( query, context, extra, seed ) {
context = context || document;
// Only use querySelectorAll on non-XML 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 {
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);
@ -7813,10 +8493,55 @@ if ( document.querySelectorAll ) {
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(){
var div = document.createElement("div");
@ -7836,30 +8561,33 @@ if ( document.querySelectorAll ) {
}
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 ) {
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 ) {
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i];
if ( elem ) {
elem = elem[dir];
var match = false;
elem = elem[dir];
while ( elem ) {
if ( elem.sizcache === doneName ) {
if ( elem[ expando ] === doneName ) {
match = checkSet[elem.sizset];
break;
}
if ( elem.nodeType === 1 && !isXML ){
elem.sizcache = doneName;
elem[ expando ] = doneName;
elem.sizset = i;
}
@ -7879,21 +8607,24 @@ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
var elem = checkSet[i];
if ( elem ) {
elem = elem[dir];
var match = false;
elem = elem[dir];
while ( elem ) {
if ( elem.sizcache === doneName ) {
if ( elem[ expando ] === doneName ) {
match = checkSet[elem.sizset];
break;
}
if ( elem.nodeType === 1 ) {
if ( !isXML ) {
elem.sizcache = doneName;
elem[ expando ] = doneName;
elem.sizset = i;
}
if ( typeof cur !== "string" ) {
if ( elem === cur ) {
match = true;
@ -7914,21 +8645,34 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
}
}
Sizzle.contains = document.compareDocumentPosition ? function(a, b){
return !!(a.compareDocumentPosition(b) & 16);
} : function(a, b){
if ( document.documentElement.contains ) {
Sizzle.contains = function( a, b ) {
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
// (such as loading iframes in IE - #4833)
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
return documentElement ? documentElement.nodeName !== "HTML" : false;
};
var posProcess = function(selector, context){
var tmpSet = [], later = "", match,
var posProcess = function( selector, context, seed ) {
var match,
tmpSet = [],
later = "",
root = context.nodeType ? [context] : context;
// Position selectors must be done after the filter
@ -7941,7 +8685,7 @@ var posProcess = function(selector, context){
selector = Expr.relative[selector] ? selector + "*" : selector;
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 );
@ -7970,8 +8714,7 @@ window.tinymce.dom.Sizzle = Sizzle;
('getPos,getRect,getParent,add,setStyle,getStyle,setStyles,' +
'setAttrib,setAttribs,getAttrib,addClass,removeClass,' +
'hasClass,getOuterHTML,setOuterHTML,remove,show,hide,' +
'isHidden,setHTML,get').split(/,/)
, function(k) {
'isHidden,setHTML,get').split(/,/), function(k) {
t[k] = function() {
var a = [id], i;
@ -7983,7 +8726,8 @@ window.tinymce.dom.Sizzle = Sizzle;
return a;
};
});
}
);
tinymce.extend(t, {
on : function(n, f, s) {
@ -8069,7 +8813,7 @@ window.tinymce.dom.Sizzle = Sizzle;
};
// 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', {
Selection : function(dom, win, serializer) {
@ -8176,7 +8920,7 @@ window.tinymce.dom.Sizzle = Sizzle;
} else {
rng.deleteContents();
if (doc.body.childNodes.length == 0) {
if (doc.body.childNodes.length === 0) {
doc.body.innerHTML = content;
} else {
// createContextualFragment doesn't exists in IE 9 DOMRanges
@ -8312,7 +9056,29 @@ window.tinymce.dom.Sizzle = Sizzle;
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() {
var rng = t.getRng(true), root = dom.getRoot(), bookmark = {};
@ -8352,6 +9118,7 @@ window.tinymce.dom.Sizzle = Sizzle;
return bookmark;
};
if (type == 2) {
if (t.tridentSel)
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>
rng.moveToElementText(rng2.parentElement());
if (rng.compareEndPoints('StartToEnd', rng2) == 0)
if (rng.compareEndPoints('StartToEnd', rng2) === 0)
rng2.move('character', -1);
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')
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
rng2 = rng.cloneRange();
rng2 = normalizeTableCellSelection(rng.cloneRange());
// Insert end marker
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));
}
rng = normalizeTableCellSelection(rng);
rng.collapse(true);
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) {
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) {
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
@ -8471,13 +9229,6 @@ window.tinymce.dom.Sizzle = Sizzle;
return true;
};
if (t.tridentSel)
return t.tridentSel.moveToBookmark(bookmark);
if (setEndPoint(true) && setEndPoint()) {
t.setRng(rng);
}
} else if (bookmark.id) {
function restoreEndPoint(suffix) {
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) {
// Adds a bogus BR element for empty block elements or just a space on IE since it renders BR elements incorrectly
if (dom.isBlock(node) && !node.innerHTML)
node.innerHTML = !isIE ? '<br data-mce-bogus="1" />' : ' ';
// Adds a bogus BR element for empty block elements
if (dom.isBlock(node) && !node.innerHTML && !isIE)
node.innerHTML = '<br data-mce-bogus="1" />';
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
restoreEndPoint('start');
restoreEndPoint('end');
@ -8568,19 +9331,12 @@ window.tinymce.dom.Sizzle = Sizzle;
select : function(node, content) {
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) {
var walker = new tinymce.dom.TreeWalker(node, node);
var walker = new TreeWalker(node, node);
do {
// Text node
if (node.nodeType == 3 && tinymce.trim(node.nodeValue).length != 0) {
if (node.nodeType == 3 && tinymce.trim(node.nodeValue).length !== 0) {
if (start)
rng.setStart(node, 0);
else
@ -8601,6 +9357,13 @@ window.tinymce.dom.Sizzle = Sizzle;
} 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);
}
@ -8644,48 +9407,58 @@ window.tinymce.dom.Sizzle = Sizzle;
},
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
if (w3c && t.tridentSel)
return t.tridentSel.getRangeAt(0);
if (w3c && self.tridentSel) {
return self.tridentSel.getRangeAt(0);
}
try {
if (s = t.getSel())
r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : doc.createRange());
if (selection = self.getSel()) {
rng = selection.rangeCount > 0 ? selection.getRangeAt(0) : (selection.createRange ? selection.createRange() : doc.createRange());
}
} catch (ex) {
// 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
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);
r = doc.createRange();
r.setStartBefore(elm);
r.setEndAfter(elm);
rng = doc.createRange();
rng.setStartBefore(elm);
rng.setEndAfter(elm);
}
// No range found then create an empty one
// This can occur when the editor is placed in a hidden container element on Gecko
// Or on IE when there was an exception
if (!r)
r = doc.createRange ? doc.createRange() : doc.body.createTextRange();
if (!rng) {
rng = doc.createRange ? doc.createRange() : doc.body.createTextRange();
}
if (t.selectedRange && t.explicitRange) {
if (r.compareBoundaryPoints(r.START_TO_START, t.selectedRange) === 0 && r.compareBoundaryPoints(r.END_TO_END, t.selectedRange) === 0) {
// If range is at start of document then move it to start of body
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.
// 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 {
t.selectedRange = null;
t.explicitRange = null;
self.selectedRange = null;
self.explicitRange = null;
}
}
return r;
return rng;
},
setRng : function(r) {
setRng : function(r, forward) {
var s, t = this;
if (!t.tridentSel) {
@ -8701,6 +9474,13 @@ window.tinymce.dom.Sizzle = Sizzle;
}
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
t.selectedRange = s.rangeCount > 0 ? s.getRangeAt(0) : null;
}
@ -8735,6 +9515,14 @@ window.tinymce.dom.Sizzle = Sizzle;
getNode : function() {
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
if (!rng)
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.
// This happens when you double click an underlined word in FireFox.
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) {
start = skipEmptyTextNodes(start.nextSibling, true);
} else {
@ -8802,7 +9583,7 @@ window.tinymce.dom.Sizzle = Sizzle;
if (sb && eb && sb != eb) {
n = sb;
var walker = new tinymce.dom.TreeWalker(sb, dom.getRoot());
var walker = new TreeWalker(sb, dom.getRoot());
while ((n = walker.next()) && n != eb) {
if (dom.isBlock(n))
bl.push(n);
@ -8815,54 +9596,120 @@ window.tinymce.dom.Sizzle = Sizzle;
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() {
var self = this, rng, normalized;
// 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;
var self = this, rng, normalized, collapsed, node, sibling;
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'];
offset = rng[(start ? 'start' : 'end') + 'Offset'];
nonEmptyElementsMap = dom.schema.getNonEmptyElements();
// If the container is a document move it to the body element
if (container.nodeType === 9) {
container = container.body;
container = dom.getRoot();
offset = 0;
}
// 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 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
if (container.hasChildNodes()) {
container = container.childNodes[Math.min(!start && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1)];
offset = 0;
// 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
node = container;
walker = new tinymce.dom.TreeWalker(container, body);
walker = new TreeWalker(container, body);
do {
// Found a text node use that position
if (node.nodeType === 3) {
offset = start ? 0 : node.nodeValue.length - 1;
if (node.nodeType === 3 && node.nodeValue.length > 0) {
offset = start ? 0 : node.nodeValue.length;
container = node;
normalized = true;
break;
}
// 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);
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
if (normalized)
rng['set' + (start ? 'Start' : 'End')](container, offset);
};
// Normalize only on non IE browsers for now
if (tinymce.isIE)
return;
rng = self.getRng();
collapsed = rng.collapsed;
// Normalize the end points
normalizeEndPoint(true);
if (!rng.collapsed)
if (!collapsed)
normalizeEndPoint();
// Set the selection if it was normalized
if (normalized) {
// If it was collapsed then make sure it still is
if (collapsed) {
rng.collapse(true);
}
//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() {
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
function rngFromPoint(x, y) {
var rng = body.createTextRange();
@ -8965,6 +9847,9 @@ window.tinymce.dom.Sizzle = Sizzle;
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
dom.bind(doc, ['mousedown', 'contextmenu'], function(e) {
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) {
var i = nodes.length, node, value;
while (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);
}
});
@ -9223,7 +10108,7 @@ window.tinymce.dom.Sizzle = Sizzle;
// Parse and serialize HTML
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
@ -9263,7 +10148,7 @@ window.tinymce.dom.Sizzle = Sizzle;
scriptLoadedCallbacks = {},
queueLoadedCallbacks = [],
loading = 0,
undefined;
undef;
function loadScript(url, callback) {
var t = this, dom = tinymce.DOM, elm, uri, loc, id;
@ -9372,7 +10257,7 @@ window.tinymce.dom.Sizzle = Sizzle;
var item, state = states[url];
// Add url to load queue
if (state == undefined) {
if (state == undef) {
queue.push(url);
states[url] = QUEUED;
}
@ -9402,7 +10287,7 @@ window.tinymce.dom.Sizzle = Sizzle;
callback.func.call(callback.scope);
});
scriptLoadedCallbacks[url] = undefined;
scriptLoadedCallbacks[url] = undef;
};
queueLoadedCallbacks.push({
@ -9459,46 +10344,6 @@ window.tinymce.dom.Sizzle = Sizzle;
tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();
})(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) {
tinymce.dom.RangeUtils = function(dom) {
var INVISIBLE_CHAR = '\uFEFF';
@ -10159,8 +11004,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
update : function() {
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;
th = s.max_height ? Math.min(tb.clientHeight, s.max_height) : tb.clientHeight;
tw = s.max_width ? Math.min(tb.offsetWidth, s.max_width) : tb.offsetWidth;
th = s.max_height ? Math.min(tb.offsetHeight, s.max_height) : tb.offsetHeight;
if (!DOM.boxModel)
t.element.setStyles({width : tw + 2, height : th + 2});
@ -10519,7 +11364,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
})(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', {
ListBox : function(id, s, ed) {
@ -10546,7 +11391,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
t.marked = {};
if (va == undefined)
if (va == undef)
return t.selectByIndex(-1);
// Is string or number make function selector
@ -10638,7 +11483,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
showMenu : function() {
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;
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', {
menu_line : 1,
'class' : t.classPrefix + 'Menu mceNoIcons',
max_width : 150,
max_width : 250,
max_height : 150
});
@ -10725,7 +11570,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
each(t.items, function(o) {
// No value then treat it as a title
if (o.value === undefined) {
if (o.value === undef) {
m.add({
title : o.title,
role : "option",
@ -10815,7 +11660,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
})(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', {
NativeListBox : function(id, s) {
@ -10835,7 +11680,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
select : function(va) {
var t = this, fv, f;
if (va == undefined)
if (va == undef)
return t.selectByIndex(-1);
// 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_y = p2.y;
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);
t.setState('Selected', 1);
@ -11172,7 +12017,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
p2 = DOM.getPos(e);
DOM.setStyles(t.id + '_menu', {
left : p2.x,
top : p2.y + e.clientHeight,
top : p2.y + e.firstChild.clientHeight,
zIndex : 200000
});
e = 0;
@ -11215,7 +12060,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
renderMenu : function() {
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'});
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.
if (!tinymce.isIE ) {
settings['role']= 'option';
settings.role = 'option';
}
n = DOM.add(n, 'a', settings);
@ -11540,7 +12385,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
if (typeof u === "object")
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;
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,
ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
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
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));
};
function hasClass(n, c) {
return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c);
};
s = extend({
theme : "simple",
language : "en"
@ -11677,10 +12526,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
case "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) {
if (s.editor_deselector && hasClass(elm, s.editor_deselector))
return;
@ -11741,7 +12586,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
},
get : function(id) {
if (id === undefined)
if (id === undef)
return this.editors;
return this.editors[id];
@ -11794,6 +12639,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
execCommand : function(c, u, v) {
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
switch (c) {
case "mceFocus":
@ -11822,12 +12673,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Fix IE memory leaks
if (tinymce.isIE) {
function clr() {
ed.destroy();
w.detachEvent('onunload', clr);
w = w.tinyMCE = w.tinymce = null; // IE leak
};
w.attachEvent('onunload', clr);
}
@ -11910,108 +12755,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
(function(tinymce) {
// Shorten these names
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,
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', {
Editor : function(id, s) {
var t = this;
Editor : function(id, settings) {
var self = this, TRUE = true;
t.id = t.editorId = id;
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({
self.settings = settings = extend({
id : id,
language : 'en',
docs_language : 'en',
theme : 'simple',
skin : 'default',
delta_width : 0,
@ -12019,58 +12774,63 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
popup_css : '',
plugins : '',
document_base_url : tinymce.documentBaseURL,
add_form_submit_trigger : 1,
submit_patch : 1,
add_unload_trigger : 1,
convert_urls : 1,
relative_urls : 1,
remove_script_host : 1,
table_inline_editing : 0,
object_resizing : 1,
cleanup : 1,
accessibility_focus : 1,
custom_shortcuts : 1,
custom_undo_redo_keyboard_shortcuts : 1,
custom_undo_redo_restore_selection : 1,
custom_undo_redo : 1,
add_form_submit_trigger : TRUE,
submit_patch : TRUE,
add_unload_trigger : TRUE,
convert_urls : TRUE,
relative_urls : TRUE,
remove_script_host : TRUE,
table_inline_editing : false,
object_resizing : TRUE,
accessibility_focus : TRUE,
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 : 1,
visual : TRUE,
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
apply_source_formatting : 1,
apply_source_formatting : TRUE,
directionality : 'ltr',
forced_root_block : 'p',
hidden_input : 1,
padd_empty_editor : 1,
render_ui : 1,
init_theme : 1,
force_p_newlines : 1,
hidden_input : TRUE,
padd_empty_editor : TRUE,
render_ui : TRUE,
indentation : '30px',
keep_styles : 1,
fix_table_elements : 1,
inline_styles : 1,
convert_fonts_to_spans : true,
fix_table_elements : TRUE,
inline_styles : TRUE,
convert_fonts_to_spans : TRUE,
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_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',
validate : true,
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,figure',
validate : TRUE,
entity_encoding : 'named',
url_converter : t.convertURL,
url_converter_scope : t,
ie7_compat : true
}, s);
url_converter : self.convertURL,
url_converter_scope : self,
ie7_compat : TRUE
}, 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
});
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
t.execCallback('setup', t);
self.execCallback('setup', self);
},
render : function(nst) {
@ -12091,8 +12851,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
return;
// 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
// caret We will remove this check ones Apple implements full contentEditable support
// here since the browser says it has contentEditable support but there is no visible caret.
if (tinymce.isIDevice && !tinymce.isIOS5)
return;
@ -12171,9 +12930,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
var dependencies = PluginManager.dependencies(p);
each(dependencies, function(dep) {
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);
});
} else {
// 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);
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(/\/$/, ''));
}
function initPlugin(p) {
@ -12243,51 +13001,27 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
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) {
// Don't refresh the select lists until caret move
if (!/^(FontName|FontSize)$/.test(c))
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
t.onBeforeRenderUI.dispatch(t, t.controlManager);
// Measure box
if (s.render_ui) {
if (s.render_ui && t.theme) {
w = s.width || e.style.width || e.offsetWidth;
h = s.height || e.style.height || e.offsetHeight;
t.orgDisplay = e.style.display;
re = /^[0-9\.]+(|px)$/i;
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))
h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);
h = Math.max(parseInt(h, 10) + (o.deltaHeight || 0), 100);
// Render UI
o = t.theme.renderUI({
@ -12301,6 +13035,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
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
if (document.domain && location.hostname != document.domain)
@ -12312,13 +13058,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
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) : '');
if (h < 100)
h = 100;
@ -12362,7 +13101,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Domain relaxing enabled, then set document domain
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
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
@ -12386,73 +13125,61 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
DOM.setAttrib(t.id, 'aria-hidden', true);
if (!tinymce.relaxedDomain || !u)
t.setupIframe();
t.initContentBody();
e = n = o = null; // Cleanup
},
setupIframe : function() {
var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;
initContentBody : function() {
var self = this, settings = self.settings, targetElm = DOM.get(self.id), doc = self.getDoc(), html, body;
// Setup iframe body
if (!isIE || !tinymce.relaxedDomain) {
d.open();
d.write(t.iframeHTML);
d.close();
if ((!isIE || !tinymce.relaxedDomain) && !settings.content_editable) {
doc.open();
doc.write(self.iframeHTML);
doc.close();
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
b = t.getBody();
b.disabled = true;
body = self.getBody();
body.disabled = true;
if (!s.readonly)
b.contentEditable = true;
if (!settings.readonly)
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,
url_converter : t.convertURL,
url_converter_scope : t,
hex_colors : s.force_hex_style_colors,
class_filter : s.class_filter,
update_styles : 1,
fix_ie_paragraphs : 1,
schema : t.schema
url_converter : self.convertURL,
url_converter_scope : self,
hex_colors : settings.force_hex_style_colors,
class_filter : settings.class_filter,
update_styles : true,
root_element : settings.content_editable ? self.id : null,
schema : self.schema
});
t.parser = new tinymce.html.DomParser(s, t.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);
}
}
});
}
self.parser = new tinymce.html.DomParser(settings, self.schema);
// Convert src and href into data-mce-src, data-mce-href and data-mce-style
t.parser.addAttributeFilter('src,href,style', function(nodes, name) {
var i = nodes.length, node, dom = t.dom, value, internalName;
self.parser.addAttributeFilter('src,href,style', function(nodes, name) {
var i = nodes.length, node, dom = self.dom, value, internalName;
while (i--) {
node = nodes[i];
@ -12464,13 +13191,13 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
if (name === "style")
node.attr(internalName, dom.serializeStyle(dom.parseStyle(value), node.name));
else
node.attr(internalName, t.convertURL(value, name, node.name));
node.attr(internalName, self.convertURL(value, name, node.name));
}
}
});
// Keep scripts from executing
t.parser.addNodeFilter('script', function(nodes, name) {
self.parser.addNodeFilter('script', function(nodes, name) {
var i = nodes.length, node;
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;
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) {
var i = nodes.length, node, nonEmptyElements = t.schema.getNonEmptyElements();
self.parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function(nodes, name) {
var i = nodes.length, node, nonEmptyElements = self.schema.getNonEmptyElements();
while (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
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'}}
],
self.undoManager = new tinymce.UndoManager(self);
aligncenter : [
{selector : '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 : '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);
self.forceBlocks = new tinymce.ForceBlocks(self);
self.enterKey = new tinymce.EnterKey(self);
self.editorCommands = new tinymce.EditorCommands(self);
// Pass through
t.undoManager.onAdd.add(function(um, l) {
if (um.hasUndo())
return t.onChange.dispatch(t, l, um);
self.serializer.onPreProcess.add(function(se, o) {
return self.onPreProcess.dispatch(self, o, se);
});
t.undoManager.onUndo.add(function(um, l) {
return t.onUndo.dispatch(t, l, um);
self.serializer.onPostProcess.add(function(se, o) {
return self.onPostProcess.dispatch(self, o, se);
});
t.undoManager.onRedo.add(function(um, l) {
return t.onRedo.dispatch(t, l, um);
});
self.onPreInit.dispatch(self);
t.forceBlocks = new tinymce.ForceBlocks(t);
t.enterKey = new tinymce.EnterKey(t);
if (!settings.gecko_spellcheck)
doc.body.spellcheck = false;
t.editorCommands = new tinymce.EditorCommands(t);
// 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 (!settings.readonly) {
self.bindNativeEvents();
}
if (s.save_callback) {
t.onSaveContent.add(function(ed, o) {
var h = t.execCallback('save_callback', t.id, o.content, t.getBody());
self.controlManager.onPostRender.dispatch(self, self.controlManager);
self.onPostRender.dispatch(self);
if (h)
o.content = h;
});
}
self.quirks = tinymce.util.Quirks(self);
if (s.onchange_callback) {
t.onChange.add(function(ed, l) {
t.execCallback('onchange_callback', t, l);
});
}
if (settings.directionality)
body.dir = settings.directionality;
if (s.protect) {
t.onBeforeSetContent.add(function(ed, o) {
if (s.protect) {
each(s.protect, function(pattern) {
if (settings.nowrap)
body.style.whiteSpace = "nowrap";
if (settings.protect) {
self.onBeforeSetContent.add(function(ed, o) {
each(settings.protect, function(pattern) {
o.content = o.content.replace(pattern, function(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
t.onSetContent.add(function() {
t.addVisual(t.getBody());
self.onSetContent.add(function() {
self.addVisual(self.getBody());
});
// Remove empty contents
if (s.padd_empty_editor) {
t.onPostProcess.add(function(ed, o) {
if (settings.padd_empty_editor) {
self.onPostProcess.add(function(ed, o) {
o.content = o.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');
});
}
if (isGecko) {
// Fix gecko link bug, when a link is placed at the end of block elements there is
// 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;
self.load({initial : true, format : 'html'});
self.startContent = self.getContent({format : 'raw'});
if (ed.dom.isBlock(pn) && pn.lastChild === n)
ed.dom.add(pn, 'br', {'data-mce-bogus' : 1});
});
};
self.initialized = true;
t.onExecCommand.add(function(ed, cmd) {
if (cmd === 'CreateLink')
fixLinks(ed);
});
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});
self.onInit.dispatch(self);
self.execCallback('setupcontent_callback', self.id, body, doc);
self.execCallback('init_instance_callback', self);
self.focus(true);
self.nodeChanged({initial : true});
// Load specified content CSS last
each(t.contentCSS, function(u) {
t.dom.loadCSS(u);
each(self.contentCSS, function(url) {
self.dom.loadCSS(url);
});
// Handle auto focus
if (s.auto_focus) {
if (settings.auto_focus) {
setTimeout(function () {
var ed = tinymce.get(s.auto_focus);
var ed = tinymce.get(settings.auto_focus);
ed.selection.select(ed.getBody(), 1);
ed.selection.collapse(1);
@ -12809,29 +13319,41 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}, 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) {
var oed, t = this, selection = t.selection, ce = t.settings.content_editable, ieRng, controlElm, doc = t.getDoc();
if (!sf) {
if (!skip_focus) {
// Get selected control element
ieRng = selection.getRng();
if (ieRng.item) {
controlElm = ieRng.item(0);
}
t._refreshContentEditable();
self._refreshContentEditable();
// Is not content editable
if (!ce)
t.getWin().focus();
// Focus the window iframe
if (!contentEditable) {
self.getWin().focus();
}
// Focus the body as well since it's contentEditable
if (tinymce.isGecko) {
t.getBody().focus();
if (tinymce.isGecko || contentEditable) {
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
@ -12842,17 +13364,16 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
ieRng.addElement(controlElm);
ieRng.select();
}
}
if (tinymce.activeEditor != t) {
if (tinymce.activeEditor != self) {
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) {
@ -12884,7 +13405,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
if (!s)
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 + '}';
});
},
@ -12918,37 +13439,40 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
},
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
if (t.initialized) {
if (self.initialized) {
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
o.parents = [];
t.dom.getParent(n, function(node) {
self.dom.getParent(node, function(node) {
if (node.nodeName == 'BODY')
return true;
o.parents.push(node);
});
t.onNodeChange.dispatch(
t,
o ? o.controlManager || t.controlManager : t.controlManager,
n,
s.isCollapsed(),
self.onNodeChange.dispatch(
self,
o ? o.controlManager || self.controlManager : self.controlManager,
node,
selection.isCollapsed(),
o
);
}
},
addButton : function(n, s) {
var t = this;
addButton : function(name, settings) {
var self = this;
t.buttons = t.buttons || {};
t.buttons[n] = s;
self.buttons = self.buttons || {};
self.buttons[name] = settings;
},
addCommand : function(name, callback, scope) {
@ -12966,7 +13490,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
addShortcut : function(pa, desc, cmd_func, sc) {
var t = this, c;
if (!t.settings.custom_shortcuts)
if (t.settings.custom_shortcuts === false)
return false;
t.shortcuts = t.shortcuts || {};
@ -12991,7 +13515,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
var o = {
func : cmd_func,
scope : sc || this,
desc : desc,
desc : t.translate(desc),
alt : false,
ctrl : false,
shift : false
@ -13133,24 +13657,24 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
},
show : function() {
var t = this;
var self = this;
DOM.show(t.getContainer());
DOM.hide(t.id);
t.load();
DOM.show(self.getContainer());
DOM.hide(self.id);
self.load();
},
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
if (isIE && d)
d.execCommand('SelectAll');
if (isIE && doc)
doc.execCommand('SelectAll');
// We must save before we hide so Safari doesn't crash
t.save();
DOM.hide(t.getContainer());
DOM.setStyle(t.id, 'display', t.orgDisplay);
self.save();
DOM.hide(self.getContainer());
DOM.setStyle(self.id, 'display', self.orgDisplay);
},
isHidden : function() {
@ -13192,12 +13716,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
o = o || {};
o.save = true;
// Add undo level will trigger onchange event
if (!o.no_events) {
t.undoManager.typing = false;
t.undoManager.add();
}
o.element = e;
h = o.content = t.getContent(o);
@ -13283,6 +13801,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
args = args || {};
args.format = args.format || 'html';
args.get = true;
args.getInner = true;
// Do preprocessing
if (!args.no_events)
@ -13310,12 +13829,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
},
getContainer : function() {
var t = this;
var self = this;
if (!t.container)
t.container = DOM.get(t.editorContainer || t.id + '_parent');
if (!self.container)
self.container = DOM.get(self.editorContainer || self.id + '_parent');
return t.container;
return self.container;
},
getContentAreaContainer : function() {
@ -13327,125 +13846,125 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
},
getWin : function() {
var t = this, e;
var self = this, elm;
if (!t.contentWindow) {
e = DOM.get(t.id + "_ifr");
if (!self.contentWindow) {
elm = DOM.get(self.id + "_ifr");
if (e)
t.contentWindow = e.contentWindow;
if (elm)
self.contentWindow = elm.contentWindow;
}
return t.contentWindow;
return self.contentWindow;
},
getDoc : function() {
var t = this, w;
var self = this, win;
if (!t.contentDocument) {
w = t.getWin();
if (!self.contentDocument) {
win = self.getWin();
if (w)
t.contentDocument = w.document;
if (win)
self.contentDocument = win.document;
}
return t.contentDocument;
return self.contentDocument;
},
getBody : function() {
return this.bodyElement || this.getDoc().body;
},
convertURL : function(u, n, e) {
var t = this, s = t.settings;
convertURL : function(url, name, elm) {
var self = this, settings = self.settings;
// Use callback instead
if (s.urlconverter_callback)
return t.execCallback('urlconverter_callback', u, e, true, n);
if (settings.urlconverter_callback)
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
if (!s.convert_urls || (e && e.nodeName == 'LINK') || u.indexOf('file:') === 0)
return u;
if (!settings.convert_urls || (elm && elm.nodeName == 'LINK') || url.indexOf('file:') === 0)
return url;
// Convert to relative
if (s.relative_urls)
return t.documentBaseURI.toRelative(u);
if (settings.relative_urls)
return self.documentBaseURI.toRelative(url);
// 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) {
var t = this, s = t.settings;
addVisual : function(elm) {
var self = this, settings = self.settings, dom = self.dom, cls;
e = e || t.getBody();
elm = elm || self.getBody();
if (!is(t.hasVisual))
t.hasVisual = s.visual;
if (!is(self.hasVisual))
self.hasVisual = settings.visual;
each(t.dom.select('table,a', e), function(e) {
var v;
each(dom.select('table,a', elm), function(elm) {
var value;
switch (e.nodeName) {
switch (elm.nodeName) {
case 'TABLE':
v = t.dom.getAttrib(e, 'border');
cls = settings.visual_table_class || 'mceItemTable';
value = dom.getAttrib(elm, 'border');
if (!v || v == '0') {
if (t.hasVisual)
t.dom.addClass(e, s.visual_table_class);
if (!value || value == '0') {
if (self.hasVisual)
dom.addClass(elm, cls);
else
t.dom.removeClass(e, s.visual_table_class);
dom.removeClass(elm, cls);
}
return;
case 'A':
v = t.dom.getAttrib(e, 'name');
value = dom.getAttrib(elm, 'name');
cls = 'mceItemAnchor';
if (v) {
if (t.hasVisual)
t.dom.addClass(e, 'mceItemAnchor');
if (value) {
if (self.hasVisual)
dom.addClass(elm, cls);
else
t.dom.removeClass(e, 'mceItemAnchor');
dom.removeClass(elm, cls);
}
return;
}
});
t.onVisualAid.dispatch(t, e, t.hasVisual);
self.onVisualAid.dispatch(self, elm, self.hasVisual);
},
remove : function() {
var t = this, e = t.getContainer();
var self = this, elm = self.getContainer();
if (!t.removed) {
t.removed = 1; // Cancels post remove event execution
t.hide();
// Remove all events
if (!self.removed) {
self.removed = 1; // Cancels post remove event execution
self.hide();
// Don't clear the window or document if content editable
// is enabled since other instances might still be present
if (!t.settings.content_editable) {
Event.clear(t.getWin());
Event.clear(t.getDoc());
if (!self.settings.content_editable) {
Event.clear(self.getWin());
Event.clear(self.getDoc());
}
Event.clear(t.getBody());
Event.clear(t.formElement);
Event.unbind(e);
Event.clear(self.getBody());
Event.clear(self.formElement);
Event.unbind(elm);
t.execCallback('remove_instance_callback', t);
t.onRemove.dispatch(t);
self.execCallback('remove_instance_callback', self);
self.onRemove.dispatch(self);
// 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);
DOM.remove(e);
tinymce.remove(self);
DOM.remove(elm);
}
},
@ -13492,343 +14011,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// 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() {
var self = this, body, parent;
@ -13852,14 +14034,294 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Weird, wheres that cursor selection?
s = this.selection.getSel();
return (!s || !s.rangeCount || s.rangeCount == 0);
return (!s || !s.rangeCount || s.rangeCount === 0);
}
});
})(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) {
// 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) {
var dom = editor.dom,
@ -13922,10 +14384,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Private methods
function execNativeCommand(command, ui, value) {
if (ui === undefined)
if (ui === undef)
ui = FALSE;
if (value === undefined)
if (value === undef)
value = null;
return editor.getDoc().execCommand(command, ui, value);
@ -13936,7 +14398,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
};
function toggleFormat(name, value) {
formatter.toggle(name, value ? {value : value} : undefined);
formatter.toggle(name, value ? {value : value} : undef);
};
function storeSelection(type) {
@ -14336,9 +14798,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
// Override justify commands
'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull' : function(command) {
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
// 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 nodes = selection.isCollapsed() ? [dom.getParent(selection.getNode(), dom.isBlock)] : selection.getSelectedBlocks();
var matches = tinymce.map(nodes, function(node) {
return !!formatter.matchNode(node, name);
});
@ -14389,7 +14849,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
}, 'value');
// Add undo manager logic
if (settings.custom_undo_redo) {
addCommands({
Undo : function() {
editor.undoManager.undo();
@ -14399,7 +14858,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
editor.undoManager.redo();
}
});
}
};
})(tinymce);
@ -14407,21 +14865,116 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
var Dispatcher = tinymce.util.Dispatcher;
tinymce.UndoManager = function(editor) {
var self, index = 0, data = [], beforeBookmark;
var self, index = 0, data = [], beforeBookmark, onAdd, onUndo, onRedo;
function getContent() {
// 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 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,
onAdd : new Dispatcher(self),
onAdd : onAdd,
onUndo : new Dispatcher(self),
onUndo : onUndo,
onRedo : new Dispatcher(self),
onRedo : onRedo,
beforeChange : function() {
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 self;
};
})(tinymce);
tinymce.ForceBlocks = function(editor) {
var settings = editor.settings, dom = editor.dom, selection = editor.selection, blockElements = editor.schema.getBlockElements();
// Force root blocks
if (settings.forced_root_block) {
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)
return;
// Check if node is wrapped in block
while (node != rootNode) {
while (node && node != rootNode) {
if (blockElements[node.nodeName])
return;
@ -14567,11 +15120,13 @@ tinymce.ForceBlocks = function(editor) {
}
// 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 (!rootBlockNode) {
rootBlockNode = dom.create(settings.forced_root_block);
node.parentNode.insertBefore(rootBlockNode, node);
wrapped = true;
}
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();
}
};
// Force root blocks
if (settings.forced_root_block) {
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'))
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;
cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu;
c = t.controls[id] = new cls(id, s);
@ -15121,20 +15683,8 @@ tinymce.ForceBlocks = function(editor) {
MCE_ATTR_RE = /^(src|href|style)$/,
FALSE = false,
TRUE = true,
undefined;
// 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;
};
undef,
getContentEditable = dom.getContentEditable;
function isArray(obj) {
return obj instanceof Array;
@ -15148,6 +15698,103 @@ tinymce.ForceBlocks = function(editor) {
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
function get(name) {
@ -15167,15 +15814,15 @@ tinymce.ForceBlocks = function(editor) {
each(format, function(format) {
// Set deep to false by default on selector formats this to avoid removing
// alignment on images inside paragraphs when alignment is changed on paragraphs
if (format.deep === undefined)
if (format.deep === undef)
format.deep = !format.selector;
// Default to true
if (format.split === undefined)
if (format.split === undef)
format.split = !format.selector || format.inline;
// Default to true
if (format.remove === undefined && format.selector && !format.inline)
if (format.remove === undef && format.selector && !format.inline)
format.remove = 'none';
// Mark format as a mixed format inline + block level
@ -15248,7 +15895,7 @@ tinymce.ForceBlocks = function(editor) {
function findSelectionEnd(start, end) {
var walker = new TreeWalker(end);
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;
}
}
@ -15260,7 +15907,7 @@ tinymce.ForceBlocks = function(editor) {
var start = rng.startContainer;
var end = rng.endContainer;
if (start != end && rng.endOffset == 0) {
if (start != end && rng.endOffset === 0) {
var newEnd = findSelectionEnd(start, end);
var endOffset = newEnd.nodeType == 3 ? newEnd.length : newEnd.childNodes.length;
@ -15720,7 +16367,7 @@ tinymce.ForceBlocks = function(editor) {
};
function removeRngStyle(rng) {
var startContainer, endContainer;
var startContainer, endContainer, node;
rng = expandRng(rng, formatList, TRUE);
@ -15729,6 +16376,12 @@ tinymce.ForceBlocks = function(editor) {
endContainer = getContainer(rng);
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
startContainer = wrap(startContainer, 'span', {id : '_start', 'data-mce-type' : 'bookmark'});
endContainer = wrap(endContainer, 'span', {id : '_end', 'data-mce-type' : 'bookmark'});
@ -15790,20 +16443,12 @@ tinymce.ForceBlocks = function(editor) {
ed.nodeChanged();
} else
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) {
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);
else
apply(name, vars, node);
@ -15823,7 +16468,7 @@ tinymce.ForceBlocks = function(editor) {
// Check all items
if (items) {
// Non indexed object
if (items.length === undefined) {
if (items.length === undef) {
for (key in items) {
if (items.hasOwnProperty(key)) {
if (item_name === 'attributes')
@ -15961,6 +16606,10 @@ tinymce.ForceBlocks = function(editor) {
canApply : canApply
});
// Initialize
defaultFormats();
addKeyboardShortcuts();
// Private functions
function matchName(node, format) {
@ -16027,15 +16676,15 @@ tinymce.ForceBlocks = function(editor) {
};
function expandRng(rng, format, remove) {
var sibling, lastIdx, leaf,
var sibling, lastIdx, leaf, endPoint,
startContainer = rng.startContainer,
startOffset = rng.startOffset,
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
function findParentContainer(start) {
var container, parent, child, sibling, siblingName;
var container, parent, child, sibling, siblingName, root;
container = parent = start ? startContainer : endContainer;
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.
// 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) {
if (offset === undefined)
if (offset === undef)
offset = node.nodeType === 3 ? node.length : node.childNodes.length;
while (node && node.hasChildNodes()) {
node = node.childNodes[offset];
@ -16118,29 +16767,6 @@ tinymce.ForceBlocks = function(editor) {
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) {
var walker, node, pos, lastTextNode;
@ -16203,63 +16829,12 @@ tinymce.ForceBlocks = function(editor) {
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) {
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];
parents = getParents(container);
@ -16279,13 +16854,6 @@ tinymce.ForceBlocks = function(editor) {
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) {
var node;
@ -16318,6 +16886,84 @@ tinymce.ForceBlocks = function(editor) {
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
startContainer = findBlockEndPoint(startContainer, 'previousSibling');
endContainer = findBlockEndPoint(endContainer, 'nextSibling');
@ -16454,14 +17100,14 @@ tinymce.ForceBlocks = function(editor) {
function removeNode(node, format) {
var parentNode = node.parentNode, rootBlockElm;
if (format.block) {
if (!forcedRootBlock) {
function find(node, next, inc) {
node = getNonWhiteSpaceSibling(node, next, inc);
return !node || (node.nodeName == 'BR' || isBlock(node));
};
if (format.block) {
if (!forcedRootBlock) {
// Append BR elements if needed before we remove the block
if (isBlock(node) && !isBlock(parentNode)) {
if (!find(node, FALSE) && !find(node.firstChild, TRUE, 1))
@ -16541,7 +17187,7 @@ tinymce.ForceBlocks = function(editor) {
value = obj2[name];
// Obj2 doesn't have obj1 item
if (value === undefined)
if (value === undef)
return FALSE;
// Obj2 item has a different value
@ -16574,8 +17220,6 @@ tinymce.ForceBlocks = function(editor) {
return TRUE;
};
// Check if next/prev exists and that they are elements
if (prev && next) {
function findElementSibling(node, sibling_name) {
for (sibling = node; sibling; sibling = sibling[sibling_name]) {
if (sibling.nodeType == 3 && sibling.nodeValue.length !== 0)
@ -16588,6 +17232,8 @@ tinymce.ForceBlocks = function(editor) {
return node;
};
// Check if next/prev exists and that they are elements
if (prev && next) {
// If previous sibling is empty then jump over it
prev = findElementSibling(prev, 'previousSibling');
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 (container.nodeType === 3 && !start && offset == 0) {
if (container.nodeType === 3 && !start && offset === 0) {
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;
}
@ -16907,14 +17562,15 @@ tinymce.ForceBlocks = function(editor) {
function moveStart(rng) {
var container = rng.startContainer,
offset = rng.startOffset,
offset = rng.startOffset, isAtEndOfText,
walker, node, nodes, tmpNode;
// Convert text node into index if possible
if (container.nodeType == 3 && offset >= container.nodeValue.length) {
// Get the parent container location and walk from there
offset = nodeIndex(container);
container = container.parentNode;
offset = nodeIndex(container) + 1;
isAtEndOfText = true;
}
// 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));
// 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();
for (node = walker.current(); node; node = walker.next()) {
@ -16950,9 +17606,6 @@ tinymce.ForceBlocks = function(editor) {
tinymce.onAddEditor.add(function(tinymce, ed) {
var filters, fontSizes, dom, settings = ed.settings;
if (settings.inline_styles) {
fontSizes = tinymce.explode(settings.font_size_legacy_values);
function replaceWithSpan(node, styles) {
tinymce.each(styles, function(value, name) {
if (value)
@ -16962,13 +17615,26 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
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 = {
font : function(dom, node) {
replaceWithSpan(node, {
backgroundColor : node.style.backgroundColor,
color : node.color,
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.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;
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
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
function moveToCaretPosition(root) {
var walker, node, rng, y, viewPort, lastNode = root;
var walker, node, rng, y, viewPort, lastNode = root, tempElm;
rng = dom.createRng();
@ -17050,8 +17711,19 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
}
} else {
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.setEndAfter(root);
}
} else {
rng.setStart(root, 0);
rng.setEnd(root, 0);
@ -17060,6 +17732,9 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
selection.setRng(rng);
// Remove tempElm created for old IE:s
dom.remove(tempElm);
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
@ -17074,10 +17749,11 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
function createNewBlock(name) {
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;
// Clone any parent styles
if (settings.keep_styles !== false) {
do {
if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(node.nodeName)) {
clonedNode = node.cloneNode(false);
@ -17092,6 +17768,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
}
}
} while (node = node.parentNode);
}
// BR is needed in empty blocks on non IE browsers
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
function isCaretAtStartOrEndOfBlock(start) {
var walker, node;
var walker, node, name;
// Caret is in the middle of a text node like "a|b"
if (container.nodeType == 3 && (start ? offset > 0 : offset < container.nodeValue.length)) {
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
walker = new TreeWalker(container, parentBlock);
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
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
parentBlock = dom.getParent(container, dom.isBlock);
if (newBlockName && !evt.shiftKey && (!parentBlock || !canSplitBlock(parentBlock))) {
parentBlock = parentBlock || dom.getRoot();
if (!parentBlock || !canSplitBlock(parentBlock)) {
parentBlock = parentBlock || editableRoot;
if (!parentBlock.hasChildNodes()) {
newBlock = dom.create(newBlockName);
newBlock = dom.create(blockName);
parentBlock.appendChild(newBlock);
rng.setStart(newBlock, 0);
rng.setEnd(newBlock, 0);
@ -17162,7 +17849,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
}
if (startNode) {
newBlock = dom.create(newBlockName);
newBlock = dom.create(blockName);
startNode.parentNode.insertBefore(newBlock, startNode);
// 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
function insertBr() {
var brElm, extraBr, documentMode;
var brElm, extraBr;
if (container && container.nodeType == 3 && offset >= container.nodeValue.length) {
// Insert extra BR element at the end block elements
@ -17258,7 +17945,6 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
rng.insertNode(brElm);
// 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)) {
brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm);
}
@ -17286,6 +17972,22 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
} 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
if (!rng.collapsed) {
editor.execCommand('Delete');
@ -17302,18 +18004,40 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
offset = rng.startOffset;
newBlockName = settings.forced_root_block;
newBlockName = newBlockName ? newBlockName.toUpperCase() : '';
documentMode = dom.doc.documentMode;
// Resolve node index
if (container.nodeType == 1 && container.hasChildNodes()) {
isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
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();
// 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.
// 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);
}
// Find parent block and setup empty block paddings
parentBlock = dom.getParent(container, dom.isBlock);
@ -17394,3 +18118,4 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
});
};
})(tinymce);

View file

@ -6,9 +6,9 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 3.0.1341\n"
"Project-Id-Version: 3.0.1343\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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -150,15 +150,15 @@ msgstr ""
#: ../../addon/statusnet/statusnet.php:318
#: ../../addon/statusnet/statusnet.php:325
#: ../../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/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/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/posterous/posterous.php:103
#: ../../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/quattro/config.php:52 ../../view/theme/dispy/config.php:70
#: ../../include/conversation.php:558
@ -352,7 +352,7 @@ msgstr ""
#: ../../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:1394 ../../addon/communityhome/communityhome.php:110
#: ../../view/theme/diabook/theme.php:594
#: ../../view/theme/diabook/theme.php:593
msgid "Contact Photos"
msgstr ""
@ -375,7 +375,7 @@ msgstr ""
#: ../../mod/profile_photo.php:74 ../../mod/profile_photo.php:174
#: ../../mod/profile_photo.php:252 ../../mod/profile_photo.php:261
#: ../../addon/communityhome/communityhome.php:111
#: ../../view/theme/diabook/theme.php:595
#: ../../view/theme/diabook/theme.php:594
msgid "Profile Photos"
msgstr ""
@ -397,7 +397,7 @@ msgstr ""
#: ../../mod/photos.php:528 ../../mod/like.php:127 ../../mod/tagger.php:70
#: ../../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/conversation.php:126
msgid "photo"
@ -1775,8 +1775,8 @@ msgid "Remove account"
msgstr ""
#: ../../mod/settings.php:88 ../../mod/admin.php:735 ../../mod/admin.php:940
#: ../../addon/mathjax/mathjax.php:36 ../../view/theme/diabook/theme.php:639
#: ../../view/theme/diabook/theme.php:769 ../../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"
msgstr ""
@ -1832,7 +1832,7 @@ msgstr ""
#: ../../addon/impressum/impressum.php:77
#: ../../addon/openstreetmap/openstreetmap.php:80
#: ../../addon/mathjax/mathjax.php:66 ../../addon/piwik/piwik.php:105
#: ../../addon/twitter/twitter.php:370
#: ../../addon/twitter/twitter.php:376
msgid "Settings updated."
msgstr ""
@ -1842,12 +1842,12 @@ msgid "Add application"
msgstr ""
#: ../../mod/settings.php:542 ../../mod/settings.php:568
#: ../../addon/statusnet/statusnet.php:547
#: ../../addon/statusnet/statusnet.php:555
msgid "Consumer Key"
msgstr ""
#: ../../mod/settings.php:543 ../../mod/settings.php:569
#: ../../addon/statusnet/statusnet.php:546
#: ../../addon/statusnet/statusnet.php:554
msgid "Consumer Secret"
msgstr ""
@ -2787,8 +2787,8 @@ msgstr ""
#: ../../addon/facebook/facebook.php:1564
#: ../../addon/communityhome/communityhome.php:158
#: ../../addon/communityhome/communityhome.php:167
#: ../../view/theme/diabook/theme.php:561
#: ../../view/theme/diabook/theme.php:570 ../../include/diaspora.php:1654
#: ../../view/theme/diabook/theme.php:560
#: ../../view/theme/diabook/theme.php:569 ../../include/diaspora.php:1654
#: ../../include/conversation.php:48 ../../include/conversation.php:57
#: ../../include/conversation.php:121 ../../include/conversation.php:130
msgid "status"
@ -2796,7 +2796,7 @@ msgstr ""
#: ../../mod/like.php:144 ../../addon/facebook/facebook.php:1568
#: ../../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
#, php-format
msgid "%1$s likes %2$s's %3$s"
@ -3137,7 +3137,7 @@ msgstr ""
msgid "Advanced"
msgstr ""
#: ../../mod/admin.php:412 ../../addon/statusnet/statusnet.php:544
#: ../../mod/admin.php:412 ../../addon/statusnet/statusnet.php:552
msgid "Site name"
msgstr ""
@ -4073,7 +4073,7 @@ msgstr ""
msgid "No entries."
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
msgid "Friend Suggestions"
msgstr ""
@ -4088,7 +4088,7 @@ msgstr ""
msgid "Ignore/Hide"
msgstr ""
#: ../../mod/directory.php:47 ../../view/theme/diabook/theme.php:620
#: ../../mod/directory.php:47 ../../view/theme/diabook/theme.php:619
msgid "Global Directory"
msgstr ""
@ -4673,7 +4673,7 @@ msgid "Latest likes"
msgstr ""
#: ../../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
msgid "event"
msgstr ""
@ -4824,7 +4824,7 @@ msgstr ""
msgid "Post to Drupal by default"
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
msgid "Post from Friendica"
msgstr ""
@ -5272,14 +5272,14 @@ msgid "Send public postings to StatusNet by default"
msgstr ""
#: ../../addon/statusnet/statusnet.php:345
msgid "Send #tag links to StatusNet"
msgid "Send linked #-tags and @-names to StatusNet"
msgstr ""
#: ../../addon/statusnet/statusnet.php:350 ../../addon/twitter/twitter.php:206
msgid "Clear OAuth configuration"
msgstr ""
#: ../../addon/statusnet/statusnet.php:545
#: ../../addon/statusnet/statusnet.php:553
msgid "API URL"
msgstr ""
@ -5346,30 +5346,38 @@ msgstr ""
msgid "Post to Wordpress"
msgstr ""
#: ../../addon/wppost/wppost.php:74
#: ../../addon/wppost/wppost.php:76
msgid "WordPress Post Settings"
msgstr ""
#: ../../addon/wppost/wppost.php:76
#: ../../addon/wppost/wppost.php:78
msgid "Enable WordPress Post Plugin"
msgstr ""
#: ../../addon/wppost/wppost.php:81
#: ../../addon/wppost/wppost.php:83
msgid "WordPress username"
msgstr ""
#: ../../addon/wppost/wppost.php:86
#: ../../addon/wppost/wppost.php:88
msgid "WordPress password"
msgstr ""
#: ../../addon/wppost/wppost.php:91
#: ../../addon/wppost/wppost.php:93
msgid "WordPress API URL"
msgstr ""
#: ../../addon/wppost/wppost.php:96
#: ../../addon/wppost/wppost.php:98
msgid "Post to WordPress by default"
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
msgid "\"Show more\" Settings"
msgstr ""
@ -5481,14 +5489,14 @@ msgid "Send public postings to Twitter by default"
msgstr ""
#: ../../addon/twitter/twitter.php:201
msgid "Send #tag links to Twitter"
msgid "Send linked #-tags and @-names to Twitter"
msgstr ""
#: ../../addon/twitter/twitter.php:377
#: ../../addon/twitter/twitter.php:383
msgid "Consumer key"
msgstr ""
#: ../../addon/twitter/twitter.php:378
#: ../../addon/twitter/twitter.php:384
msgid "Consumer secret"
msgstr ""
@ -5631,96 +5639,97 @@ msgid "Your personal photos"
msgstr ""
#: ../../view/theme/diabook/theme.php:129
#: ../../view/theme/diabook/theme.php:639
#: ../../view/theme/diabook/theme.php:743
#: ../../view/theme/diabook/theme.php:638
#: ../../view/theme/diabook/theme.php:742
#: ../../view/theme/diabook/config.php:201
msgid "Community Pages"
msgstr ""
#: ../../view/theme/diabook/theme.php:486
#: ../../view/theme/diabook/theme.php:745
#: ../../view/theme/diabook/theme.php:485
#: ../../view/theme/diabook/theme.php:744
#: ../../view/theme/diabook/config.php:203
msgid "Community Profiles"
msgstr ""
#: ../../view/theme/diabook/theme.php:507
#: ../../view/theme/diabook/theme.php:750
#: ../../view/theme/diabook/theme.php:506
#: ../../view/theme/diabook/theme.php:749
#: ../../view/theme/diabook/config.php:208
msgid "Last users"
msgstr ""
#: ../../view/theme/diabook/theme.php:536
#: ../../view/theme/diabook/theme.php:752
#: ../../view/theme/diabook/theme.php:535
#: ../../view/theme/diabook/theme.php:751
#: ../../view/theme/diabook/config.php:210
msgid "Last likes"
msgstr ""
#: ../../view/theme/diabook/theme.php:581
#: ../../view/theme/diabook/theme.php:751
#: ../../view/theme/diabook/theme.php:580
#: ../../view/theme/diabook/theme.php:750
#: ../../view/theme/diabook/config.php:209
msgid "Last photos"
msgstr ""
#: ../../view/theme/diabook/theme.php:618
#: ../../view/theme/diabook/theme.php:748
#: ../../view/theme/diabook/theme.php:617
#: ../../view/theme/diabook/theme.php:747
#: ../../view/theme/diabook/config.php:206
msgid "Find Friends"
msgstr ""
#: ../../view/theme/diabook/theme.php:619
#: ../../view/theme/diabook/theme.php:618
msgid "Local Directory"
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"
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"
msgstr ""
#: ../../view/theme/diabook/theme.php:674
#: ../../view/theme/diabook/theme.php:744
#: ../../view/theme/diabook/theme.php:673
#: ../../view/theme/diabook/theme.php:743
#: ../../view/theme/diabook/config.php:202
msgid "Earth Layers"
msgstr ""
#: ../../view/theme/diabook/theme.php:679
#: ../../view/theme/diabook/theme.php:678
msgid "Set zoomfactor for Earth Layers"
msgstr ""
#: ../../view/theme/diabook/theme.php:680
#: ../../view/theme/diabook/theme.php:679
#: ../../view/theme/diabook/config.php:199
msgid "Set longitude (X) for Earth Layers"
msgstr ""
#: ../../view/theme/diabook/theme.php:681
#: ../../view/theme/diabook/theme.php:680
#: ../../view/theme/diabook/config.php:200
msgid "Set latitude (Y) for Earth Layers"
msgstr ""
#: ../../view/theme/diabook/theme.php:694
#: ../../view/theme/diabook/theme.php:746
#: ../../view/theme/diabook/theme.php:693
#: ../../view/theme/diabook/theme.php:745
#: ../../view/theme/diabook/config.php:204
msgid "Help or @NewHere ?"
msgstr ""
#: ../../view/theme/diabook/theme.php:701
#: ../../view/theme/diabook/theme.php:747
#: ../../view/theme/diabook/theme.php:700
#: ../../view/theme/diabook/theme.php:746
#: ../../view/theme/diabook/config.php:205
msgid "Connect Services"
msgstr ""
#: ../../view/theme/diabook/theme.php:708
#: ../../view/theme/diabook/theme.php:749
#: ../../view/theme/diabook/theme.php:707
#: ../../view/theme/diabook/theme.php:748
msgid "Last Tweets"
msgstr ""
#: ../../view/theme/diabook/theme.php:711
#: ../../view/theme/diabook/theme.php:710
#: ../../view/theme/diabook/config.php:197
msgid "Set twitter search term"
msgstr ""
#: ../../view/theme/diabook/theme.php:730
#: ../../view/theme/diabook/theme.php:731
#: ../../view/theme/diabook/theme.php:732
#: ../../view/theme/diabook/theme.php:733
@ -5729,11 +5738,11 @@ msgstr ""
#: ../../view/theme/diabook/theme.php:736
#: ../../view/theme/diabook/theme.php:737
#: ../../view/theme/diabook/theme.php:738
#: ../../view/theme/diabook/theme.php:739
#: ../../view/theme/diabook/theme.php:740 ../../include/acl_selectors.php:288
#: ../../view/theme/diabook/theme.php:739 ../../include/acl_selectors.php:288
msgid "don't show"
msgstr ""
#: ../../view/theme/diabook/theme.php:730
#: ../../view/theme/diabook/theme.php:731
#: ../../view/theme/diabook/theme.php:732
#: ../../view/theme/diabook/theme.php:733
@ -5742,12 +5751,11 @@ msgstr ""
#: ../../view/theme/diabook/theme.php:736
#: ../../view/theme/diabook/theme.php:737
#: ../../view/theme/diabook/theme.php:738
#: ../../view/theme/diabook/theme.php:739
#: ../../view/theme/diabook/theme.php:740 ../../include/acl_selectors.php:287
#: ../../view/theme/diabook/theme.php:739 ../../include/acl_selectors.php:287
msgid "show"
msgstr ""
#: ../../view/theme/diabook/theme.php:741
#: ../../view/theme/diabook/theme.php:740
msgid "Show/hide boxes at right-hand column:"
msgstr ""

View file

@ -19,8 +19,8 @@ msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: http://bugs.friendica.com/\n"
"POT-Creation-Date: 2012-05-06 10:00-0700\n"
"PO-Revision-Date: 2012-05-08 07:06+0000\n"
"POT-Creation-Date: 2012-05-14 10:00-0700\n"
"PO-Revision-Date: 2012-05-15 08:40+0000\n"
"Last-Translator: bavatar <tobias.diekershoff@gmx.net>\n"
"Language-Team: German (http://www.transifex.net/projects/p/friendica/language/de/)\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/item.php:140 ../../mod/profile_photo.php:19
#: ../../mod/profile_photo.php:139 ../../mod/profile_photo.php:150
#: ../../mod/profile_photo.php:163 ../../mod/message.php:38
#: ../../mod/message.php:90 ../../mod/allfriends.php:9
#: ../../mod/profile_photo.php:163 ../../mod/message.php:44
#: ../../mod/message.php:96 ../../mod/allfriends.php:9
#: ../../mod/nogroup.php:25 ../../mod/wall_upload.php:53
#: ../../mod/follow.php:8 ../../mod/display.php:138 ../../mod/profiles.php:7
#: ../../mod/profiles.php:365 ../../mod/delegate.php:6
#: ../../mod/suggest.php:28 ../../mod/invite.php:13 ../../mod/invite.php:81
#: ../../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."
msgstr "Zugriff verweigert."
@ -97,7 +97,7 @@ msgid "Return to contact editor"
msgstr "Zurück zum Kontakteditor"
#: ../../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"
msgstr "Name"
@ -141,9 +141,9 @@ msgstr "Neues Foto von dieser URL"
#: ../../mod/localtime.php:45 ../../mod/contacts.php:322
#: ../../mod/settings.php:539 ../../mod/settings.php:685
#: ../../mod/settings.php:746 ../../mod/settings.php:940
#: ../../mod/manage.php:109 ../../mod/group.php:85 ../../mod/admin.php:402
#: ../../mod/admin.php:637 ../../mod/admin.php:773 ../../mod/admin.php:972
#: ../../mod/admin.php:1059 ../../mod/profiles.php:534
#: ../../mod/manage.php:109 ../../mod/group.php:85 ../../mod/admin.php:404
#: ../../mod/admin.php:640 ../../mod/admin.php:776 ../../mod/admin.php:975
#: ../../mod/admin.php:1062 ../../mod/profiles.php:534
#: ../../mod/invite.php:119 ../../addon/facebook/facebook.php:597
#: ../../addon/yourls/yourls.php:76 ../../addon/ljpost/ljpost.php:93
#: ../../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/openstreetmap/openstreetmap.php:70
#: ../../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/jappixmini/jappixmini.php:302
#: ../../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/twitter/twitter.php:209 ../../addon/twitter/twitter.php:375
#: ../../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/diabook/theme.php:590
#: ../../view/theme/diabook/config.php:95
#: ../../view/theme/diabook/theme.php:752
#: ../../view/theme/diabook/config.php:190
#: ../../view/theme/quattro/config.php:52 ../../view/theme/dispy/config.php:70
#: ../../include/conversation.php:555
#: ../../include/conversation.php:558
msgid "Submit"
msgstr "Senden"
@ -231,8 +231,8 @@ msgstr "Veranstaltung bearbeiten"
msgid "link to source"
msgstr "Link zum Originalbeitrag"
#: ../../mod/events.php:324 ../../view/theme/diabook/theme.php:69
#: ../../include/nav.php:52 ../../boot.php:1493
#: ../../mod/events.php:324 ../../view/theme/diabook/theme.php:126
#: ../../include/nav.php:52 ../../boot.php:1503
msgid "Events"
msgstr "Veranstaltungen"
@ -282,7 +282,7 @@ msgid "Description:"
msgstr "Beschreibung"
#: ../../mod/events.php:423 ../../include/event.php:37
#: ../../include/bb2diaspora.php:260 ../../boot.php:1092
#: ../../include/bb2diaspora.php:260 ../../boot.php:1102
msgid "Location:"
msgstr "Ort:"
@ -357,14 +357,14 @@ msgstr "Ja"
msgid "No"
msgstr "Nein"
#: ../../mod/photos.php:43 ../../boot.php:1487
#: ../../mod/photos.php:43 ../../boot.php:1497
msgid "Photo Albums"
msgstr "Fotoalben"
#: ../../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:1394 ../../addon/communityhome/communityhome.php:110
#: ../../view/theme/diabook/theme.php:485
#: ../../view/theme/diabook/theme.php:593
msgid "Contact Photos"
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:252 ../../mod/profile_photo.php:261
#: ../../addon/communityhome/communityhome.php:111
#: ../../view/theme/diabook/theme.php:486
#: ../../view/theme/diabook/theme.php:594
msgid "Profile Photos"
msgstr "Profilbilder"
@ -409,7 +409,7 @@ msgstr "wurde getaggt in einem"
#: ../../mod/photos.php:528 ../../mod/like.php:127 ../../mod/tagger.php:70
#: ../../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/conversation.php:126
msgid "photo"
@ -499,7 +499,7 @@ msgstr "Foto bearbeiten"
msgid "Use as profile photo"
msgstr "Als Profilbild verwenden"
#: ../../mod/photos.php:1078 ../../include/conversation.php:480
#: ../../mod/photos.php:1078 ../../include/conversation.php:483
msgid "Private Message"
msgstr "Private Nachricht"
@ -532,44 +532,44 @@ msgid ""
"Example: @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)"
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)"
msgstr "Ich mag das nicht (toggle)"
#: ../../mod/photos.php:1213 ../../include/conversation.php:964
#: ../../mod/photos.php:1213 ../../include/conversation.php:967
msgid "Share"
msgstr "Teilen"
#: ../../mod/photos.php:1214 ../../mod/editpost.php:104
#: ../../mod/wallmessage.php:145 ../../mod/message.php:188
#: ../../mod/message.php:380 ../../include/conversation.php:361
#: ../../include/conversation.php:706 ../../include/conversation.php:983
#: ../../mod/wallmessage.php:145 ../../mod/message.php:214
#: ../../mod/message.php:408 ../../include/conversation.php:364
#: ../../include/conversation.php:709 ../../include/conversation.php:986
msgid "Please wait"
msgstr "Bitte warten"
#: ../../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"
msgstr "Das bist du"
#: ../../mod/photos.php:1232 ../../mod/photos.php:1272
#: ../../mod/photos.php:1303 ../../include/conversation.php:554
#: ../../boot.php:506
#: ../../mod/photos.php:1303 ../../include/conversation.php:557
#: ../../boot.php:516
msgid "Comment"
msgstr "Kommentar"
#: ../../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"
msgstr "Vorschau"
#: ../../mod/photos.php:1331 ../../mod/settings.php:602
#: ../../mod/settings.php:683 ../../mod/group.php:168 ../../mod/admin.php:644
#: ../../include/conversation.php:318 ../../include/conversation.php:584
#: ../../mod/settings.php:683 ../../mod/group.php:168 ../../mod/admin.php:647
#: ../../include/conversation.php:321 ../../include/conversation.php:587
msgid "Delete"
msgstr "Löschen"
@ -585,7 +585,7 @@ msgstr "Neueste Fotos"
msgid "Not available."
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
msgid "Community"
msgstr "Gemeinschaft"
@ -634,28 +634,28 @@ msgstr "Beitrag nicht gefunden"
msgid "Edit post"
msgstr "Beitrag bearbeiten"
#: ../../mod/editpost.php:80 ../../include/conversation.php:950
#: ../../mod/editpost.php:80 ../../include/conversation.php:953
msgid "Post to Email"
msgstr "An E-Mail senden"
#: ../../mod/editpost.php:95 ../../mod/settings.php:601
#: ../../include/conversation.php:571
#: ../../include/conversation.php:574
msgid "Edit"
msgstr "Bearbeiten"
#: ../../mod/editpost.php:96 ../../mod/wallmessage.php:143
#: ../../mod/message.php:186 ../../mod/message.php:378
#: ../../include/conversation.php:965
#: ../../mod/message.php:212 ../../mod/message.php:406
#: ../../include/conversation.php:968
msgid "Upload photo"
msgstr "Foto hochladen"
#: ../../mod/editpost.php:97 ../../include/conversation.php:967
#: ../../mod/editpost.php:97 ../../include/conversation.php:970
msgid "Attach file"
msgstr "Datei anhängen"
#: ../../mod/editpost.php:98 ../../mod/wallmessage.php:144
#: ../../mod/message.php:187 ../../mod/message.php:379
#: ../../include/conversation.php:969
#: ../../mod/message.php:213 ../../mod/message.php:407
#: ../../include/conversation.php:972
msgid "Insert web link"
msgstr "einen Link einfügen"
@ -671,35 +671,35 @@ msgstr "Vorbis [.ogg] Video einfügen"
msgid "Insert Vorbis [.ogg] audio"
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"
msgstr "Deinen Standort festlegen"
#: ../../mod/editpost.php:103 ../../include/conversation.php:977
#: ../../mod/editpost.php:103 ../../include/conversation.php:980
msgid "Clear browser location"
msgstr "Browser-Standort leeren"
#: ../../mod/editpost.php:105 ../../include/conversation.php:984
#: ../../mod/editpost.php:105 ../../include/conversation.php:987
msgid "Permission settings"
msgstr "Berechtigungseinstellungen"
#: ../../mod/editpost.php:113 ../../include/conversation.php:993
#: ../../mod/editpost.php:113 ../../include/conversation.php:996
msgid "CC: email addresses"
msgstr "Cc:-E-Mail-Addressen"
#: ../../mod/editpost.php:114 ../../include/conversation.php:994
#: ../../mod/editpost.php:114 ../../include/conversation.php:997
msgid "Public post"
msgstr "Öffentlicher Beitrag"
#: ../../mod/editpost.php:117 ../../include/conversation.php:980
#: ../../mod/editpost.php:117 ../../include/conversation.php:983
msgid "Set title"
msgstr "Titel setzen"
#: ../../mod/editpost.php:119 ../../include/conversation.php:982
#: ../../mod/editpost.php:119 ../../include/conversation.php:985
msgid "Categories (comma-separated list)"
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"
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."
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."
msgstr "Nicht erlaubte Profil-URL."
@ -816,7 +816,7 @@ msgstr "Bitte bestätige deine Kontaktanfrage bei %s."
msgid "Confirm"
msgstr "Bestätigen"
#: ../../mod/dfrn_request.php:688 ../../include/items.php:2707
#: ../../mod/dfrn_request.php:688 ../../include/items.php:2717
msgid "[Name Withheld]"
msgstr "[Name unterdrückt]"
@ -1180,7 +1180,7 @@ msgid "is interested in:"
msgstr "ist interessiert an:"
#: ../../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"
msgstr "Verbinden"
@ -1228,7 +1228,7 @@ msgstr "Netzwerk"
msgid "Personal"
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
msgid "Home"
msgstr "Pinnwand"
@ -1237,7 +1237,7 @@ msgstr "Pinnwand"
msgid "Introductions"
msgstr "Kontaktanfragen"
#: ../../mod/notifications.php:100 ../../mod/message.php:102
#: ../../mod/notifications.php:100 ../../mod/message.php:104
#: ../../include/nav.php:128
msgid "Messages"
msgstr "Nachrichten"
@ -1277,7 +1277,7 @@ msgid "if applicable"
msgstr "falls anwendbar"
#: ../../mod/notifications.php:157 ../../mod/notifications.php:204
#: ../../mod/admin.php:642
#: ../../mod/admin.php:645
msgid "Approve"
msgstr "Genehmigen"
@ -1478,12 +1478,12 @@ msgid "View all contacts"
msgstr "Alle Kontakte anzeigen"
#: ../../mod/contacts.php:290 ../../mod/contacts.php:347
#: ../../mod/admin.php:646
#: ../../mod/admin.php:649
msgid "Unblock"
msgstr "Entsperren"
#: ../../mod/contacts.php:290 ../../mod/contacts.php:347
#: ../../mod/admin.php:645
#: ../../mod/admin.php:648
msgid "Block"
msgstr "Sperren"
@ -1576,7 +1576,7 @@ msgstr "letzte Aktualisierung:"
msgid "Update public posts"
msgstr "Öffentliche Beiträge aktualisieren"
#: ../../mod/contacts.php:344 ../../mod/admin.php:1117
#: ../../mod/contacts.php:344 ../../mod/admin.php:1120
msgid "Update now"
msgstr "Jetzt aktualisieren"
@ -1669,7 +1669,7 @@ msgstr "du bist Fan von"
msgid "Edit contact"
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
msgid "Contacts"
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
#: ../../addon/facebook/facebook.php:680
#: ../../addon/facebook/facebook.php:1170
#: ../../addon/testdrive/testdrive.php:58 ../../include/items.php:2716
#: ../../boot.php:686
#: ../../addon/testdrive/testdrive.php:58 ../../include/items.php:2726
#: ../../boot.php:696
msgid "Administrator"
msgstr "Administrator"
@ -1716,7 +1716,7 @@ msgid ""
"Password reset failed."
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"
msgstr "Passwort zurücksetzen"
@ -1788,8 +1788,9 @@ msgstr "Persönliche Daten exportieren"
msgid "Remove account"
msgstr "Account entfernen"
#: ../../mod/settings.php:88 ../../mod/admin.php:732 ../../mod/admin.php:937
#: ../../addon/mathjax/mathjax.php:36 ../../include/nav.php:137
#: ../../mod/settings.php:88 ../../mod/admin.php:735 ../../mod/admin.php:940
#: ../../addon/mathjax/mathjax.php:36 ../../view/theme/diabook/theme.php:638
#: ../../view/theme/diabook/theme.php:768 ../../include/nav.php:137
msgid "Settings"
msgstr "Einstellungen"
@ -2015,7 +2016,7 @@ msgstr "Maximal 100 Beiträge"
msgid "Don't show emoticons"
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"
msgstr "Normaler Account"
@ -2023,7 +2024,7 @@ msgstr "Normaler Account"
msgid "This account is a normal personal profile"
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"
msgstr "Sandkasten-Account"
@ -2031,7 +2032,7 @@ msgstr "Sandkasten-Account"
msgid "Automatically approve all connection/friend requests as read-only fans"
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"
msgstr "Gemeinschafts/Promi-Account"
@ -2040,7 +2041,7 @@ msgid ""
"Automatically approve all connection/friend requests as read-write fans"
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"
msgstr "Automatischer Freundesaccount"
@ -2366,7 +2367,7 @@ msgstr "Private Nachrichten an diese Person könnten an die Öffentlichkeit gela
msgid "Invalid contact."
msgstr "Ungültiger Kontakt."
#: ../../mod/notes.php:44 ../../boot.php:1499
#: ../../mod/notes.php:44 ../../boot.php:1509
msgid "Personal Notes"
msgstr "Persönliche Notizen"
@ -2382,7 +2383,7 @@ msgstr "Speichern"
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."
#: ../../mod/wallmessage.php:56 ../../mod/message.php:59
#: ../../mod/wallmessage.php:56 ../../mod/message.php:65
msgid "No recipient selected."
msgstr "Kein Empfänger gewählt."
@ -2390,15 +2391,15 @@ msgstr "Kein Empfänger gewählt."
msgid "Unable to check your home location."
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."
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."
msgstr "Konnte Nachrichten nicht abrufen."
#: ../../mod/wallmessage.php:68 ../../mod/message.php:72
#: ../../mod/wallmessage.php:68 ../../mod/message.php:78
msgid "Message sent."
msgstr "Nachricht gesendet."
@ -2406,12 +2407,12 @@ msgstr "Nachricht gesendet."
msgid "No recipient."
msgstr "Kein Empfänger."
#: ../../mod/wallmessage.php:124 ../../mod/message.php:169
#: ../../include/conversation.php:918
#: ../../mod/wallmessage.php:124 ../../mod/message.php:171
#: ../../include/conversation.php:921
msgid "Please enter a link URL:"
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"
msgstr "Private Nachricht senden"
@ -2422,18 +2423,18 @@ msgid ""
"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."
#: ../../mod/wallmessage.php:133 ../../mod/message.php:178
#: ../../mod/message.php:370
#: ../../mod/wallmessage.php:133 ../../mod/message.php:200
#: ../../mod/message.php:397
msgid "To:"
msgstr "An:"
#: ../../mod/wallmessage.php:134 ../../mod/message.php:179
#: ../../mod/message.php:371
#: ../../mod/wallmessage.php:134 ../../mod/message.php:205
#: ../../mod/message.php:399
msgid "Subject:"
msgstr "Betreff:"
#: ../../mod/wallmessage.php:140 ../../mod/message.php:183
#: ../../mod/message.php:374 ../../mod/invite.php:113
#: ../../mod/wallmessage.php:140 ../../mod/message.php:209
#: ../../mod/message.php:402 ../../mod/invite.php:113
msgid "Your message:"
msgstr "Deine Nachricht:"
@ -2615,9 +2616,9 @@ msgstr "Ungültiger Profil-Bezeichner"
msgid "Profile Visibility Editor"
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/nav.php:50 ../../boot.php:1478
#: ../../include/nav.php:50 ../../boot.php:1488
msgid "Profile"
msgstr "Profil"
@ -2766,7 +2767,7 @@ msgstr "Mitgliedschaft auf dieser Seite ist nur nach vorheriger Einladung mögli
msgid "Your invitation ID: "
msgstr "ID deiner Einladung: "
#: ../../mod/register.php:553 ../../mod/admin.php:403
#: ../../mod/register.php:553 ../../mod/admin.php:405
msgid "Registration"
msgstr "Registrierung"
@ -2789,7 +2790,7 @@ msgstr "Wähle einen Spitznamen für dein Profil. Dieser muss mit einem Buchstab
msgid "Choose a nickname: "
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"
msgstr "Registrieren"
@ -2801,8 +2802,8 @@ msgstr "Personen Suche"
#: ../../addon/facebook/facebook.php:1564
#: ../../addon/communityhome/communityhome.php:158
#: ../../addon/communityhome/communityhome.php:167
#: ../../view/theme/diabook/theme.php:452
#: ../../view/theme/diabook/theme.php:461 ../../include/diaspora.php:1654
#: ../../view/theme/diabook/theme.php:560
#: ../../view/theme/diabook/theme.php:569 ../../include/diaspora.php:1654
#: ../../include/conversation.php:48 ../../include/conversation.php:57
#: ../../include/conversation.php:121 ../../include/conversation.php:130
msgid "status"
@ -2810,7 +2811,7 @@ msgstr "Status"
#: ../../mod/like.php:144 ../../addon/facebook/facebook.php:1568
#: ../../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
#, php-format
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"
#: ../../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/display.php:142 ../../include/items.php:3074
#: ../../mod/admin.php:684 ../../mod/admin.php:883 ../../mod/display.php:37
#: ../../mod/display.php:142 ../../include/items.php:3084
msgid "Item not found."
msgstr "Beitrag nicht gefunden."
@ -2831,8 +2832,8 @@ msgstr "Beitrag nicht gefunden."
msgid "Access denied."
msgstr "Zugriff verweigert."
#: ../../mod/fbrowser.php:23 ../../view/theme/diabook/theme.php:68
#: ../../include/nav.php:51 ../../boot.php:1484
#: ../../mod/fbrowser.php:23 ../../view/theme/diabook/theme.php:125
#: ../../include/nav.php:51 ../../boot.php:1494
msgid "Photos"
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:"
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"
msgstr "Neue Nachricht"
#: ../../mod/message.php:63
#: ../../mod/message.php:69
msgid "Unable to locate contact information."
msgstr "Konnte die Kontaktinformationen nicht finden."
#: ../../mod/message.php:117
#: ../../mod/message.php:119
msgid "Message deleted."
msgstr "Nachricht gelöscht."
#: ../../mod/message.php:147
#: ../../mod/message.php:149
msgid "Conversation removed."
msgstr "Unterhaltung gelöscht."
#: ../../mod/message.php:219
#: ../../mod/message.php:245
msgid "No messages."
msgstr "Keine Nachrichten."
#: ../../mod/message.php:226
#: ../../mod/message.php:252
#, php-format
msgid "Unknown sender - %s"
msgstr "'Unbekannter Absender - %s"
#: ../../mod/message.php:229
#: ../../mod/message.php:255
#, php-format
msgid "You and %s"
msgstr "Du und %s"
#: ../../mod/message.php:232
#: ../../mod/message.php:258
#, php-format
msgid "%s and You"
msgstr "%s und Du"
#: ../../mod/message.php:242 ../../mod/message.php:363
#: ../../mod/message.php:268 ../../mod/message.php:390
msgid "Delete conversation"
msgstr "Unterhaltung löschen"
#: ../../mod/message.php:245
#: ../../mod/message.php:271
msgid "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
msgid "%d message"
msgid_plural "%d messages"
msgstr[0] "%d Nachricht"
msgstr[1] "%d Nachrichten"
#: ../../mod/message.php:282
#: ../../mod/message.php:308
msgid "Message not available."
msgstr "Nachricht nicht verfügbar."
#: ../../mod/message.php:347
#: ../../mod/message.php:373
msgid "Delete message"
msgstr "Nachricht löschen"
#: ../../mod/message.php:365
#: ../../mod/message.php:392
msgid ""
"No secure communications available. You <strong>may</strong> be able to "
"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."
#: ../../mod/message.php:369
#: ../../mod/message.php:396
msgid "Send Reply"
msgstr "Antwort senden"
@ -3054,19 +3055,19 @@ msgstr "Keine Freunde zum Anzeigen."
msgid "Theme settings updated."
msgstr "Themen Einstellungen aktualisiert."
#: ../../mod/admin.php:96 ../../mod/admin.php:401
#: ../../mod/admin.php:96 ../../mod/admin.php:403
msgid "Site"
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"
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"
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"
msgstr "Themen"
@ -3078,7 +3079,7 @@ msgstr "DB Updates"
msgid "Software Update"
msgstr "Software Update"
#: ../../mod/admin.php:115 ../../mod/admin.php:1058
#: ../../mod/admin.php:115 ../../mod/admin.php:1061
msgid "Logs"
msgstr "Protokolle"
@ -3086,9 +3087,9 @@ msgstr "Protokolle"
msgid "User registrations waiting for confirmation"
msgstr "Nutzeranmeldungen die auf Bestätigung warten"
#: ../../mod/admin.php:195 ../../mod/admin.php:400 ../../mod/admin.php:635
#: ../../mod/admin.php:729 ../../mod/admin.php:771 ../../mod/admin.php:934
#: ../../mod/admin.php:970 ../../mod/admin.php:1057
#: ../../mod/admin.php:195 ../../mod/admin.php:402 ../../mod/admin.php:638
#: ../../mod/admin.php:732 ../../mod/admin.php:774 ../../mod/admin.php:937
#: ../../mod/admin.php:973 ../../mod/admin.php:1060
msgid "Administration"
msgstr "Administration"
@ -3112,497 +3113,507 @@ msgstr "Version"
msgid "Active plugins"
msgstr "Aktive Plugins"
#: ../../mod/admin.php:339
#: ../../mod/admin.php:341
msgid "Site settings updated."
msgstr "Seiteneinstellungen aktualisiert."
#: ../../mod/admin.php:387
#: ../../mod/admin.php:389
msgid "Closed"
msgstr "Geschlossen"
#: ../../mod/admin.php:388
#: ../../mod/admin.php:390
msgid "Requires approval"
msgstr "Bedarf der Zustimmung"
#: ../../mod/admin.php:389
#: ../../mod/admin.php:391
msgid "Open"
msgstr "Offen"
#: ../../mod/admin.php:393
#: ../../mod/admin.php:395
msgid "No SSL policy, links will track page SSL state"
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"
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)"
msgstr "Selbst-unterzeichnetes Zertifikat, SSL nur für lokale Links verwenden (nicht empfohlen)"
#: ../../mod/admin.php:404
#: ../../mod/admin.php:406
msgid "File upload"
msgstr "Datei hochladen"
#: ../../mod/admin.php:405
#: ../../mod/admin.php:407
msgid "Policies"
msgstr "Regeln"
#: ../../mod/admin.php:406
#: ../../mod/admin.php:408
msgid "Advanced"
msgstr "Erweitert"
#: ../../mod/admin.php:410 ../../addon/statusnet/statusnet.php:544
#: ../../mod/admin.php:412 ../../addon/statusnet/statusnet.php:544
msgid "Site name"
msgstr "Seitenname"
#: ../../mod/admin.php:411
#: ../../mod/admin.php:413
msgid "Banner/Logo"
msgstr "Banner/Logo"
#: ../../mod/admin.php:412
#: ../../mod/admin.php:414
msgid "System language"
msgstr "Systemsprache"
#: ../../mod/admin.php:413
#: ../../mod/admin.php:415
msgid "System theme"
msgstr "Systemweites Thema"
#: ../../mod/admin.php:413
#: ../../mod/admin.php:415
msgid ""
"Default system theme - may be over-ridden by user profiles - <a href='#' "
"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>"
#: ../../mod/admin.php:414
#: ../../mod/admin.php:416
msgid "SSL link policy"
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"
msgstr "Bestimmt, ob generierte Links SSL verwenden müssen"
#: ../../mod/admin.php:415
#: ../../mod/admin.php:417
msgid "Maximum image size"
msgstr "Maximale Größe von Bildern"
#: ../../mod/admin.php:415
#: ../../mod/admin.php:417
msgid ""
"Maximum size in bytes of uploaded images. Default is 0, which means no "
"limits."
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"
msgstr "Registrierungsmethode"
#: ../../mod/admin.php:418
#: ../../mod/admin.php:420
msgid "Register text"
msgstr "Registrierungstext"
#: ../../mod/admin.php:418
#: ../../mod/admin.php:420
msgid "Will be displayed prominently on the registration page."
msgstr "Wird gut sichtbar auf der Registrierungs-Seite angezeigt."
#: ../../mod/admin.php:419
#: ../../mod/admin.php:421
msgid "Accounts abandoned after x days"
msgstr "Accounts gelten nach x Tagen als unbenutzt"
#: ../../mod/admin.php:419
#: ../../mod/admin.php:421
msgid ""
"Will not waste system resources polling external sites for abandonded "
"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."
#: ../../mod/admin.php:420
#: ../../mod/admin.php:422
msgid "Allowed friend domains"
msgstr "Erlaubte Domains für Kontakte"
#: ../../mod/admin.php:420
#: ../../mod/admin.php:422
msgid ""
"Comma separated list of domains which are allowed to establish friendships "
"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."
#: ../../mod/admin.php:421
#: ../../mod/admin.php:423
msgid "Allowed email domains"
msgstr "Erlaubte Domains für Emails"
#: ../../mod/admin.php:421
#: ../../mod/admin.php:423
msgid ""
"Comma separated list of domains which are allowed in email addresses for "
"registrations to this site. Wildcards are accepted. Empty to allow any "
"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."
#: ../../mod/admin.php:422
#: ../../mod/admin.php:424
msgid "Block public"
msgstr "Öffentlichen Zugriff blockieren"
#: ../../mod/admin.php:422
#: ../../mod/admin.php:424
msgid ""
"Check to block public access to all otherwise public personal pages on this "
"site unless you are currently logged in."
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"
msgstr "Erzwinge Veröffentlichung"
#: ../../mod/admin.php:423
#: ../../mod/admin.php:425
msgid ""
"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."
#: ../../mod/admin.php:424
#: ../../mod/admin.php:426
msgid "Global directory update URL"
msgstr "URL für Updates beim weltweiten Verzeichnis"
#: ../../mod/admin.php:424
#: ../../mod/admin.php:426
msgid ""
"URL to update the global directory. If this is not set, the global directory"
" is completely unavailable to the application."
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"
msgstr "Unterbinde Mehrfachregistrierung"
#: ../../mod/admin.php:426
#: ../../mod/admin.php:428
msgid "Disallow users to register additional accounts for use as pages."
msgstr "Benutzern nicht erlauben, weitere Accounts als zusätzliche Profile anzulegen."
#: ../../mod/admin.php:427
#: ../../mod/admin.php:429
msgid "OpenID support"
msgstr "OpenID Unterstützung"
#: ../../mod/admin.php:427
#: ../../mod/admin.php:429
msgid "OpenID support for registration and logins."
msgstr "OpenID-Unterstützung für Registrierung und Login."
#: ../../mod/admin.php:428
#: ../../mod/admin.php:430
msgid "Fullname check"
msgstr "Namen auf Vollständigkeit überprüfen"
#: ../../mod/admin.php:428
#: ../../mod/admin.php:430
msgid ""
"Force users to register with a space between firstname and lastname in Full "
"name, as an antispam measure"
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"
msgstr "UTF-8 Reguläre Ausdrücke"
#: ../../mod/admin.php:429
#: ../../mod/admin.php:431
msgid "Use PHP UTF8 regular expressions"
msgstr "PHP UTF8 Ausdrücke verwenden"
#: ../../mod/admin.php:430
#: ../../mod/admin.php:432
msgid "Show Community Page"
msgstr "Gemeinschaftsseite anzeigen"
#: ../../mod/admin.php:430
#: ../../mod/admin.php:432
msgid ""
"Display a Community page showing all recent public postings on this site."
msgstr "Zeige die Gemeinschaftsseite mit allen öffentlichen Beiträgen auf diesem Server."
#: ../../mod/admin.php:431
#: ../../mod/admin.php:433
msgid "Enable OStatus support"
msgstr "OStatus Unterstützung aktivieren"
#: ../../mod/admin.php:431
#: ../../mod/admin.php:433
msgid ""
"Provide built-in OStatus (identi.ca, status.net, etc.) compatibility. All "
"communications in OStatus are public, so privacy warnings will be "
"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."
#: ../../mod/admin.php:432
#: ../../mod/admin.php:434
msgid "Enable Diaspora support"
msgstr "Diaspora-Support aktivieren"
#: ../../mod/admin.php:432
#: ../../mod/admin.php:434
msgid "Provide built-in Diaspora network compatibility."
msgstr "Verwende die eingebaute Diaspora-Verknüpfung."
#: ../../mod/admin.php:433
#: ../../mod/admin.php:435
msgid "Only allow Friendica contacts"
msgstr "Nur Friendica-Kontakte erlauben"
#: ../../mod/admin.php:433
#: ../../mod/admin.php:435
msgid ""
"All contacts must use Friendica protocols. All other built-in communication "
"protocols disabled."
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"
msgstr "SSL Überprüfen"
#: ../../mod/admin.php:434
#: ../../mod/admin.php:436
msgid ""
"If you wish, you can turn on strict certificate checking. This will mean you"
" 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."
#: ../../mod/admin.php:435
#: ../../mod/admin.php:437
msgid "Proxy user"
msgstr "Proxy Nutzer"
#: ../../mod/admin.php:436
#: ../../mod/admin.php:438
msgid "Proxy URL"
msgstr "Proxy URL"
#: ../../mod/admin.php:437
#: ../../mod/admin.php:439
msgid "Network timeout"
msgstr "Netzwerk Wartezeit"
#: ../../mod/admin.php:437
#: ../../mod/admin.php:439
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)."
#: ../../mod/admin.php:438
#: ../../mod/admin.php:440
msgid "Delivery interval"
msgstr "Zustellungsintervall"
#: ../../mod/admin.php:438
#: ../../mod/admin.php:440
msgid ""
"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."
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"
msgstr "Maximum Load Average"
#: ../../mod/admin.php:439
#: ../../mod/admin.php:442
msgid ""
"Maximum system load before delivery and poll processes are deferred - "
"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"
msgstr "Update wurde als erfolgreich markiert"
#: ../../mod/admin.php:463
#: ../../mod/admin.php:466
#, php-format
msgid "Executing %s failed. Check system logs."
msgstr "Ausführung von %s schlug fehl. Systemprotokolle prüfen."
#: ../../mod/admin.php:466
#: ../../mod/admin.php:469
#, php-format
msgid "Update %s was successfully applied."
msgstr "Update %s war erfolgreich."
#: ../../mod/admin.php:470
#: ../../mod/admin.php:473
#, php-format
msgid "Update %s did not return a status. Unknown if it succeeded."
msgstr "Update %s hat keinen Status zurückgegeben. Unbekannter Status."
#: ../../mod/admin.php:473
#: ../../mod/admin.php:476
#, php-format
msgid "Update function %s could not be found."
msgstr "Updatefunktion %s konnte nicht gefunden werden."
#: ../../mod/admin.php:488
#: ../../mod/admin.php:491
msgid "No failed updates."
msgstr "Keine fehlgeschlagenen Updates."
#: ../../mod/admin.php:492
#: ../../mod/admin.php:495
msgid "Failed Updates"
msgstr "Fehlgeschlagene Updates"
#: ../../mod/admin.php:493
#: ../../mod/admin.php:496
msgid ""
"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."
#: ../../mod/admin.php:494
#: ../../mod/admin.php:497
msgid "Mark success (if update was manually applied)"
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"
msgstr "Versuchen, diesen Schritt automatisch auszuführen"
#: ../../mod/admin.php:520
#: ../../mod/admin.php:523
#, php-format
msgid "%s user blocked/unblocked"
msgid_plural "%s users blocked/unblocked"
msgstr[0] "%s Benutzer geblockt/freigegeben"
msgstr[1] "%s Benutzer geblockt/freigegeben"
#: ../../mod/admin.php:527
#: ../../mod/admin.php:530
#, php-format
msgid "%s user deleted"
msgid_plural "%s users deleted"
msgstr[0] "%s Nutzer gelöscht"
msgstr[1] "%s Nutzer gelöscht"
#: ../../mod/admin.php:566
#: ../../mod/admin.php:569
#, php-format
msgid "User '%s' deleted"
msgstr "Nutzer '%s' gelöscht"
#: ../../mod/admin.php:574
#: ../../mod/admin.php:577
#, php-format
msgid "User '%s' unblocked"
msgstr "Nutzer '%s' entsperrt"
#: ../../mod/admin.php:574
#: ../../mod/admin.php:577
#, php-format
msgid "User '%s' blocked"
msgstr "Nutzer '%s' gesperrt"
#: ../../mod/admin.php:638
#: ../../mod/admin.php:641
msgid "select all"
msgstr "Alle auswählen"
#: ../../mod/admin.php:639
#: ../../mod/admin.php:642
msgid "User registrations waiting for confirm"
msgstr "Neuanmeldungen, die auf deine Bestätigung warten"
#: ../../mod/admin.php:640
#: ../../mod/admin.php:643
msgid "Request date"
msgstr "Anfrage Datum"
#: ../../mod/admin.php:640 ../../mod/admin.php:649
#: ../../mod/admin.php:643 ../../mod/admin.php:652
#: ../../include/contact_selectors.php:79
msgid "Email"
msgstr "Email"
#: ../../mod/admin.php:641
#: ../../mod/admin.php:644
msgid "No registrations."
msgstr "Keine Neuanmeldungen."
#: ../../mod/admin.php:643
#: ../../mod/admin.php:646
msgid "Deny"
msgstr "Verwehren"
#: ../../mod/admin.php:649
#: ../../mod/admin.php:652
msgid "Register date"
msgstr "Anmeldedatum"
#: ../../mod/admin.php:649
#: ../../mod/admin.php:652
msgid "Last login"
msgstr "Letzte Anmeldung"
#: ../../mod/admin.php:649
#: ../../mod/admin.php:652
msgid "Last item"
msgstr "Letzter Beitrag"
#: ../../mod/admin.php:649
#: ../../mod/admin.php:652
msgid "Account"
msgstr "Nutzerkonto"
#: ../../mod/admin.php:651
#: ../../mod/admin.php:654
msgid ""
"Selected users will be deleted!\\n\\nEverything these users had posted on "
"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?"
#: ../../mod/admin.php:652
#: ../../mod/admin.php:655
msgid ""
"The user {0} will be deleted!\\n\\nEverything this user has posted on this "
"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?"
#: ../../mod/admin.php:693
#: ../../mod/admin.php:696
#, php-format
msgid "Plugin %s disabled."
msgstr "Plugin %s deaktiviert."
#: ../../mod/admin.php:697
#: ../../mod/admin.php:700
#, php-format
msgid "Plugin %s enabled."
msgstr "Plugin %s aktiviert."
#: ../../mod/admin.php:707 ../../mod/admin.php:905
#: ../../mod/admin.php:710 ../../mod/admin.php:908
msgid "Disable"
msgstr "Ausschalten"
#: ../../mod/admin.php:709 ../../mod/admin.php:907
#: ../../mod/admin.php:712 ../../mod/admin.php:910
msgid "Enable"
msgstr "Einschalten"
#: ../../mod/admin.php:731 ../../mod/admin.php:936
#: ../../mod/admin.php:734 ../../mod/admin.php:939
msgid "Toggle"
msgstr "Umschalten"
#: ../../mod/admin.php:739 ../../mod/admin.php:946
#: ../../mod/admin.php:742 ../../mod/admin.php:949
msgid "Author: "
msgstr "Autor:"
#: ../../mod/admin.php:740 ../../mod/admin.php:947
#: ../../mod/admin.php:743 ../../mod/admin.php:950
msgid "Maintainer: "
msgstr "Betreuer:"
#: ../../mod/admin.php:869
#: ../../mod/admin.php:872
msgid "No themes found."
msgstr "Keine Themen gefunden."
#: ../../mod/admin.php:928
#: ../../mod/admin.php:931
msgid "Screenshot"
msgstr "Bildschirmfoto"
#: ../../mod/admin.php:976
#: ../../mod/admin.php:979
msgid "[Experimental]"
msgstr "[Experimentell]"
#: ../../mod/admin.php:977
#: ../../mod/admin.php:980
msgid "[Unsupported]"
msgstr "[Nicht unterstützt]"
#: ../../mod/admin.php:1004
#: ../../mod/admin.php:1007
msgid "Log settings updated."
msgstr "Protokolleinstellungen aktualisiert."
#: ../../mod/admin.php:1060
#: ../../mod/admin.php:1063
msgid "Clear"
msgstr "löschen"
#: ../../mod/admin.php:1066
#: ../../mod/admin.php:1069
msgid "Debugging"
msgstr "Protokoll führen"
#: ../../mod/admin.php:1067
#: ../../mod/admin.php:1070
msgid "Log file"
msgstr "Protokolldatei"
#: ../../mod/admin.php:1067
#: ../../mod/admin.php:1070
msgid ""
"Must be writable by web server. Relative to your Friendica top-level "
"directory."
msgstr "Webserver muss Schreibrechte besitzen. Abhängig vom Friendica-Installationsverzeichnis."
#: ../../mod/admin.php:1068
#: ../../mod/admin.php:1071
msgid "Log level"
msgstr "Protokoll-Level"
#: ../../mod/admin.php:1118 ../../view/theme/diabook/theme.php:599
#: ../../mod/admin.php:1121
msgid "Close"
msgstr "Schließen"
#: ../../mod/admin.php:1124
#: ../../mod/admin.php:1127
msgid "FTP Host"
msgstr "FTP Host"
#: ../../mod/admin.php:1125
#: ../../mod/admin.php:1128
msgid "FTP Path"
msgstr "FTP Pfad"
#: ../../mod/admin.php:1126
#: ../../mod/admin.php:1129
msgid "FTP User"
msgstr "FTP Nutzername"
#: ../../mod/admin.php:1127
#: ../../mod/admin.php:1130
msgid "FTP Password"
msgstr "FTP Passwort"
#: ../../mod/profile.php:21 ../../boot.php:949
#: ../../mod/profile.php:21 ../../boot.php:959
msgid "Requested profile is not available."
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."
msgstr "Annmeldung fehlgeschlagen."
#: ../../mod/follow.php:27
#: ../../mod/follow.php:30
msgid "Connect URL missing."
msgstr "Connect-URL fehlt"
#: ../../mod/follow.php:47
#: ../../mod/follow.php:56
msgid ""
"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."
#: ../../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."
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."
msgstr "Die angegebene Profiladresse liefert unzureichende Informationen."
#: ../../mod/follow.php:65
#: ../../mod/follow.php:74
msgid "An author or name was not found."
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."
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 ""
"The profile address specified belongs to a network which has been disabled "
"on this site."
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 ""
"Limited profile. This person will be unable to receive direct/personal "
"notifications from you."
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."
msgstr "Konnte die Kontaktinformationen nicht empfangen."
#: ../../mod/follow.php:195
#: ../../mod/follow.php:206
msgid "following"
msgstr "folgen"
@ -4000,27 +4021,27 @@ msgstr "Alter: "
msgid "Edit/Manage Profiles"
msgstr "Verwalte/Editiere Profile"
#: ../../mod/profiles.php:621 ../../boot.php:1058
#: ../../mod/profiles.php:621 ../../boot.php:1068
msgid "Change profile photo"
msgstr "Profilbild ändern"
#: ../../mod/profiles.php:622 ../../boot.php:1059
#: ../../mod/profiles.php:622 ../../boot.php:1069
msgid "Create New Profile"
msgstr "Neues Profil anlegen"
#: ../../mod/profiles.php:633 ../../boot.php:1069
#: ../../mod/profiles.php:633 ../../boot.php:1079
msgid "Profile Image"
msgstr "Profilbild"
#: ../../mod/profiles.php:635 ../../boot.php:1072
#: ../../mod/profiles.php:635 ../../boot.php:1082
msgid "visible to everybody"
msgstr "sichtbar für jeden"
#: ../../mod/profiles.php:636 ../../boot.php:1073
#: ../../mod/profiles.php:636 ../../boot.php:1083
msgid "Edit visibility"
msgstr "Sichtbarkeit bearbeiten"
#: ../../mod/filer.php:29 ../../include/conversation.php:922
#: ../../mod/filer.php:29 ../../include/conversation.php:925
msgid "Save to Folder:"
msgstr "In diesen Ordner verschieben:"
@ -4068,7 +4089,7 @@ msgstr "Hinzufügen"
msgid "No entries."
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
msgid "Friend Suggestions"
msgstr "Kontaktvorschläge"
@ -4083,7 +4104,7 @@ msgstr "Keine Vorschläge. Falls der Server frisch aufgesetzt wurde, versuche es
msgid "Ignore/Hide"
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"
msgstr "Weltweites Verzeichnis"
@ -4312,13 +4333,13 @@ msgstr "Veröffentliche standardmäßig bei Facebook"
msgid ""
"Facebook friend linking has been disabled on this site. The following "
"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
msgid ""
"Facebook friend linking has been disabled on this site. If you disable 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
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."
msgstr "NSFW-Einstellungen gespeichert"
#: ../../addon/nsfw/nsfw.php:120
#: ../../addon/nsfw/nsfw.php:121
#, php-format
msgid "%s - Click to open/close"
msgstr "%s Zum Öffnen/Schließen klicken"
@ -4621,8 +4642,8 @@ msgid "Forums"
msgstr "Foren"
#: ../../addon/page/page.php:63 ../../addon/showmore/showmore.php:87
#: ../../include/contact_widgets.php:187 ../../include/conversation.php:466
#: ../../boot.php:507
#: ../../include/contact_widgets.php:188 ../../include/conversation.php:469
#: ../../boot.php:517
msgid "show more"
msgstr "mehr anzeigen"
@ -4638,7 +4659,7 @@ msgstr "Aktiviere Planeten Plugin"
#: ../../addon/communityhome/communityhome.php:34
#: ../../addon/communityhome/twillingham/communityhome.php:28
#: ../../addon/communityhome/twillingham/communityhome.php:34
#: ../../include/nav.php:64 ../../boot.php:805
#: ../../include/nav.php:64 ../../boot.php:815
msgid "Login"
msgstr "Anmeldung"
@ -4666,7 +4687,7 @@ msgid "Latest likes"
msgstr "Neueste Favoriten"
#: ../../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
msgid "event"
msgstr "Veranstaltung"
@ -4819,7 +4840,7 @@ msgid "Post to Drupal by default"
msgstr "Veröffentliche öffentliche Beiträge standardmäßig bei Drupal"
#: ../../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"
msgstr "Beitrag via Friendica"
@ -5533,32 +5554,40 @@ msgstr "Blogger-API-URL"
msgid "Post to Blogger by default"
msgstr "Standardmäßig auf Blogger posten"
#: ../../addon/posterous/posterous.php:36
#: ../../addon/posterous/posterous.php:37
msgid "Post to Posterous"
msgstr "Nach Posterous senden"
#: ../../addon/posterous/posterous.php:67
#: ../../addon/posterous/posterous.php:70
msgid "Posterous Post Settings"
msgstr "Posterous Beitrags-Einstellungen"
#: ../../addon/posterous/posterous.php:69
#: ../../addon/posterous/posterous.php:72
msgid "Enable Posterous Post Plugin"
msgstr "Posterous-Plugin aktivieren"
#: ../../addon/posterous/posterous.php:74
#: ../../addon/posterous/posterous.php:77
msgid "Posterous login"
msgstr "Posterous-Anmeldename"
#: ../../addon/posterous/posterous.php:79
#: ../../addon/posterous/posterous.php:82
msgid "Posterous password"
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"
msgstr "Veröffentliche öffentliche Beiträge standardmäßig bei Posterous"
#: ../../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
msgid "Theme settings"
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)"
#: ../../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"
msgstr "Schriftgröße für Beiträge und Kommentare festlegen"
@ -5581,105 +5611,177 @@ msgstr "Theme Breite festlegen"
msgid "Color scheme"
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
msgid "Your posts and conversations"
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"
msgstr "Deine Profilseite"
#: ../../view/theme/diabook/theme.php:67
#: ../../view/theme/diabook/theme.php:124
msgid "Your contacts"
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"
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"
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"
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"
msgstr "Deine privaten Fotos"
#: ../../view/theme/diabook/theme.php:72
#: ../../view/theme/diabook/theme.php:530
#: ../../view/theme/diabook/theme.php:129
#: ../../view/theme/diabook/theme.php:638
#: ../../view/theme/diabook/theme.php:742
#: ../../view/theme/diabook/config.php:201
msgid "Community Pages"
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"
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"
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"
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"
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"
msgstr "Freunde finden"
#: ../../view/theme/diabook/theme.php:510
#: ../../view/theme/diabook/theme.php:618
msgid "Local Directory"
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"
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"
msgstr "Freunde einladen"
#: ../../view/theme/diabook/theme.php:565
msgid "Earth View"
msgstr "Earth View"
#: ../../view/theme/diabook/theme.php:673
#: ../../view/theme/diabook/theme.php:743
#: ../../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 ?"
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"
msgstr "Verbinde Dienste"
#: ../../view/theme/diabook/theme.php:587
#: ../../view/theme/diabook/theme.php:707
#: ../../view/theme/diabook/theme.php:748
msgid "Last Tweets"
msgstr "Neueste Tweets"
#: ../../view/theme/diabook/theme.php:591
#: ../../view/theme/diabook/config.php:102
#: ../../view/theme/diabook/theme.php:710
#: ../../view/theme/diabook/config.php:197
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"
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"
msgstr "Auflösung für die Mittelspalte setzen"
#: ../../view/theme/diabook/config.php:101
#: ../../view/theme/diabook/config.php:196
msgid "Set color scheme"
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
msgid "Alignment"
msgstr "Ausrichtung"
@ -5696,7 +5798,7 @@ msgstr "Mitte"
msgid "Set colour scheme"
msgstr "Farbschema wählen"
#: ../../include/profile_advanced.php:17 ../../boot.php:1094
#: ../../include/profile_advanced.php:17 ../../boot.php:1104
msgid "Gender:"
msgstr "Geschlecht:"
@ -5709,7 +5811,7 @@ msgid "j F"
msgstr "j F"
#: ../../include/profile_advanced.php:30 ../../include/datetime.php:448
#: ../../include/items.php:1403
#: ../../include/items.php:1413
msgid "Birthday:"
msgstr "Geburtstag:"
@ -5717,11 +5819,11 @@ msgstr "Geburtstag:"
msgid "Age:"
msgstr "Alter:"
#: ../../include/profile_advanced.php:37 ../../boot.php:1097
#: ../../include/profile_advanced.php:37 ../../boot.php:1107
msgid "Status:"
msgstr "Status:"
#: ../../include/profile_advanced.php:45 ../../boot.php:1099
#: ../../include/profile_advanced.php:45 ../../boot.php:1109
msgid "Homepage:"
msgstr "Homepage:"
@ -6085,11 +6187,11 @@ msgstr "Beginnt:"
msgid "Finishes:"
msgstr "Endet:"
#: ../../include/delivery.php:445 ../../include/notifier.php:652
#: ../../include/delivery.php:452 ../../include/notifier.php:652
msgid "(no subject)"
msgstr "(kein Betreff)"
#: ../../include/delivery.php:452 ../../include/enotify.php:23
#: ../../include/delivery.php:459 ../../include/enotify.php:23
#: ../../include/notifier.php:659
msgid "noreply"
msgstr "noreply"
@ -6305,7 +6407,7 @@ msgstr "Neue Gruppe erstellen"
msgid "Contacts not in any group"
msgstr "Kontakte in keiner Gruppe"
#: ../../include/nav.php:46 ../../boot.php:804
#: ../../include/nav.php:46 ../../boot.php:814
msgid "Logout"
msgstr "Abmelden"
@ -6313,7 +6415,7 @@ msgstr "Abmelden"
msgid "End this session"
msgstr "Diese Sitzung beenden"
#: ../../include/nav.php:49 ../../boot.php:1472
#: ../../include/nav.php:49 ../../boot.php:1482
msgid "Status"
msgstr "Status"
@ -6393,11 +6495,11 @@ msgstr "Verwalten"
msgid "Manage other pages"
msgstr "Andere Seiten verwalten"
#: ../../include/nav.php:138 ../../boot.php:1052
#: ../../include/nav.php:138 ../../boot.php:1062
msgid "Profiles"
msgstr "Profile"
#: ../../include/nav.php:138 ../../boot.php:1052
#: ../../include/nav.php:138 ../../boot.php:1062
msgid "Manage/edit profiles"
msgstr "Profile verwalten/editieren"
@ -6563,7 +6665,7 @@ msgstr "Sekunden"
msgid "%1$d %2$s ago"
msgstr "%1$d %2$s her"
#: ../../include/onepoll.php:402
#: ../../include/onepoll.php:406
msgid "From: "
msgstr "Von: "
@ -6588,14 +6690,6 @@ msgstr "[kein Betreff]"
msgid "Visible to everybody"
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
msgid "Friendica Notification"
msgstr "Friendica-Benachrichtigung"
@ -6784,11 +6878,11 @@ msgstr "Foto:"
msgid "Please visit %s to approve or reject the suggestion."
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 "
msgstr "Eine neue Person teilt mit dir auf "
#: ../../include/items.php:2714
#: ../../include/items.php:2724
msgid "You have a new follower at "
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"
msgstr "wird nicht mehr gefolgt"
#: ../../include/Contact.php:203 ../../include/conversation.php:817
#: ../../include/Contact.php:203 ../../include/conversation.php:820
msgid "View Status"
msgstr "Pinnwand anschauen"
#: ../../include/Contact.php:204 ../../include/conversation.php:818
#: ../../include/Contact.php:204 ../../include/conversation.php:821
msgid "View Profile"
msgstr "Profil anschauen"
#: ../../include/Contact.php:205 ../../include/conversation.php:819
#: ../../include/Contact.php:205 ../../include/conversation.php:822
msgid "View Photos"
msgstr "Bilder anschauen"
#: ../../include/Contact.php:206 ../../include/Contact.php:219
#: ../../include/conversation.php:820
#: ../../include/conversation.php:823
msgid "Network Posts"
msgstr "Netzwerk-Beiträge"
#: ../../include/Contact.php:207 ../../include/Contact.php:219
#: ../../include/conversation.php:821
#: ../../include/conversation.php:824
msgid "Edit Contact"
msgstr "Kontakt bearbeiten"
#: ../../include/Contact.php:208 ../../include/Contact.php:219
#: ../../include/conversation.php:822
#: ../../include/conversation.php:825
msgid "Send PM"
msgstr "Private Nachricht senden"
@ -6859,309 +6953,309 @@ msgstr "Nachricht/Beitrag"
msgid "%1$s marked %2$s's %3$s as favorite"
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"
msgstr "Auswählen"
#: ../../include/conversation.php:334 ../../include/conversation.php:676
#: ../../include/conversation.php:677
#: ../../include/conversation.php:337 ../../include/conversation.php:679
#: ../../include/conversation.php:680
#, php-format
msgid "View %s's profile @ %s"
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
msgid "%s from %s"
msgstr "%s von %s"
#: ../../include/conversation.php:359
#: ../../include/conversation.php:362
msgid "View in context"
msgstr "Im Zusammenhang betrachten"
#: ../../include/conversation.php:465
#: ../../include/conversation.php:468
#, php-format
msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] "%d Kommentar"
msgstr[1] "%d Kommentare"
#: ../../include/conversation.php:529
#: ../../include/conversation.php:532
msgid "like"
msgstr "mag ich"
#: ../../include/conversation.php:530
#: ../../include/conversation.php:533
msgid "dislike"
msgstr "mag ich nicht"
#: ../../include/conversation.php:532
#: ../../include/conversation.php:535
msgid "Share this"
msgstr "Teile dieses"
#: ../../include/conversation.php:532
#: ../../include/conversation.php:535
msgid "share"
msgstr "Teilen"
#: ../../include/conversation.php:556
#: ../../include/conversation.php:559
msgid "Bold"
msgstr "Fett"
#: ../../include/conversation.php:557
#: ../../include/conversation.php:560
msgid "Italic"
msgstr "Kursiv"
#: ../../include/conversation.php:558
#: ../../include/conversation.php:561
msgid "Underline"
msgstr "Unterstrichen"
#: ../../include/conversation.php:559
#: ../../include/conversation.php:562
msgid "Quote"
msgstr "Zitat"
#: ../../include/conversation.php:560
#: ../../include/conversation.php:563
msgid "Code"
msgstr "Code"
#: ../../include/conversation.php:561
#: ../../include/conversation.php:564
msgid "Image"
msgstr "Bild"
#: ../../include/conversation.php:562
#: ../../include/conversation.php:565
msgid "Link"
msgstr "Verweis"
#: ../../include/conversation.php:563
#: ../../include/conversation.php:566
msgid "Video"
msgstr "Video"
#: ../../include/conversation.php:596
#: ../../include/conversation.php:599
msgid "add star"
msgstr "markieren"
#: ../../include/conversation.php:597
#: ../../include/conversation.php:600
msgid "remove star"
msgstr "Markierung entfernen"
#: ../../include/conversation.php:598
#: ../../include/conversation.php:601
msgid "toggle star status"
msgstr "Markierung umschalten"
#: ../../include/conversation.php:601
#: ../../include/conversation.php:604
msgid "starred"
msgstr "markiert"
#: ../../include/conversation.php:602
#: ../../include/conversation.php:605
msgid "add tag"
msgstr "Tag hinzufügen"
#: ../../include/conversation.php:606
#: ../../include/conversation.php:609
msgid "save to folder"
msgstr "In Ordner speichern"
#: ../../include/conversation.php:678
#: ../../include/conversation.php:681
msgid "to"
msgstr "zu"
#: ../../include/conversation.php:679
#: ../../include/conversation.php:682
msgid "Wall-to-Wall"
msgstr "Wall-to-Wall"
#: ../../include/conversation.php:680
#: ../../include/conversation.php:683
msgid "via Wall-To-Wall:"
msgstr "via Wall-To-Wall:"
#: ../../include/conversation.php:725
#: ../../include/conversation.php:728
msgid "Delete Selected Items"
msgstr "Lösche die markierten Beiträge"
#: ../../include/conversation.php:876
#: ../../include/conversation.php:879
#, php-format
msgid "%s likes this."
msgstr "%s mag das."
#: ../../include/conversation.php:876
#: ../../include/conversation.php:879
#, php-format
msgid "%s doesn't like this."
msgstr "%s mag das nicht."
#: ../../include/conversation.php:880
#: ../../include/conversation.php:883
#, php-format
msgid "<span %1$s>%2$d people</span> like this."
msgstr "<span %1$s>%2$d Leute</span> mögen das."
#: ../../include/conversation.php:882
#: ../../include/conversation.php:885
#, php-format
msgid "<span %1$s>%2$d people</span> don't like this."
msgstr "<span %1$s>%2$d Leute</span> mögen das nicht."
#: ../../include/conversation.php:888
#: ../../include/conversation.php:891
msgid "and"
msgstr "und"
#: ../../include/conversation.php:891
#: ../../include/conversation.php:894
#, php-format
msgid ", and %d other people"
msgstr " und %d andere"
#: ../../include/conversation.php:892
#: ../../include/conversation.php:895
#, php-format
msgid "%s like this."
msgstr "%s mögen das."
#: ../../include/conversation.php:892
#: ../../include/conversation.php:895
#, php-format
msgid "%s don't like this."
msgstr "%s mögen das nicht."
#: ../../include/conversation.php:917
#: ../../include/conversation.php:920
msgid "Visible to <strong>everybody</strong>"
msgstr "Für <strong>jedermann</strong> sichtbar"
#: ../../include/conversation.php:919
#: ../../include/conversation.php:922
msgid "Please enter a video link/URL:"
msgstr "Bitte Link/URL zum Video einfügen:"
#: ../../include/conversation.php:920
#: ../../include/conversation.php:923
msgid "Please enter an audio link/URL:"
msgstr "Bitte Link/URL zum Audio einfügen:"
#: ../../include/conversation.php:921
#: ../../include/conversation.php:924
msgid "Tag term:"
msgstr "Tag:"
#: ../../include/conversation.php:923
#: ../../include/conversation.php:926
msgid "Where are you right now?"
msgstr "Wo hältst du dich jetzt gerade auf?"
#: ../../include/conversation.php:966
#: ../../include/conversation.php:969
msgid "upload photo"
msgstr "Bild hochladen"
#: ../../include/conversation.php:968
#: ../../include/conversation.php:971
msgid "attach file"
msgstr "Datei anhängen"
#: ../../include/conversation.php:970
#: ../../include/conversation.php:973
msgid "web link"
msgstr "Weblink"
#: ../../include/conversation.php:971
#: ../../include/conversation.php:974
msgid "Insert video link"
msgstr "Video-Adresse einfügen"
#: ../../include/conversation.php:972
#: ../../include/conversation.php:975
msgid "video link"
msgstr "Video-Link"
#: ../../include/conversation.php:973
#: ../../include/conversation.php:976
msgid "Insert audio link"
msgstr "Audio-Adresse einfügen"
#: ../../include/conversation.php:974
#: ../../include/conversation.php:977
msgid "audio link"
msgstr "Audio-Link"
#: ../../include/conversation.php:976
#: ../../include/conversation.php:979
msgid "set location"
msgstr "Ort setzen"
#: ../../include/conversation.php:978
#: ../../include/conversation.php:981
msgid "clear location"
msgstr "Ort löschen"
#: ../../include/conversation.php:985
#: ../../include/conversation.php:988
msgid "permissions"
msgstr "Zugriffsrechte"
#: ../../boot.php:505
#: ../../boot.php:515
msgid "Delete this item?"
msgstr "Diesen Beitrag löschen?"
#: ../../boot.php:508
#: ../../boot.php:518
msgid "show fewer"
msgstr "weniger anzeigen"
#: ../../boot.php:681
#: ../../boot.php:691
#, php-format
msgid "Update %s failed. See error logs."
msgstr "Update %s fehlgeschlagen. Bitte Fehlerprotokoll überprüfen."
#: ../../boot.php:683
#: ../../boot.php:693
#, php-format
msgid "Update Error at %s"
msgstr "Updatefehler bei %s"
#: ../../boot.php:783
#: ../../boot.php:793
msgid "Create a New Account"
msgstr "Neuen Account erstellen"
#: ../../boot.php:807
#: ../../boot.php:817
msgid "Nickname or Email address: "
msgstr "Spitzname oder Email-Adresse: "
#: ../../boot.php:808
#: ../../boot.php:818
msgid "Password: "
msgstr "Passwort: "
#: ../../boot.php:811
#: ../../boot.php:821
msgid "Or login using OpenID: "
msgstr "Oder melde dich mit deiner OpenID an: "
#: ../../boot.php:817
#: ../../boot.php:827
msgid "Forgot your password?"
msgstr "Passwort vergessen?"
#: ../../boot.php:984
#: ../../boot.php:994
msgid "Edit profile"
msgstr "Profil bearbeiten"
#: ../../boot.php:1044
#: ../../boot.php:1054
msgid "Message"
msgstr "Nachricht"
#: ../../boot.php:1160 ../../boot.php:1236
#: ../../boot.php:1170 ../../boot.php:1246
msgid "g A l F d"
msgstr "l, d. F G \\U\\h\\r"
#: ../../boot.php:1161 ../../boot.php:1237
#: ../../boot.php:1171 ../../boot.php:1247
msgid "F d"
msgstr "d. F"
#: ../../boot.php:1206 ../../boot.php:1277
#: ../../boot.php:1216 ../../boot.php:1287
msgid "[today]"
msgstr "[heute]"
#: ../../boot.php:1218
#: ../../boot.php:1228
msgid "Birthday Reminders"
msgstr "Geburtstagserinnerungen"
#: ../../boot.php:1219
#: ../../boot.php:1229
msgid "Birthdays this week:"
msgstr "Geburtstage diese Woche:"
#: ../../boot.php:1270
#: ../../boot.php:1280
msgid "[No description]"
msgstr "[keine Beschreibung]"
#: ../../boot.php:1288
#: ../../boot.php:1298
msgid "Event Reminders"
msgstr "Veranstaltungserinnerungen"
#: ../../boot.php:1289
#: ../../boot.php:1299
msgid "Events this week:"
msgstr "Veranstaltungen diese Woche"
#: ../../boot.php:1475
#: ../../boot.php:1485
msgid "Status Messages and Posts"
msgstr "Statusnachrichten und Beiträge"
#: ../../boot.php:1481
#: ../../boot.php:1491
msgid "Profile Details"
msgstr "Profildetails"
#: ../../boot.php:1496
#: ../../boot.php:1506
msgid "Events and Calendar"
msgstr "Ereignisse und Kalender"
#: ../../boot.php:1502
#: ../../boot.php:1512
msgid "Only You Can See This"
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["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["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 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["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.";
@ -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["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["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["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.";
@ -972,8 +976,8 @@ $a->strings["Install Facebook connector for this account."] = "Facebook-Connecto
$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["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. If you disable it, you will be unable to re-enable it."] = "";
$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."] = "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["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.";
@ -1255,6 +1259,8 @@ $a->strings["Posterous Post Settings"] = "Posterous Beitrags-Einstellungen";
$a->strings["Enable Posterous Post Plugin"] = "Posterous-Plugin aktivieren";
$a->strings["Posterous login"] = "Posterous-Anmeldename";
$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["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)";
@ -1277,14 +1283,22 @@ $a->strings["Find Friends"] = "Freunde finden";
$a->strings["Local Directory"] = "Lokales Verzeichnis";
$a->strings["Similar Interests"] = "Ähnliche Interessen";
$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["Connect Services"] = "Verbinde Dienste";
$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 resolution for middle column"] = "Auflösung für die Mittelspalte setzen";
$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["Left"] = "Links";
$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["[no subject]"] = "[kein Betreff]";
$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["Thank You,"] = "Danke,";
$a->strings["%s Administrator"] = "der Administrator von %s";

View file

@ -45,3 +45,17 @@ nav #site-location {
-moz-border-radius: 3px;
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;
}