effective_ckeditor 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/ckeditor/CHANGES.md +16 -1
- data/app/assets/javascripts/ckeditor/LICENSE.md +1 -1
- data/app/assets/javascripts/ckeditor/adapters/jquery.js +1 -1
- data/app/assets/javascripts/ckeditor/build-config.js +54 -50
- data/app/assets/javascripts/ckeditor/ckeditor.js +482 -460
- data/app/assets/javascripts/ckeditor/config.js +1 -1
- data/app/assets/javascripts/ckeditor/contents.css +1 -1
- data/app/assets/javascripts/ckeditor/lang/en.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/clipboard/dialogs/paste.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/colordialog/dialogs/colordialog.js +3 -3
- data/app/assets/javascripts/ckeditor/plugins/dialog/dialogDefinition.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/find/dialogs/find.js +21 -21
- data/app/assets/javascripts/ckeditor/plugins/footnotes/dialogs/footnotes.js +166 -0
- data/app/assets/javascripts/ckeditor/plugins/footnotes/icons/footnotes.png +0 -0
- data/app/assets/javascripts/ckeditor/plugins/footnotes/plugin.js +305 -0
- data/app/assets/javascripts/ckeditor/plugins/image/dialogs/image.js +3 -3
- data/app/assets/javascripts/ckeditor/plugins/image2/dialogs/image2.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/link/dialogs/anchor.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/link/dialogs/link.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/liststyle/dialogs/liststyle.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/pastefromword/filter/default.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/sourcedialog/dialogs/sourcedialog.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/table/dialogs/table.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/tabletools/dialogs/tableCell.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/templates/dialogs/templates.css +1 -1
- data/app/assets/javascripts/ckeditor/plugins/templates/dialogs/templates.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/templates/templates/default.js +1 -1
- data/app/assets/javascripts/ckeditor/plugins/tliyoutube/dialogs/tliyoutube.js +1 -1
- data/app/assets/javascripts/ckeditor/styles.js +1 -1
- data/app/assets/javascripts/effective_ckeditor/config.js.coffee +4 -2
- data/app/assets/stylesheets/effective_ckeditor/overrides.scss +1 -0
- data/lib/effective_ckeditor/version.rb +1 -1
- metadata +5 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
Copyright (c) 2003-
|
2
|
+
Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
|
3
3
|
For licensing, see LICENSE.html or http://ckeditor.com/license
|
4
4
|
*/
|
5
5
|
CKEDITOR.lang['en']={"editor":"Rich Text Editor","editorPanel":"Rich Text Editor panel","common":{"editorHelp":"Press ALT 0 for help","browseServer":"Browse Server","url":"URL","protocol":"Protocol","upload":"Upload","uploadSubmit":"Send it to the Server","image":"Image","flash":"Flash","form":"Form","checkbox":"Checkbox","radio":"Radio Button","textField":"Text Field","textarea":"Textarea","hiddenField":"Hidden Field","button":"Button","select":"Selection Field","imageButton":"Image Button","notSet":"<not set>","id":"Id","name":"Name","langDir":"Language Direction","langDirLtr":"Left to Right (LTR)","langDirRtl":"Right to Left (RTL)","langCode":"Language Code","longDescr":"Long Description URL","cssClass":"Stylesheet Classes","advisoryTitle":"Advisory Title","cssStyle":"Style","ok":"OK","cancel":"Cancel","close":"Close","preview":"Preview","resize":"Resize","generalTab":"General","advancedTab":"Advanced","validateNumberFailed":"This value is not a number.","confirmNewPage":"Any unsaved changes to this content will be lost. Are you sure you want to load new page?","confirmCancel":"You have changed some options. Are you sure you want to close the dialog window?","options":"Options","target":"Target","targetNew":"New Window (_blank)","targetTop":"Topmost Window (_top)","targetSelf":"Same Window (_self)","targetParent":"Parent Window (_parent)","langDirLTR":"Left to Right (LTR)","langDirRTL":"Right to Left (RTL)","styles":"Style","cssClasses":"Stylesheet Classes","width":"Width","height":"Height","align":"Alignment","alignLeft":"Left","alignRight":"Right","alignCenter":"Center","alignJustify":"Justify","alignTop":"Top","alignMiddle":"Middle","alignBottom":"Bottom","alignNone":"None","invalidValue":"Invalid value.","invalidHeight":"Height must be a number.","invalidWidth":"Width must be a number.","invalidCssLength":"Value specified for the \"%1\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).","invalidHtmlLength":"Value specified for the \"%1\" field must be a positive number with or without a valid HTML measurement unit (px or %).","invalidInlineStyle":"Value specified for the inline style must consist of one or more tuples with the format of \"name : value\", separated by semi-colons.","cssLengthTooltip":"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).","unavailable":"%1<span class=\"cke_accessibility\">, unavailable</span>"},"basicstyles":{"bold":"Bold","italic":"Italic","strike":"Strikethrough","subscript":"Subscript","superscript":"Superscript","underline":"Underline"},"blockquote":{"toolbar":"Block Quote"},"clipboard":{"copy":"Copy","copyError":"Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).","cut":"Cut","cutError":"Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).","paste":"Paste","pasteArea":"Paste Area","pasteMsg":"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK","securityMsg":"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.","title":"Paste"},"button":{"selectedLabel":"%1 (Selected)"},"colorbutton":{"auto":"Automatic","bgColorTitle":"Background Color","colors":{"000":"Black","800000":"Maroon","8B4513":"Saddle Brown","2F4F4F":"Dark Slate Gray","008080":"Teal","000080":"Navy","4B0082":"Indigo","696969":"Dark Gray","B22222":"Fire Brick","A52A2A":"Brown","DAA520":"Golden Rod","006400":"Dark Green","40E0D0":"Turquoise","0000CD":"Medium Blue","800080":"Purple","808080":"Gray","F00":"Red","FF8C00":"Dark Orange","FFD700":"Gold","008000":"Green","0FF":"Cyan","00F":"Blue","EE82EE":"Violet","A9A9A9":"Dim Gray","FFA07A":"Light Salmon","FFA500":"Orange","FFFF00":"Yellow","00FF00":"Lime","AFEEEE":"Pale Turquoise","ADD8E6":"Light Blue","DDA0DD":"Plum","D3D3D3":"Light Grey","FFF0F5":"Lavender Blush","FAEBD7":"Antique White","FFFFE0":"Light Yellow","F0FFF0":"Honeydew","F0FFFF":"Azure","F0F8FF":"Alice Blue","E6E6FA":"Lavender","FFF":"White"},"more":"More Colors...","panelTitle":"Colors","textColorTitle":"Text Color"},"colordialog":{"clear":"Clear","highlight":"Highlight","options":"Color Options","selected":"Selected Color","title":"Select color"},"contextmenu":{"options":"Context Menu Options"},"elementspath":{"eleLabel":"Elements path","eleTitle":"%1 element"},"find":{"find":"Find","findOptions":"Find Options","findWhat":"Find what:","matchCase":"Match case","matchCyclic":"Match cyclic","matchWord":"Match whole word","notFoundMsg":"The specified text was not found.","replace":"Replace","replaceAll":"Replace All","replaceSuccessMsg":"%1 occurrence(s) replaced.","replaceWith":"Replace with:","title":"Find and Replace"},"format":{"label":"Format","panelTitle":"Paragraph Format","tag_address":"Address","tag_div":"Normal (DIV)","tag_h1":"Heading 1","tag_h2":"Heading 2","tag_h3":"Heading 3","tag_h4":"Heading 4","tag_h5":"Heading 5","tag_h6":"Heading 6","tag_p":"Normal","tag_pre":"Formatted"},"horizontalrule":{"toolbar":"Insert Horizontal Line"},"image":{"alertUrl":"Please type the image URL","alt":"Alternative Text","border":"Border","btnUpload":"Send it to the Server","button2Img":"Do you want to transform the selected image button on a simple image?","hSpace":"HSpace","img2Button":"Do you want to transform the selected image on a image button?","infoTab":"Image Info","linkTab":"Link","lockRatio":"Lock Ratio","menu":"Image Properties","resetSize":"Reset Size","title":"Image Properties","titleButton":"Image Button Properties","upload":"Upload","urlMissing":"Image source URL is missing.","vSpace":"VSpace","validateBorder":"Border must be a whole number.","validateHSpace":"HSpace must be a whole number.","validateVSpace":"VSpace must be a whole number."},"widget":{"move":"Click and drag to move"},"image2":{"alt":"Alternative Text","btnUpload":"Send it to the Server","captioned":"Captioned image","captionPlaceholder":"Caption","infoTab":"Image Info","lockRatio":"Lock Ratio","menu":"Image Properties","pathName":"image","pathNameCaption":"caption","resetSize":"Reset Size","resizer":"Click and drag to resize","title":"Image Properties","uploadTab":"Upload","urlMissing":"Image source URL is missing."},"indent":{"indent":"Increase Indent","outdent":"Decrease Indent"},"justify":{"block":"Justify","center":"Center","left":"Align Left","right":"Align Right"},"fakeobjects":{"anchor":"Anchor","flash":"Flash Animation","hiddenfield":"Hidden Field","iframe":"IFrame","unknown":"Unknown Object"},"link":{"acccessKey":"Access Key","advanced":"Advanced","advisoryContentType":"Advisory Content Type","advisoryTitle":"Advisory Title","anchor":{"toolbar":"Anchor","menu":"Edit Anchor","title":"Anchor Properties","name":"Anchor Name","errorName":"Please type the anchor name","remove":"Remove Anchor"},"anchorId":"By Element Id","anchorName":"By Anchor Name","charset":"Linked Resource Charset","cssClasses":"Stylesheet Classes","emailAddress":"E-Mail Address","emailBody":"Message Body","emailSubject":"Message Subject","id":"Id","info":"Link Info","langCode":"Language Code","langDir":"Language Direction","langDirLTR":"Left to Right (LTR)","langDirRTL":"Right to Left (RTL)","menu":"Edit Link","name":"Name","noAnchors":"(No anchors available in the document)","noEmail":"Please type the e-mail address","noUrl":"Please type the link URL","other":"<other>","popupDependent":"Dependent (Netscape)","popupFeatures":"Popup Window Features","popupFullScreen":"Full Screen (IE)","popupLeft":"Left Position","popupLocationBar":"Location Bar","popupMenuBar":"Menu Bar","popupResizable":"Resizable","popupScrollBars":"Scroll Bars","popupStatusBar":"Status Bar","popupToolbar":"Toolbar","popupTop":"Top Position","rel":"Relationship","selectAnchor":"Select an Anchor","styles":"Style","tabIndex":"Tab Index","target":"Target","targetFrame":"<frame>","targetFrameName":"Target Frame Name","targetPopup":"<popup window>","targetPopupName":"Popup Window Name","title":"Link","toAnchor":"Link to anchor in the text","toEmail":"E-mail","toUrl":"URL","toolbar":"Link","type":"Link Type","unlink":"Unlink","upload":"Upload"},"list":{"bulletedlist":"Insert/Remove Bulleted List","numberedlist":"Insert/Remove Numbered List"},"liststyle":{"armenian":"Armenian numbering","bulletedTitle":"Bulleted List Properties","circle":"Circle","decimal":"Decimal (1, 2, 3, etc.)","decimalLeadingZero":"Decimal leading zero (01, 02, 03, etc.)","disc":"Disc","georgian":"Georgian numbering (an, ban, gan, etc.)","lowerAlpha":"Lower Alpha (a, b, c, d, e, etc.)","lowerGreek":"Lower Greek (alpha, beta, gamma, etc.)","lowerRoman":"Lower Roman (i, ii, iii, iv, v, etc.)","none":"None","notset":"<not set>","numberedTitle":"Numbered List Properties","square":"Square","start":"Start","type":"Type","upperAlpha":"Upper Alpha (A, B, C, D, E, etc.)","upperRoman":"Upper Roman (I, II, III, IV, V, etc.)","validateStartNumber":"List start number must be a whole number."},"magicline":{"title":"Insert paragraph here"},"newpage":{"toolbar":"New Page"},"pagebreak":{"alt":"Page Break","toolbar":"Insert Page Break for Printing"},"pastefromword":{"confirmCleanup":"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?","error":"It was not possible to clean up the pasted data due to an internal error","title":"Paste from Word","toolbar":"Paste from Word"},"pastetext":{"button":"Paste as plain text","title":"Paste as Plain Text"},"removeformat":{"toolbar":"Remove Format"},"selectall":{"toolbar":"Select All"},"showblocks":{"toolbar":"Show Blocks"},"sourcearea":{"toolbar":"Source"},"sourcedialog":{"toolbar":"Source","title":"Source"},"stylescombo":{"label":"Styles","panelTitle":"Formatting Styles","panelTitle1":"Block Styles","panelTitle2":"Inline Styles","panelTitle3":"Object Styles"},"syntaxhighlight":{"title":"Add or update a code snippet","contextTitle":"Edit source code","sourceTab":"Source code","langLbl":"Select language","sourceTextareaEmptyError":"Source code mustn't be empty.","advancedTab":"Advanced","hideGutter":"Hide gutter","hideGutterLbl":"Hide gutter & line numbers.","hideControls":"Hide controls","hideControlsLbl":"Hide code controls at the top of the code block.","collapse":"Collapse","collapseLbl":"Collapse the code block by default. (controls need to be turned on)","codeTitleLbl":"Use a Code Title","showColumns":"Show columns","showColumnsLbl":"Show row columns in the first line.","lineWrap":"Disable line wrapping","lineWrapLbl":"Switch off line wrapping.","lineCount":"Default line count","highlight":"Highlight lines","highlightLbl":"Enter a comma seperated lines of lines you want to highlight, eg <em style=\"font-style:italic\">3,10,15</em>."},"table":{"border":"Border size","caption":"Caption","cell":{"menu":"Cell","insertBefore":"Insert Cell Before","insertAfter":"Insert Cell After","deleteCell":"Delete Cells","merge":"Merge Cells","mergeRight":"Merge Right","mergeDown":"Merge Down","splitHorizontal":"Split Cell Horizontally","splitVertical":"Split Cell Vertically","title":"Cell Properties","cellType":"Cell Type","rowSpan":"Rows Span","colSpan":"Columns Span","wordWrap":"Word Wrap","hAlign":"Horizontal Alignment","vAlign":"Vertical Alignment","alignBaseline":"Baseline","bgColor":"Background Color","borderColor":"Border Color","data":"Data","header":"Header","yes":"Yes","no":"No","invalidWidth":"Cell width must be a number.","invalidHeight":"Cell height must be a number.","invalidRowSpan":"Rows span must be a whole number.","invalidColSpan":"Columns span must be a whole number.","chooseColor":"Choose"},"cellPad":"Cell padding","cellSpace":"Cell spacing","column":{"menu":"Column","insertBefore":"Insert Column Before","insertAfter":"Insert Column After","deleteColumn":"Delete Columns"},"columns":"Columns","deleteTable":"Delete Table","headers":"Headers","headersBoth":"Both","headersColumn":"First column","headersNone":"None","headersRow":"First Row","invalidBorder":"Border size must be a number.","invalidCellPadding":"Cell padding must be a positive number.","invalidCellSpacing":"Cell spacing must be a positive number.","invalidCols":"Number of columns must be a number greater than 0.","invalidHeight":"Table height must be a number.","invalidRows":"Number of rows must be a number greater than 0.","invalidWidth":"Table width must be a number.","menu":"Table Properties","row":{"menu":"Row","insertBefore":"Insert Row Before","insertAfter":"Insert Row After","deleteRow":"Delete Rows"},"rows":"Rows","summary":"Summary","title":"Table Properties","toolbar":"Table","widthPc":"percent","widthPx":"pixels","widthUnit":"width unit"},"templates":{"button":"Templates","emptyListMsg":"(No templates defined)","insertOption":"Replace actual contents","options":"Template Options","selectPromptMsg":"Please select the template to open in the editor","title":"Content Templates"},"toolbar":{"toolbarCollapse":"Collapse Toolbar","toolbarExpand":"Expand Toolbar","toolbarGroups":{"document":"Document","clipboard":"Clipboard/Undo","editing":"Editing","forms":"Forms","basicstyles":"Basic Styles","paragraph":"Paragraph","links":"Links","insert":"Insert","styles":"Styles","colors":"Colors","tools":"Tools"},"toolbars":"Editor toolbars"},"undo":{"redo":"Redo","undo":"Undo"}};
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
Copyright (c) 2003-
|
2
|
+
Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
|
3
3
|
For licensing, see LICENSE.md or http://ckeditor.com/license
|
4
4
|
*/
|
5
5
|
CKEDITOR.dialog.add("paste",function(c){function h(a){var b=new CKEDITOR.dom.document(a.document),f=b.getBody(),d=b.getById("cke_actscrpt");d&&d.remove();f.setAttribute("contenteditable",!0);if(CKEDITOR.env.ie&&8>CKEDITOR.env.version)b.getWindow().on("blur",function(){b.$.selection.empty()});b.on("keydown",function(a){var a=a.data,b;switch(a.getKeystroke()){case 27:this.hide();b=1;break;case 9:case CKEDITOR.SHIFT+9:this.changeFocus(1),b=1}b&&a.preventDefault()},this);c.fire("ariaWidget",new CKEDITOR.dom.element(a.frameElement));
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
Copyright (c) 2003-
|
2
|
+
Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
|
3
3
|
For licensing, see LICENSE.md or http://ckeditor.com/license
|
4
4
|
*/
|
5
5
|
CKEDITOR.dialog.add("colordialog",function(t){function n(){f.getById(o).removeStyle("background-color");p.getContentElement("picker","selectedColor").setValue("");j&&j.removeAttribute("aria-selected");j=null}function u(a){var a=a.data.getTarget(),b;if("td"==a.getName()&&(b=a.getChild(0).getHtml()))j=a,j.setAttribute("aria-selected",!0),p.getContentElement("picker","selectedColor").setValue(b)}function y(a){for(var a=a.replace(/^#/,""),b=0,c=[];2>=b;b++)c[b]=parseInt(a.substr(2*b,2),16);return"#"+
|
@@ -9,5 +9,5 @@ else if(a=c.getParent().getNext())if((a=a.getChild([0]))&&1==a.type)a.focus(),b.
|
|
9
9
|
a;s<a+3;s++){var e=new r(i.$.insertRow(-1));e.setAttribute("role","row");for(var f=d;f<d+3;f++)for(var g=0;6>g;g++)b(e.$,"#"+c[f]+c[g]+c[s])}}function b(a,c){var b=new r(a.insertCell(-1));b.setAttribute("class","ColorCell");b.setAttribute("tabIndex",-1);b.setAttribute("role","gridcell");b.on("keydown",z);b.on("click",u);b.on("focus",v);b.on("blur",q);b.setStyle("background-color",c);b.setStyle("border","1px solid "+c);b.setStyle("width","14px");b.setStyle("height","14px");var d=m("color_table_cell");
|
10
10
|
b.setAttribute("aria-labelledby",d);b.append(CKEDITOR.dom.element.createFromHtml('<span id="'+d+'" class="cke_voice_label">'+c+"</span>",CKEDITOR.document))}i=CKEDITOR.dom.element.createFromHtml('<table tabIndex="-1" aria-label="'+h.options+'" role="grid" style="border-collapse:separate;" cellspacing="0"><caption class="cke_voice_label">'+h.options+'</caption><tbody role="presentation"></tbody></table>');i.on("mouseover",v);i.on("mouseout",q);var c="00 33 66 99 cc ff".split(" ");a(0,0);a(3,0);a(0,
|
11
11
|
3);a(3,3);var e=new r(i.$.insertRow(-1));e.setAttribute("role","row");for(var d=0;6>d;d++)b(e.$,"#"+c[d]+c[d]+c[d]);for(d=0;12>d;d++)b(e.$,"#000000")})();return{title:h.title,minWidth:360,minHeight:220,onLoad:function(){p=this},onHide:function(){n();var a=g.getChild(0).getHtml();g.setStyle("border-color",a);g.setStyle("border-style","solid");f.getById(k).removeStyle("background-color");f.getById(l).setHtml(" ");g=null},contents:[{id:"picker",label:h.title,accessKey:"I",elements:[{type:"hbox",
|
12
|
-
padding:0,widths:["70%","10%","30%"],children:[{type:"html",html:"<div></div>",onLoad:function(){CKEDITOR.document.getById(this.domId).append(i)},focus:function(){(g||this.getElement().getElementsByTag("td").getItem(0)).focus()}},x,{type:"vbox",padding:0,widths:["70%","5%","25%"],children:[{type:"html",html:"<span>"+h.highlight+'</span
|
13
|
-
|
12
|
+
padding:0,widths:["70%","10%","30%"],children:[{type:"html",html:"<div></div>",onLoad:function(){CKEDITOR.document.getById(this.domId).append(i)},focus:function(){(g||this.getElement().getElementsByTag("td").getItem(0)).focus()}},x,{type:"vbox",padding:0,widths:["70%","5%","25%"],children:[{type:"html",html:"<span>"+h.highlight+'</span><div id="'+k+'" style="border: 1px solid; height: 74px; width: 74px;"></div><div id="'+l+'"> </div><span>'+h.selected+'</span><div id="'+o+'" style="border: 1px solid; height: 20px; width: 74px;"></div>'},
|
13
|
+
{type:"text",label:h.selected,labelStyle:"display:none",id:"selectedColor",style:"width: 76px;margin-top:4px",onChange:function(){try{f.getById(o).setStyle("background-color",this.getValue())}catch(a){n()}}},x,{type:"button",id:"clear",label:h.clear,onClick:n}]}]}]}]}});
|
@@ -1,24 +1,24 @@
|
|
1
1
|
/*
|
2
|
-
Copyright (c) 2003-
|
2
|
+
Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
|
3
3
|
For licensing, see LICENSE.md or http://ckeditor.com/license
|
4
4
|
*/
|
5
|
-
(function(){function y(c){return c.type==CKEDITOR.NODE_TEXT&&0<c.getLength()&&(!o||!c.isReadOnly())}function s(c){return!(c.type==CKEDITOR.NODE_ELEMENT&&c.isBlockBoundary(CKEDITOR.tools.extend({},CKEDITOR.dtd.$empty,CKEDITOR.dtd.$nonEditable)))}
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
(this.matchRange.
|
15
|
-
|
16
|
-
this.matchRange.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
5
|
+
(function(){function y(c){return c.type==CKEDITOR.NODE_TEXT&&0<c.getLength()&&(!o||!c.isReadOnly())}function s(c){return!(c.type==CKEDITOR.NODE_ELEMENT&&c.isBlockBoundary(CKEDITOR.tools.extend({},CKEDITOR.dtd.$empty,CKEDITOR.dtd.$nonEditable)))}function n(c,g){function l(a,b){var d=this,c=new CKEDITOR.dom.walker(a);c.guard=b?s:function(a){!s(a)&&(d._.matchBoundary=!0)};c.evaluator=y;c.breakOnFalse=1;a.startContainer.type==CKEDITOR.NODE_TEXT&&(this.textNode=a.startContainer,this.offset=a.startOffset-
|
6
|
+
1);this._={matchWord:b,walker:c,matchBoundary:!1}}function n(a,b){var d=c.createRange();d.setStart(a.textNode,b?a.offset:a.offset+1);d.setEndAt(c.editable(),CKEDITOR.POSITION_BEFORE_END);return d}function p(a){var b=c.getSelection(),d=c.editable();b&&!a?(a=b.getRanges()[0].clone(),a.collapse(!0)):(a=c.createRange(),a.setStartAt(d,CKEDITOR.POSITION_AFTER_START));a.setEndAt(d,CKEDITOR.POSITION_BEFORE_END);return a}var t=new CKEDITOR.style(CKEDITOR.tools.extend({attributes:{"data-cke-highlight":1},fullMatch:1,
|
7
|
+
ignoreReadonly:1,childRule:function(){return 0}},c.config.find_highlight,!0));l.prototype={next:function(){return this.move()},back:function(){return this.move(!0)},move:function(a){var b=this.textNode;if(null===b)return u.call(this);this._.matchBoundary=!1;if(b&&a&&0<this.offset)this.offset--;else if(b&&this.offset<b.getLength()-1)this.offset++;else{for(b=null;!b&&!(b=this._.walker[a?"previous":"next"].call(this._.walker),this._.matchWord&&!b||this._.walker._.end););this.offset=(this.textNode=b)?
|
8
|
+
a?b.getLength()-1:0:0}return u.call(this)}};var q=function(a,b){this._={walker:a,cursors:[],rangeLength:b,highlightRange:null,isMatched:0}};q.prototype={toDomRange:function(){var a=c.createRange(),b=this._.cursors;if(1>b.length){var d=this._.walker.textNode;if(d)a.setStartAfter(d);else return null}else d=b[0],b=b[b.length-1],a.setStart(d.textNode,d.offset),a.setEnd(b.textNode,b.offset+1);return a},updateFromDomRange:function(a){var b=new l(a);this._.cursors=[];do a=b.next(),a.character&&this._.cursors.push(a);
|
9
|
+
while(a.character);this._.rangeLength=this._.cursors.length},setMatched:function(){this._.isMatched=!0},clearMatched:function(){this._.isMatched=!1},isMatched:function(){return this._.isMatched},highlight:function(){if(!(1>this._.cursors.length)){this._.highlightRange&&this.removeHighlight();var a=this.toDomRange(),b=a.createBookmark();t.applyToRange(a,c);a.moveToBookmark(b);this._.highlightRange=a;b=a.startContainer;b.type!=CKEDITOR.NODE_ELEMENT&&(b=b.getParent());b.scrollIntoView();this.updateFromDomRange(a)}},
|
10
|
+
removeHighlight:function(){if(this._.highlightRange){var a=this._.highlightRange.createBookmark();t.removeFromRange(this._.highlightRange,c);this._.highlightRange.moveToBookmark(a);this.updateFromDomRange(this._.highlightRange);this._.highlightRange=null}},isReadOnly:function(){return!this._.highlightRange?0:this._.highlightRange.startContainer.isReadOnly()},moveBack:function(){var a=this._.walker.back(),b=this._.cursors;a.hitMatchBoundary&&(this._.cursors=b=[]);b.unshift(a);b.length>this._.rangeLength&&
|
11
|
+
b.pop();return a},moveNext:function(){var a=this._.walker.next(),b=this._.cursors;a.hitMatchBoundary&&(this._.cursors=b=[]);b.push(a);b.length>this._.rangeLength&&b.shift();return a},getEndCharacter:function(){var a=this._.cursors;return 1>a.length?null:a[a.length-1].character},getNextCharacterRange:function(a){var b,d;d=this._.cursors;d=(b=d[d.length-1])&&b.textNode?new l(n(b)):this._.walker;return new q(d,a)},getCursors:function(){return this._.cursors}};var v=function(a,b){var d=[-1];b&&(a=a.toLowerCase());
|
12
|
+
for(var c=0;c<a.length;c++)for(d.push(d[c]+1);0<d[c+1]&&a.charAt(c)!=a.charAt(d[c+1]-1);)d[c+1]=d[d[c+1]-1]+1;this._={overlap:d,state:0,ignoreCase:!!b,pattern:a}};v.prototype={feedCharacter:function(a){for(this._.ignoreCase&&(a=a.toLowerCase());;){if(a==this._.pattern.charAt(this._.state))return this._.state++,this._.state==this._.pattern.length?(this._.state=0,2):1;if(this._.state)this._.state=this._.overlap[this._.state];else return 0}return null},reset:function(){this._.state=0}};var z=/[.,"'?!;: \u0085\u00a0\u1680\u280e\u2028\u2029\u202f\u205f\u3000]/,
|
13
|
+
w=function(a){if(!a)return!0;var b=a.charCodeAt(0);return 9<=b&&13>=b||8192<=b&&8202>=b||z.test(a)},e={searchRange:null,matchRange:null,find:function(a,b,d,f,e,A){this.matchRange?(this.matchRange.removeHighlight(),this.matchRange=this.matchRange.getNextCharacterRange(a.length)):this.matchRange=new q(new l(this.searchRange),a.length);for(var i=new v(a,!b),j=0,k="%";null!==k;){for(this.matchRange.moveNext();k=this.matchRange.getEndCharacter();){j=i.feedCharacter(k);if(2==j)break;this.matchRange.moveNext().hitMatchBoundary&&
|
14
|
+
i.reset()}if(2==j){if(d){var h=this.matchRange.getCursors(),m=h[h.length-1],h=h[0],g=c.createRange();g.setStartAt(c.editable(),CKEDITOR.POSITION_AFTER_START);g.setEnd(h.textNode,h.offset);h=g;m=n(m);h.trim();m.trim();h=new l(h,!0);m=new l(m,!0);if(!w(h.back().character)||!w(m.next().character))continue}this.matchRange.setMatched();!1!==e&&this.matchRange.highlight();return!0}}this.matchRange.clearMatched();this.matchRange.removeHighlight();return f&&!A?(this.searchRange=p(1),this.matchRange=null,
|
15
|
+
arguments.callee.apply(this,Array.prototype.slice.call(arguments).concat([!0]))):!1},replaceCounter:0,replace:function(a,b,d,f,e,g,i){o=1;a=0;if(this.matchRange&&this.matchRange.isMatched()&&!this.matchRange._.isReplaced&&!this.matchRange.isReadOnly()){this.matchRange.removeHighlight();b=this.matchRange.toDomRange();d=c.document.createText(d);if(!i){var j=c.getSelection();j.selectRanges([b]);c.fire("saveSnapshot")}b.deleteContents();b.insertNode(d);i||(j.selectRanges([b]),c.fire("saveSnapshot"));
|
16
|
+
this.matchRange.updateFromDomRange(b);i||this.matchRange.highlight();this.matchRange._.isReplaced=!0;this.replaceCounter++;a=1}else a=this.find(b,f,e,g,!i);o=0;return a}},f=c.lang.find;return{title:f.title,resizable:CKEDITOR.DIALOG_RESIZE_NONE,minWidth:350,minHeight:170,buttons:[CKEDITOR.dialog.cancelButton(c,{label:c.lang.common.close})],contents:[{id:"find",label:f.find,title:f.find,accessKey:"",elements:[{type:"hbox",widths:["230px","90px"],children:[{type:"text",id:"txtFindFind",label:f.findWhat,
|
17
|
+
isChanged:!1,labelLayout:"horizontal",accessKey:"F"},{type:"button",id:"btnFind",align:"left",style:"width:100%",label:f.find,onClick:function(){var a=this.getDialog();e.find(a.getValueOf("find","txtFindFind"),a.getValueOf("find","txtFindCaseChk"),a.getValueOf("find","txtFindWordChk"),a.getValueOf("find","txtFindCyclic"))||alert(f.notFoundMsg)}}]},{type:"fieldset",label:CKEDITOR.tools.htmlEncode(f.findOptions),style:"margin-top:29px",children:[{type:"vbox",padding:0,children:[{type:"checkbox",id:"txtFindCaseChk",
|
18
|
+
isChanged:!1,label:f.matchCase},{type:"checkbox",id:"txtFindWordChk",isChanged:!1,label:f.matchWord},{type:"checkbox",id:"txtFindCyclic",isChanged:!1,"default":!0,label:f.matchCyclic}]}]}]},{id:"replace",label:f.replace,accessKey:"M",elements:[{type:"hbox",widths:["230px","90px"],children:[{type:"text",id:"txtFindReplace",label:f.findWhat,isChanged:!1,labelLayout:"horizontal",accessKey:"F"},{type:"button",id:"btnFindReplace",align:"left",style:"width:100%",label:f.replace,onClick:function(){var a=
|
19
|
+
this.getDialog();e.replace(a,a.getValueOf("replace","txtFindReplace"),a.getValueOf("replace","txtReplace"),a.getValueOf("replace","txtReplaceCaseChk"),a.getValueOf("replace","txtReplaceWordChk"),a.getValueOf("replace","txtReplaceCyclic"))||alert(f.notFoundMsg)}}]},{type:"hbox",widths:["230px","90px"],children:[{type:"text",id:"txtReplace",label:f.replaceWith,isChanged:!1,labelLayout:"horizontal",accessKey:"R"},{type:"button",id:"btnReplaceAll",align:"left",style:"width:100%",label:f.replaceAll,isChanged:!1,
|
20
|
+
onClick:function(){var a=this.getDialog();e.replaceCounter=0;e.searchRange=p(1);e.matchRange&&(e.matchRange.removeHighlight(),e.matchRange=null);for(c.fire("saveSnapshot");e.replace(a,a.getValueOf("replace","txtFindReplace"),a.getValueOf("replace","txtReplace"),a.getValueOf("replace","txtReplaceCaseChk"),a.getValueOf("replace","txtReplaceWordChk"),!1,!0););e.replaceCounter?(alert(f.replaceSuccessMsg.replace(/%1/,e.replaceCounter)),c.fire("saveSnapshot")):alert(f.notFoundMsg)}}]},{type:"fieldset",
|
21
|
+
label:CKEDITOR.tools.htmlEncode(f.findOptions),children:[{type:"vbox",padding:0,children:[{type:"checkbox",id:"txtReplaceCaseChk",isChanged:!1,label:f.matchCase},{type:"checkbox",id:"txtReplaceWordChk",isChanged:!1,label:f.matchWord},{type:"checkbox",id:"txtReplaceCyclic",isChanged:!1,"default":!0,label:f.matchCyclic}]}]}]}],onLoad:function(){var a=this,b,c=0;this.on("hide",function(){c=0});this.on("show",function(){c=1});this.selectPage=CKEDITOR.tools.override(this.selectPage,function(f){return function(e){f.call(a,
|
22
|
+
e);var g=a._.tabs[e],i;i="find"===e?"txtFindWordChk":"txtReplaceWordChk";b=a.getContentElement(e,"find"===e?"txtFindFind":"txtFindReplace");a.getContentElement(e,i);g.initialized||(CKEDITOR.document.getById(b._.inputId),g.initialized=!0);if(c){var j,e="find"===e?1:0,g=1-e,k,h=r.length;for(k=0;k<h;k++)i=this.getContentElement(x[e],r[k][e]),j=this.getContentElement(x[g],r[k][g]),j.setValue(i.getValue())}}})},onShow:function(){e.searchRange=p();var a=this.getParentEditor().getSelection().getSelectedText(),
|
23
|
+
b=this.getContentElement(g,"find"==g?"txtFindFind":"txtFindReplace");b.setValue(a);b.select();this.selectPage(g);this[("find"==g&&this._.editor.readOnly?"hide":"show")+"Page"]("replace")},onHide:function(){var a;e.matchRange&&e.matchRange.isMatched()&&(e.matchRange.removeHighlight(),c.focus(),(a=e.matchRange.toDomRange())&&c.getSelection().selectRanges([a]));delete e.matchRange},onFocus:function(){return"replace"==g?this.getContentElement("replace","txtFindReplace"):this.getContentElement("find",
|
24
|
+
"txtFindFind")}}}var o,u=function(){return{textNode:this.textNode,offset:this.offset,character:this.textNode?this.textNode.getText().charAt(this.offset):null,hitMatchBoundary:this._.matchBoundary}},x=["find","replace"],r=[["txtFindFind","txtFindReplace"],["txtFindCaseChk","txtReplaceCaseChk"],["txtFindWordChk","txtReplaceWordChk"],["txtFindCyclic","txtReplaceCyclic"]];CKEDITOR.dialog.add("find",function(c){return n(c,"find")});CKEDITOR.dialog.add("replace",function(c){return n(c,"replace")})})();
|
@@ -0,0 +1,166 @@
|
|
1
|
+
/**
|
2
|
+
* The footnotes dialog definition.
|
3
|
+
*
|
4
|
+
* Version 1.0.9
|
5
|
+
* https://github.com/andykirk/CKEditorFootnotes
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
|
9
|
+
// Dialog definition.
|
10
|
+
CKEDITOR.dialog.add( 'footnotesDialog', function( editor ) {
|
11
|
+
|
12
|
+
return {
|
13
|
+
editor_name: false,
|
14
|
+
// Basic properties of the dialog window: title, minimum size.
|
15
|
+
title: 'Manage Footnotes',
|
16
|
+
minWidth: 400,
|
17
|
+
minHeight: 200,
|
18
|
+
footnotes_el: false,
|
19
|
+
|
20
|
+
// Dialog window contents definition.
|
21
|
+
contents: [
|
22
|
+
{
|
23
|
+
// Definition of the Basic Settings dialog tab (page).
|
24
|
+
id: 'tab-basic',
|
25
|
+
label: 'Basic Settings',
|
26
|
+
|
27
|
+
// The tab contents.
|
28
|
+
elements: [
|
29
|
+
{
|
30
|
+
// Text input field for the footnotes text.
|
31
|
+
type: 'textarea',
|
32
|
+
id: 'new_footnote',
|
33
|
+
'class': 'footnote_text',
|
34
|
+
label: 'New footnote:',
|
35
|
+
inputStyle: 'height: 100px',
|
36
|
+
},
|
37
|
+
{
|
38
|
+
// Text input field for the footnotes title (explanation).
|
39
|
+
type: 'text',
|
40
|
+
id: 'footnote_id',
|
41
|
+
name: 'footnote_id',
|
42
|
+
label: 'No existing footnotes',
|
43
|
+
|
44
|
+
|
45
|
+
// Called by the main setupContent call on dialog initialization.
|
46
|
+
setup: function( element ) {
|
47
|
+
var dialog = this.getDialog();
|
48
|
+
$el = jQuery('#' + this.domId);
|
49
|
+
|
50
|
+
dialog.footnotes_el = $el;
|
51
|
+
|
52
|
+
editor = dialog.getParentEditor();
|
53
|
+
// Dynamically add existing footnotes:
|
54
|
+
$footnotes = editor.plugins.footnotes.editorContents(editor).find('.footnotes ol');
|
55
|
+
$this = this;
|
56
|
+
|
57
|
+
if ($footnotes.length > 0) {
|
58
|
+
if ($el.find('p').length == 0) {
|
59
|
+
$el.append('<p style="margin-bottom: 10px;"><strong>OR:</strong> Choose footnote:</p><ol class="footnotes_list"></ol>');
|
60
|
+
} else {
|
61
|
+
$el.find('ol').empty();
|
62
|
+
}
|
63
|
+
|
64
|
+
var radios = '';
|
65
|
+
$footnotes.find('li').each(function(){
|
66
|
+
$item = jQuery(this);
|
67
|
+
var footnote_id = $item.attr('data-footnote-id');
|
68
|
+
radios += '<li style="margin-left: 15px;"><input type="radio" name="footnote_id" value="' + footnote_id + '" id="fn_' + footnote_id + '" /> <label for="fn_' + footnote_id + '" style="white-space: normal; display: inline-block; padding: 0 25px 0 5px; vertical-align: top; margin-bottom: 10px;">' + $item.find('cite').text() + '</label></li>';
|
69
|
+
});
|
70
|
+
|
71
|
+
$el.children('label,div').css('display', 'none');
|
72
|
+
$el.find('ol').html(radios);
|
73
|
+
$el.find(':radio').change(function(){;
|
74
|
+
$el.find(':text').val(jQuery(this).val());
|
75
|
+
});
|
76
|
+
|
77
|
+
} else {
|
78
|
+
$el.children('div').css('display', 'none');
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
]
|
83
|
+
},
|
84
|
+
],
|
85
|
+
|
86
|
+
// Invoked when the dialog is loaded.
|
87
|
+
onShow: function() {
|
88
|
+
this.setupContent();
|
89
|
+
|
90
|
+
var dialog = this;
|
91
|
+
CKEDITOR.on( 'instanceLoaded', function( evt ) {
|
92
|
+
dialog.editor_name = evt.editor.name;
|
93
|
+
} );
|
94
|
+
|
95
|
+
var current_editor_id = dialog.getParentEditor().id;
|
96
|
+
|
97
|
+
CKEDITOR.replaceAll( function( textarea, config ) {
|
98
|
+
// Make sure the textarea has the correct class:
|
99
|
+
if (!textarea.className.match(/footnote_text/)) {
|
100
|
+
return false;
|
101
|
+
}
|
102
|
+
|
103
|
+
// Make sure we only instantiate the relevant editor:
|
104
|
+
var el = textarea;
|
105
|
+
while ((el = el.parentElement) && !el.classList.contains(current_editor_id));
|
106
|
+
if (!el) {
|
107
|
+
return false;
|
108
|
+
}
|
109
|
+
//console.log(el);
|
110
|
+
config.toolbarGroups = [
|
111
|
+
{ name: 'editing', groups: [ 'undo', 'find', 'selection', 'spellchecker' ] },
|
112
|
+
{ name: 'clipboard', groups: [ 'clipboard' ] },
|
113
|
+
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
|
114
|
+
]
|
115
|
+
config.allowedContent = 'br em strong; a[!href]';
|
116
|
+
config.enterMode = CKEDITOR.ENTER_BR;
|
117
|
+
config.autoParagraph = false;
|
118
|
+
config.height = 80;
|
119
|
+
config.resize_enabled = false;
|
120
|
+
config.autoGrow_minHeight = 80;
|
121
|
+
config.removePlugins = 'footnotes';
|
122
|
+
|
123
|
+
config.on = {
|
124
|
+
focus: function( evt ){
|
125
|
+
var $editor_el = jQuery('#' + evt.editor.id + '_contents');
|
126
|
+
$editor_el.parents('tr').next().find(':checked').attr('checked', false);
|
127
|
+
$editor_el.parents('tr').next().find(':text').val('');
|
128
|
+
}
|
129
|
+
};
|
130
|
+
return true;
|
131
|
+
});
|
132
|
+
|
133
|
+
},
|
134
|
+
|
135
|
+
// This method is invoked once a user clicks the OK button, confirming the dialog.
|
136
|
+
onOk: function() {
|
137
|
+
var dialog = this;
|
138
|
+
var footnote_editor = CKEDITOR.instances[dialog.editor_name];
|
139
|
+
var footnote_id = dialog.getValueOf('tab-basic', 'footnote_id');
|
140
|
+
var footnote_data = footnote_editor.getData();
|
141
|
+
footnote_editor.destroy();
|
142
|
+
|
143
|
+
if (footnote_id == '') {
|
144
|
+
// No existing id selected, check for new footnote:
|
145
|
+
if (footnote_data == '') {
|
146
|
+
// Nothing entered, so quit:
|
147
|
+
return;
|
148
|
+
} else {
|
149
|
+
// Insert new footnote:
|
150
|
+
editor.plugins.footnotes.build(footnote_data, true, editor);
|
151
|
+
}
|
152
|
+
} else {
|
153
|
+
// Insert existing footnote:
|
154
|
+
editor.plugins.footnotes.build(footnote_id, false, editor);
|
155
|
+
}
|
156
|
+
// Destroy the editor so it's rebuilt properly next time:
|
157
|
+
return;
|
158
|
+
},
|
159
|
+
|
160
|
+
onCancel: function() {
|
161
|
+
var dialog = this;
|
162
|
+
var footnote_editor = CKEDITOR.instances[dialog.editor_name];
|
163
|
+
footnote_editor.destroy();
|
164
|
+
}
|
165
|
+
};
|
166
|
+
});
|
@@ -0,0 +1,305 @@
|
|
1
|
+
/**
|
2
|
+
* Basic sample plugin inserting footnotes elements into CKEditor editing area.
|
3
|
+
*
|
4
|
+
* Version 1.0.9
|
5
|
+
* https://github.com/andykirk/CKEditorFootnotes
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
// Register the plugin within the editor.
|
9
|
+
CKEDITOR.plugins.add( 'footnotes', {
|
10
|
+
|
11
|
+
footnote_ids: [],
|
12
|
+
requires: 'widget',
|
13
|
+
icons: 'footnotes',
|
14
|
+
|
15
|
+
|
16
|
+
// The plugin initialization logic goes inside this method.
|
17
|
+
init: function(editor) {
|
18
|
+
// Allow `cite` to be editable:
|
19
|
+
CKEDITOR.dtd.$editable['cite'] = 1;
|
20
|
+
|
21
|
+
// Add some CSS tweaks:
|
22
|
+
var css = '.footnotes{background:#eee; padding:1px 15px;} .footnotes cite{font-style: normal;}';
|
23
|
+
CKEDITOR.addCss(css);
|
24
|
+
|
25
|
+
var $this = this;
|
26
|
+
|
27
|
+
editor.on('saveSnapshot', function(evt) {
|
28
|
+
console.log('saveSnapshot');
|
29
|
+
});
|
30
|
+
|
31
|
+
// Force a reorder on startup to make sure all vars are set: (e.g. footnotes store):
|
32
|
+
editor.on('instanceReady', function(evt) {
|
33
|
+
$this.reorderMarkers(editor);
|
34
|
+
});
|
35
|
+
|
36
|
+
// Add the reorder change event:
|
37
|
+
editor.on('change', function(evt) {
|
38
|
+
// Copy the footnotes_store as we may be doing a cut:
|
39
|
+
if(!evt.editor.footnotes_tmp) {
|
40
|
+
evt.editor.footnotes_tmp = evt.editor.footnotes_store;
|
41
|
+
}
|
42
|
+
|
43
|
+
// Prevent no selection errors:
|
44
|
+
if (!evt.editor.getSelection().getStartElement()) {
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
// Don't reorder the markers if editing a cite:
|
48
|
+
var footnote_section = evt.editor.getSelection().getStartElement().getAscendant('section');
|
49
|
+
if (footnote_section && footnote_section.$.className.indexOf('footnotes') != -1) {
|
50
|
+
return;
|
51
|
+
}
|
52
|
+
// SetTimeout seems to be necessary (it's used in the core but can't be 100% sure why)
|
53
|
+
setTimeout(function(){
|
54
|
+
$this.reorderMarkers(editor);
|
55
|
+
},
|
56
|
+
0
|
57
|
+
);
|
58
|
+
});
|
59
|
+
|
60
|
+
// Build the initial footnotes widget editables definition:
|
61
|
+
var prefix = editor.config.footnotesPrefix ? '-' + editor.config.footnotesPrefix : '';
|
62
|
+
var def = {
|
63
|
+
header: {
|
64
|
+
selector: 'header > *',
|
65
|
+
//allowedContent: ''
|
66
|
+
allowedContent: 'strong em span sub sup;'
|
67
|
+
}
|
68
|
+
};
|
69
|
+
var contents = jQuery('<div>' + editor.element.$.textContent + '</div>')
|
70
|
+
, l = contents.find('.footnotes li').length
|
71
|
+
, i = 1;
|
72
|
+
for (i; i <= l; i++) {
|
73
|
+
def['footnote_' + i] = {selector: '#footnote' + prefix + '-' + i + ' cite', allowedContent: 'a[href]; cite[*](*); strong em span br'};
|
74
|
+
}
|
75
|
+
|
76
|
+
// Register the footnotes widget.
|
77
|
+
editor.widgets.add('footnotes', {
|
78
|
+
|
79
|
+
// Minimum HTML which is required by this widget to work.
|
80
|
+
requiredContent: 'section(footnotes)',
|
81
|
+
|
82
|
+
// Check the elements that need to be converted to widgets.
|
83
|
+
upcast: function(element) {
|
84
|
+
return element.name == 'section' && element.hasClass('footnotes');
|
85
|
+
},
|
86
|
+
|
87
|
+
editables: def
|
88
|
+
});
|
89
|
+
|
90
|
+
// Register the footnotemarker widget.
|
91
|
+
editor.widgets.add('footnotemarker', {
|
92
|
+
|
93
|
+
// Minimum HTML which is required by this widget to work.
|
94
|
+
requiredContent: 'sup[data-footnote-id]',
|
95
|
+
|
96
|
+
// Check the elements that need to be converted to widgets.
|
97
|
+
upcast: function(element) {
|
98
|
+
return element.name == 'sup' && element.attributes['data-footnote-id'] != 'undefined';
|
99
|
+
}
|
100
|
+
});
|
101
|
+
|
102
|
+
// Define an editor command that opens our dialog.
|
103
|
+
editor.addCommand('footnotes', new CKEDITOR.dialogCommand('footnotesDialog', {
|
104
|
+
// @TODO: This needs work:
|
105
|
+
allowedContent: 'section[*](*);header[*](*);li[*];a[*];cite(*)[*];sup[*]',
|
106
|
+
requiredContent: 'section[*](*);header[*](*);li[*];a[*];cite(*)[*];sup[*]'
|
107
|
+
}));
|
108
|
+
|
109
|
+
// Create a toolbar button that executes the above command.
|
110
|
+
editor.ui.addButton('Footnotes', {
|
111
|
+
|
112
|
+
// The text part of the button (if available) and tooptip.
|
113
|
+
label: 'Insert Footnotes',
|
114
|
+
|
115
|
+
// The command to execute on click.
|
116
|
+
command: 'footnotes',
|
117
|
+
|
118
|
+
// The button placement in the toolbar (toolbar group name).
|
119
|
+
toolbar: 'insert'
|
120
|
+
});
|
121
|
+
|
122
|
+
// Register our dialog file. this.path is the plugin folder path.
|
123
|
+
CKEDITOR.dialog.add('footnotesDialog', this.path + 'dialogs/footnotes.js');
|
124
|
+
},
|
125
|
+
|
126
|
+
editorContents: function(editor) {
|
127
|
+
if (editor.config.footnotesEditorSelector) {
|
128
|
+
return jQuery(eval(editor.config.footnotesEditorSelector)).contents()
|
129
|
+
} else {
|
130
|
+
return jQuery('#' + editor.id + '_contents iframe').contents().find('body');
|
131
|
+
}
|
132
|
+
},
|
133
|
+
|
134
|
+
build: function(footnote, is_new, editor) {
|
135
|
+
|
136
|
+
if (is_new) {
|
137
|
+
// Generate new id:
|
138
|
+
footnote_id = this.generateFootnoteId();
|
139
|
+
} else {
|
140
|
+
// Existing footnote id passed:
|
141
|
+
footnote_id = footnote;
|
142
|
+
}
|
143
|
+
|
144
|
+
// Insert the marker:
|
145
|
+
var footnote_marker = '<sup data-footnote-id="' + footnote_id + '">X</sup>';
|
146
|
+
|
147
|
+
editor.insertHtml(footnote_marker);
|
148
|
+
|
149
|
+
if (is_new) {
|
150
|
+
editor.fire('lockSnapshot');
|
151
|
+
this.addFootnote(this.buildFootnote(footnote_id, footnote, false, editor), editor);
|
152
|
+
editor.fire('unlockSnapshot');
|
153
|
+
}
|
154
|
+
this.reorderMarkers(editor);
|
155
|
+
},
|
156
|
+
|
157
|
+
buildFootnote: function(footnote_id, footnote_text, data, editor) {
|
158
|
+
data ? data : false;
|
159
|
+
var links = '';
|
160
|
+
var letters = 'abcdefghijklmnopqrstuvwxyz';
|
161
|
+
var order = data ? data.order.indexOf(footnote_id) + 1
|
162
|
+
: 1;
|
163
|
+
var prefix = editor.config.footnotesPrefix ? '-' + editor.config.footnotesPrefix : '';
|
164
|
+
if (data && data.occurrences[footnote_id] == 1) {
|
165
|
+
links = '<a href="#footnote-marker' + prefix + '-' + order + '-1">^</a> ';
|
166
|
+
} else if (data && data.occurrences[footnote_id] > 1) {
|
167
|
+
var i = 0
|
168
|
+
, l = data.occurrences[footnote_id]
|
169
|
+
, n = l;
|
170
|
+
for (i; i < l; i++) {
|
171
|
+
links += '<a href="#footnote-marker' + prefix + '-' + order + '-' + (i + 1) + '">' + letters.charAt(i) + '</a>';
|
172
|
+
if (i < l-1) {
|
173
|
+
links += ', ';
|
174
|
+
} else {
|
175
|
+
links += ' ';
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
179
|
+
footnote = '<li id="footnote' + prefix + '-' + order + '" data-footnote-id="' + footnote_id + '">' + links + '<cite>' + footnote_text + '</cite></li>';
|
180
|
+
return footnote;
|
181
|
+
},
|
182
|
+
|
183
|
+
addFootnote: function(footnote, editor) {
|
184
|
+
$contents = this.editorContents(editor);
|
185
|
+
$footnotes = $contents.find('.footnotes');
|
186
|
+
|
187
|
+
if ($footnotes.length == 0) {
|
188
|
+
var container = '<section class="footnotes"><header><h2>Footnotes</h2></header><ol>' + footnote + '</ol></section>';
|
189
|
+
// Move cursor to end of content:
|
190
|
+
var range = editor.createRange();
|
191
|
+
range.moveToElementEditEnd(range.root);
|
192
|
+
editor.getSelection().selectRanges([range]);
|
193
|
+
// Insert the container:
|
194
|
+
editor.insertHtml(container);
|
195
|
+
} else {
|
196
|
+
$footnotes.find('ol').append(footnote);
|
197
|
+
}
|
198
|
+
return;
|
199
|
+
},
|
200
|
+
|
201
|
+
generateFootnoteId: function() {
|
202
|
+
var id = Math.random().toString(36).substr(2, 5);
|
203
|
+
while (jQuery.inArray(id, this.footnote_ids) != -1) {
|
204
|
+
id = String(this.generateFootnoteId());
|
205
|
+
}
|
206
|
+
this.footnote_ids.push(id);
|
207
|
+
return id;
|
208
|
+
},
|
209
|
+
|
210
|
+
reorderMarkers: function(editor) {
|
211
|
+
editor.fire('lockSnapshot');
|
212
|
+
var prefix = editor.config.footnotesPrefix ? '-' + editor.config.footnotesPrefix : '';
|
213
|
+
$contents = this.editorContents(editor);
|
214
|
+
var data = {
|
215
|
+
order: [],
|
216
|
+
occurrences: {}
|
217
|
+
};
|
218
|
+
|
219
|
+
// Check that there's a footnotes section. If it's been deleted the markers are useless:
|
220
|
+
if ($contents.find('.footnotes').length == 0) {
|
221
|
+
$contents.find('sup[data-footnote-id]').remove();
|
222
|
+
editor.fire('unlockSnapshot');
|
223
|
+
return;
|
224
|
+
}
|
225
|
+
|
226
|
+
// Find all the markers in the document:
|
227
|
+
var $markers = $contents.find('sup[data-footnote-id]');
|
228
|
+
// If there aren't any, remove the Footnotes container:
|
229
|
+
if ($markers.length == 0) {
|
230
|
+
$contents.find('.footnotes').parent().remove();
|
231
|
+
editor.fire('unlockSnapshot');
|
232
|
+
return;
|
233
|
+
}
|
234
|
+
|
235
|
+
// Otherwise reorder the markers:
|
236
|
+
$markers.each(function(){
|
237
|
+
var footnote_id = jQuery(this).attr('data-footnote-id')
|
238
|
+
, marker_ref
|
239
|
+
, n = data.order.indexOf(footnote_id);
|
240
|
+
|
241
|
+
// If this is the markers first occurrence:
|
242
|
+
if (n == -1) {
|
243
|
+
// Store the id:
|
244
|
+
data.order.push(footnote_id);
|
245
|
+
n = data.order.length;
|
246
|
+
data.occurrences[footnote_id] = 1;
|
247
|
+
marker_ref = n + '-1';
|
248
|
+
} else {
|
249
|
+
// Otherwise increment the number of occurrences:
|
250
|
+
// (increment n due to zero-index array)
|
251
|
+
n++;
|
252
|
+
data.occurrences[footnote_id]++;
|
253
|
+
marker_ref = n + '-' + data.occurrences[footnote_id];
|
254
|
+
}
|
255
|
+
// Replace the marker contents:
|
256
|
+
var marker = '<a href="#footnote' + prefix + '-' + n + '" id="footnote-marker' + prefix + '-' + marker_ref + '" rel="footnote">[' + n + ']</a>';
|
257
|
+
jQuery(this).html(marker);
|
258
|
+
});
|
259
|
+
|
260
|
+
// Prepare the footnotes_store object:
|
261
|
+
editor.footnotes_store = {};
|
262
|
+
|
263
|
+
// Then rebuild the Footnotes content to match marker order:
|
264
|
+
var footnotes = '';
|
265
|
+
var footnote_text = '';
|
266
|
+
var i = 0
|
267
|
+
, l = data.order.length;
|
268
|
+
for (i; i < l; i++) {
|
269
|
+
footnote_id = data.order[i];
|
270
|
+
footnote_text = $contents.find('.footnotes [data-footnote-id=' + footnote_id + '] cite').html();
|
271
|
+
// If the footnotes text can't be found in the editor, it may be in the tmp store
|
272
|
+
// following a cut:
|
273
|
+
if (!footnote_text) {
|
274
|
+
footnote_text = editor.footnotes_tmp[footnote_id];
|
275
|
+
}
|
276
|
+
footnotes += this.buildFootnote(footnote_id, footnote_text, data, editor);
|
277
|
+
// Store the footnotes for later use (post cut/paste):
|
278
|
+
editor.footnotes_store[footnote_id] = footnote_text;
|
279
|
+
}
|
280
|
+
|
281
|
+
// Insert the footnotes into the list:
|
282
|
+
$contents.find('.footnotes ol').html(footnotes);
|
283
|
+
|
284
|
+
// Next we need to reinstate the 'editable' properties of the footnotes.
|
285
|
+
// (we have to do this individually due to Widgets 'fireOnce' for editable selectors)
|
286
|
+
var el = $contents.find('.footnotes')
|
287
|
+
, footnote_widget;
|
288
|
+
// So first we need to find the right Widget instance:
|
289
|
+
// (I hope there's a better way of doing this but I can't find one)
|
290
|
+
for (i in editor.widgets.instances) {
|
291
|
+
if (editor.widgets.instances[i].name == 'footnotes') {
|
292
|
+
footnote_widget = editor.widgets.instances[i];
|
293
|
+
break;
|
294
|
+
}
|
295
|
+
}
|
296
|
+
// Then we `initEditable` each footnote, giving it a unique selector:
|
297
|
+
for (i in data.order) {
|
298
|
+
n = parseInt(i) + 1;
|
299
|
+
footnote_widget.initEditable('footnote_' + n, {selector: '#footnote' + prefix + '-' + n +' cite', allowedContent: 'a[href]; cite[*](*); em strong span'});
|
300
|
+
}
|
301
|
+
|
302
|
+
editor.fire('unlockSnapshot');
|
303
|
+
return;
|
304
|
+
}
|
305
|
+
});
|