function doRemovePageBreak(){ // Backspace events means you might want to remove a line break, this stops the text ending up // on the same line as the page break.. var rep = this.rep; var documentAttributeManager = this.documentAttributeManager; if (!(rep.selStart && rep.selEnd)){ return; } // only continue if we have some caret position var firstLine = rep.selStart[0]; // Get the first line var line = rep.lines.atIndex(firstLine); // If it's actually a page break.. if(line.lineNode && (line.lineNode.firstChild && line.lineNode.firstChild.className === "pageBreak")){ documentAttributeManager.removeAttributeOnLine(firstLine, 'pageBreak'); // remove the page break from the line // TODO: Control Z can make this kinda break // Get the document var document = this.editorInfo.ace_getDocument(); // Update the selection from the rep this.editorInfo.ace_updateBrowserSelectionFromRep(); // Get the current selection var myselection = document.getSelection(); // Get the selections top offset var caretOffsetTop = myselection.focusNode.offsetTop; // Move to the new Y co-ord to bring the new page into focus $('iframe[name="ace_outer"]').contents().find('#outerdocbody').scrollTop(caretOffsetTop-120); // Works in Chrome $('iframe[name="ace_outer"]').contents().find('#outerdocbody').parent().scrollTop(caretOffsetTop-120); // Works in Firefox // Sighs } }
enable: function() { if(clientVars.plugins.plugins && clientVars.plugins.plugins.ep_slideshow && clientVars.plugins.plugins.ep_slideshow.isEnabled) return false; $('#editorcontainer, iframe').addClass('page_view'); $innerIframe.addClass('outerPV'); $outerIframeContents.find('#outerdocbody').addClass("outerBackground"); $innerdocbody.addClass('innerPV').css("margin-left","0px"); $innerdocbody.contents().find('.pageBreak').click(function(e){ $(this).focusout().blur(); top.console.log("Can't edit pagebreak Line"); e.preventDefault(); return false; }); // $('#editorcontainer').css("top", "15px"); // var containerTop = $('.toolbar').position().top + $('.toolbar').height() +5; // $('#editorcontainerbox').css("top", containerTop); $('#ep_page_ruler').show(); // if line numbers are enabled.. if($('#options-linenoscheck').is(':checked')) { $outerIframeContents.find('#sidediv').addClass("lineNumbersAndPageView"); $innerdocbody.addClass('innerPVlineNumbers'); } reDrawPageBreaks(); var inner = $('iframe[name="ace_outer"]').contents().find('iframe[name="ace_inner"]'); var style = "width:850px;margin-left:-102px;height:40px;background-color:#f7f7f7;margin-top:100px;margin-bottom:100px;border-bottom:1px dotted #aaa"; inner.contents().find("head").append("<style>.pageBreak{"+style+"}</style>"); inner.contents().find("head").append("<style>.pageBreakComputed{"+style+"}</style>"); },
var documentReady = function () { top = window.top.document; $top = $(top); $body = $('body', $(top)); // $frame = $('#epframet1', $body); $frame = $(window.frameElement); console.log('documentReady', $frame); };
listEntry.click(function() { // replace current selected suggestion with this entry $(this).siblings(".selected").removeClass("selected"); $(this).addClass("selected"); // replace text with this suggestion autocomp.selectSuggestion(context); });
success: function(data, textStatus, jqXHR) { if (data.success && data.allpadspublicsauthentifiedonly) { var url = baseURL+'/mypads/?/mypads/group/'+data.group+'/pad/view/'+padID; $('#linkinput').hide(); $('#embedcode').hide(); $('#linkinput').parent().append('<input id="linkinput2" value="'+url+'" onclick="this.select()" type="text">'); } }
$('.ep_fullscreen').click(function () { toggleFullscreen(); $('.ep_fullscreen').attr('title', window._(_full ? 'ep_exit_fullscreen' : 'ep_open_fullscreen')); inst.focus(); var rem = _full ? 'buttonicon-fullscreen' : 'buttonicon-exit-fullscreen'; var add = !_full ? 'buttonicon-fullscreen' : 'buttonicon-exit-fullscreen'; $('.buttonicon', this).removeClass(rem).addClass(add); });
var addListenersToPageView = function() { $("#options-pageview").on("click", function() { getPadOuter().find('#outerdocbody').toggleClass("pageViewDisabled"); }); // add class if Page View is disabled already if(!$('#options-pageview').is(':checked')) { getPadOuter().find('#outerdocbody').addClass("pageViewDisabled"); } }
disable: function() { $('#editorcontainer, iframe').removeClass('page_view'); $('iframe[name="ace_outer"]').contents().find('iframe').contents().find("#innerdocbody").removeClass('innerPV'); $('iframe[name="ace_outer"]').contents().find("iframe").removeClass('outerPV'); $('iframe[name="ace_outer"]').contents().find('iframe').contents().find("#innerdocbody").css("margin-left","-100px"); $('iframe[name="ace_outer"]').contents().find('#outerdocbody').removeClass("outerBackground"); $('#ep_page_ruler').hide(); var containerTop = $('.toolbar').position().top + $('.toolbar').height() +5; $('#editorcontainerbox').css("top", containerTop+"px"); $('#editorcontainer').css("top", 0); }
update_task_status: function(){ var ace = this; var target = event.target; var isTaskList = ($(target).hasClass("task-open") || $(target).hasClass("task-done")); var targetRight = event.target.offsetLeft + 14; // The right hand side of the checkbox -- remember the checkbox can be indented var isCheckbox = (event.pageX < targetRight); // was the click to the left of the checkbox if(!isTaskList || !isCheckbox){ return; } // Dont continue if we're not clicking a checkbox of a tasklist padEditor.callWithAce(function(ace){ // call the function to apply the attribute inside ACE ace.ace_toggle_task_status(); }, 'tasks', true); // TODO what's the second attribute do here? }
padComment.each(function(it){ var $this = $(this); var cls = $this.attr('class'); var classCommentId = /(?:^| )(c-[A-Za-z0-9]*)/.exec(cls); var commentId = (classCommentId) ? classCommentId[1] : null; if (commentId === null) { var isAuthorClassName = /(?:^| )(a.[A-Za-z0-9]*)/.exec(cls); if (isAuthorClassName) self.removeComment(isAuthorClassName[1], it); console.log('o_O', cls); return; } var commentId = classCommentId[1]; var commentElm = container.find('#'+ commentId); var comment = comments[commentId]; if (comment !== null) { // If comment is not in sidebar insert it if (commentElm.length == 0) { self.insertComment(commentId, comment.data, it); commentElm = container.find('#'+ commentId); $this.mouseenter(function(){ commentElm.addClass('mouseover'); }).mouseleave(function(){ commentElm.removeClass('mouseover'); }); $(this).on('click', function(){ markerTop = $(this).position().top; commentTop = commentElm.position().top; containerTop = container.css('top'); console.log(container); container.css('top', containerTop - (commentTop - markerTop)); }); } } var prevCommentElm = commentElm.prev(); var commentPos; if (prevCommentElm.length == 0) { commentPos = 0; } else { var prevCommentPos = prevCommentElm.css('top'); var prevCommentHeight = prevCommentElm.innerHeight(); commentPos = parseInt(prevCommentPos) + prevCommentHeight + 30; } commentElm.css({ 'top': commentPos }); });
exports.postAceInit = function(hook, context){ $('.subscript').click(function(){ context.ace.callWithAce(function(ace){ ace.ace_toggleAttributeOnSelection("sub"); },'insertsubscript' , true); }); $('.superscript').click(function(){ context.ace.callWithAce(function(ace){ ace.ace_toggleAttributeOnSelection("sup"); },'insertsuperscript' , true); }) };
var postAceInit = function(hook, context){ $('.ep_align_left').click(function(){ align(context, 0); }); $('.ep_align_center').click(function(){ align(context, 1); }); $('.ep_align_justify').click(function(){ align(context, 3); }); $('.ep_align_right').click(function(){ align(context, 2); }); };
ep_comments.prototype.displayNewCommentForm = function() { var self = this; var rep = {}; var ace = this.ace; ace.callWithAce(function(ace) { var saveRep = ace.ace_getRep(); rep.lines = saveRep.lines; rep.selStart = saveRep.selStart; rep.selEnd = saveRep.selEnd; },'saveCommentedSelection', true); var selectedText = self.getSelectedText(rep); // we have nothing selected, do nothing var noTextSelected = (selectedText.length === 0); if (noTextSelected) { return; } self.createNewCommentFormIfDontExist(rep); // Write the text to the changeFrom form var padOuter = $('iframe[name="ace_outer"]').contents(); padOuter.find(".comment-suggest-from").val(selectedText); // Display form newComment.showNewCommentForm(); // Check if the first element selected is visible in the viewport var $firstSelectedElement = self.getFirstElementSelected(); var firstSelectedElementInViewport = self.isElementInViewport($firstSelectedElement); if(!firstSelectedElementInViewport){ self.scrollViewportIfSelectedTextIsNotVisible($firstSelectedElement); } // Adjust focus on the form padOuter.find('.comment-content').focus(); // fix for iOS: when opening #newComment, we need to force focus on padOuter // contentWindow, otherwise keyboard will be displayed but text input made by // the user won't be added to textarea var outerIframe = $('iframe[name="ace_outer"]').get(0); if (outerIframe && outerIframe.contentWindow) { outerIframe.contentWindow.focus(); } }
aceEditEvent:function(type, context, cb){ // ACE event processing disable by other plugins if (!autocomp.processEditEvent) return; //if disabled in settings if(!$('#options-autocomp').is(':checked')) return; autocomp.update(context); },
adjustCaretPosition:function(currentElement, textToInsert){ var rightarrows = ""; for (var i = textToInsert.length - 1; i >= 0; i--) { rightarrows += '{rightarrow}'; }; $(currentElement).sendkeys(rightarrows); },
ep_comments.prototype.findContainers = function(){ var padOuter = $('iframe[name="ace_outer"]').contents(); this.padOuter = padOuter; this.sideDiv = padOuter.find('#sidediv'); this.padInner = padOuter.find('iframe[name="ace_inner"]'); };
$('#options-pageview').on('click', function() { if($('#options-pageview').is(':checked')) { pv.enable(); } else { pv.disable(); } });
$(this).on('click', function(){ markerTop = $(this).position().top; commentTop = commentElm.position().top; containerTop = container.css('top'); console.log(container); container.css('top', containerTop - (commentTop - markerTop)); });
ep_comments.prototype.scrollViewportIfSelectedTextIsNotVisible = function($firstSelectedElement){ // Set the top of the form to be the same Y as the target Rep var y = $firstSelectedElement.offsetTop; var padOuter = $('iframe[name="ace_outer"]').contents(); padOuter.find('#outerdocbody').scrollTop(y); // Works in Chrome padOuter.find('#outerdocbody').parent().scrollTop(y); // Works in Firefox }
ep_comments.prototype.setYofComments = function(){ // for each comment in the pad var padOuter = $('iframe[name="ace_outer"]').contents(); var padInner = padOuter.find('iframe[name="ace_inner"]'); var inlineComments = padInner.contents().find(".comment"); var commentsToBeShown = []; // hide each outer comment... commentBoxes.hideAllComments(); // ... and hide comment icons too commentIcons.hideIcons(); $.each(inlineComments, function(){ var y = this.offsetTop; var commentId = /(?:^| )(c-[A-Za-z0-9]*)/.exec(this.className); // classname is the ID of the comment if(commentId) { // adjust outer comment... var commentEle = commentBoxes.adjustTopOf(commentId[1], y); // ... and adjust icons too commentIcons.adjustTopOf(commentId[1], y); // mark this comment to be displayed if it was visible before we start adjusting its position if (commentIcons.shouldShow(commentEle)) commentsToBeShown.push(commentEle); } }); // re-display comments that were visible before _.each(commentsToBeShown, function(commentEle) { commentEle.show(); }); };
ep_comments.prototype.init = function(){ var self = this; var ace = this.ace; // Init prerequisite this.findContainers(); this.insertContainer(); this.hideLineNumbers(); // Get all comments this.getComments(function (comments){ if (!$.isEmptyObject(comments)){ self.setComments(comments); self.collectComments(); } }); // Init add push event this.pushComment('add', function (commentId, comment){ self.setComment(commentId, comment); console.log('pushComment', comment); window.setTimeout(function() { self.collectComments(); }, 300); }); // On click comment icon toolbar $('#addComment').on('click', function(){ // If a new comment box doesn't already exist // Add a new comment and link it to the selection if (self.container.find('#newComment').length == 0) self.addComment(); }); };
exports.aceKeyEvent = function(hook, callstack, editorInfo, rep, documentAttributeManager, evt){ var evt = callstack.evt; var k = evt.keyCode; // Control Enter // Note: We use keydown here to stop enter -> paste quick events firing a new page if(evt.ctrlKey && k == 13 && evt.type == "keydown" ){ callstack.editorInfo.ace_doInsertPageBreak(); evt.preventDefault(); return true; } // Up arrow so we can handle up arrow at top of document regain focus to 0 offset if(k == 38){ var selStart = callstack.rep.selStart; var selEnd = callstack.rep.selEnd; if(selStart[0] == 0 && selStart[1] == 0 && selEnd[0] == 0 && selEnd[1] == 0){ // Move to the new Y co-ord to bring the new page into focus var $outerdocbody = $('iframe[name="ace_outer"]').contents().find('#outerdocbody'); $outerdocbody.scrollTop(0); // Works in Chrome $outerdocbody.parent().scrollTop(0); // Works in Firefox // Sighs } return true; } // Backspace deletes full line above if it is a pagebreak if(k == 8 && evt.type == "keyup"){ callstack.editorInfo.ace_doRemovePageBreak(); } return; }
exports.aceEditEvent = function(hook, callstack, editorInfo, rep, documentAttributeManager){ // This seems a little too often to run // If we're not in page view mode just hide all the things if($('#options-pageview').is(':checked')) {}else{ $('iframe[name="ace_outer"]').contents().find('iframe').contents().find("#innerdocbody").children("div").find('.pageBreakComputed').remove(); return false; } // Some more times to drop if(callstack.callstack.type == "handleClick" || callstack.callstack.type == "idleWorkTimer" || !callstack.callstack.docTextChanged){ // console.log("not doing anything so it's all good", callstack); }else{ // console.log("aceEditEvent so redrawing", callstack); // Redraw Page Breaks reDrawPageBreaks(); } }
selectSuggestion:function(context){ var suggestionFound = false; var $selectedSuggestion = $list.children(".selected").eq(0); // get the data out of the currently selected element var textToInsert = $selectedSuggestion.data("complementary"); // get the text typed by used before suggestion was selected var textAlreadyInserted = $selectedSuggestion.data("partialWord"); // get the original suggestion var suggestionText = $selectedSuggestion.text(); // the element the caret is in var currentLineNode = context.rep.lines.atIndex(context.rep.selEnd[0]).lineNode; if(textToInsert !== undefined){ // register listener to be able to call all callbacks when sendkeys is done $(currentLineNode).on("sendkeys", function() { // unregister listener to avoid duplicate calls in the future $(currentLineNode).off("sendkeys"); // fix replaced text if necessary (see more details on fixReplacedText()) autocomp.fixReplacedText(currentLineNode, suggestionText, textToInsert, textAlreadyInserted); autocomp.callPostSuggestionSelectedCallbacks(); }); // Empty lines always have a <br>, so due to problems with inserting text // with sendkeys, in this case, we need to insert the html directly var emptyLine = $(currentLineNode).find("br"); var lineIsEmpty = emptyLine.length; if (lineIsEmpty){ emptyLine.replaceWith("<span>" + textToInsert + "</span>"); this.adjustCaretPosition(currentLineNode, textToInsert); }else{ // we cannot use sendkeys with currentLineNode (the div whith the full line on editor) // because this removes lineAttributes if caret is on beginning of line. To avoid this, // we use sendkeys with the specific text node where caret is var currentElement = this.getNodeInfoWhereCaretIs(context).node; $(currentElement).sendkeys(textToInsert); } this.closeSuggestionBox(); suggestionFound = true; } return suggestionFound; },
$helperLines.each(function(index, element) { var $helperLine = $(element); var originalId = $helperLine.attr("id"); $helperLine.attr("data-original-id", originalId); // remove id to not mess up with existing lines $helperLine.attr("id", ""); });
linkClick: function() { var text = $(this).text(); console.log(text); timestampRegexp.lastIndex = 0; var parts = timestampRegexp.exec(text); if (parts) { if (!parts[2]) parts[2] = '0'; var time = parts[4] * 1 + parts[3] * 60 + parts[2] * 3600; console.dir($('#audioplayer')); ep_chaptermarks.audioplayer().currentTime = time; }; return false; },
this.ace.callWithAce(function(ace) { var rep = ace.ace_getRep(); var line = rep.lines.atIndex(rep.selStart[0]); var key = "#"+line.key; var padOuter = $('iframe[name="ace_outer"]').contents(); var padInner = padOuter.find('iframe[name="ace_inner"]').contents(); element = padInner.find(key); },'getFirstElementSelected', true);
$('#options-comments').on('click', function() { if($('#options-comments').is(':checked')) { padcookie.setPref("comments", true); self.container.addClass("active"); } else { padcookie.setPref("comments", false); self.container.removeClass("active"); } });
self.socket.emit('addCommentReply', data, function (){ // Append the reply to the comment // console.warn("addCommentReplyEmit WE EXPECT REPLY ID", data); $('iframe[name="ace_outer"]').contents().find('#'+data.commentId + ' > form.comment-reply .comment-reply-input').val(""); self.getCommentReplies(function(replies){ self.commentReplies = replies; self.collectCommentReplies(); }); });
$('#options-pagebreaks').on('click', function() { if($('#options-pagebreaks').is(':checked')) { pv.pageBreaksEnable(); padcookie.setPref("page_breaks", true); } else { pv.pageBreaksDisable(); padcookie.setPref("page_breaks", false); } });