Google App Script Page break at cursor? - google-apps-script

I have a button in my sidebar of which's purpose is to insert a page break where the cursor is. I tried scripting it to just insert a page break (not at the cursor but just in the body) and it works fine.
However, I can't seem to get it to work at the cursor:
function pageBreak() {
var cursor = DocumentApp.getActiveDocument().getOffset();
insertPageBreak(cursor);
}
How can I accomplish this?

You need to know the element type at the cursor position. Not all element types allow a page break to be inserted.
Begin by getting the element at the cursor position, then work from there.
function insertPgBrk() {
var theCursor = DocumentApp.getActiveDocument().getCursor();
var theElement = theCursor.getElement();
var elementTypeAtCursor = theElement.getType();
Logger.log('elementTypeAtCursor: ' + elementTypeAtCursor);
if (elementTypeAtCursor === DocumentApp.ElementType.PARAGRAPH) {
Logger.log('its the right type');
theElement.insertPageBreak(0);
};
};
You can't insert a page break in a TEXT element. The element needs to be a PARAGRAPH or a LISTITEM.

Related

element.addEventListener not adding listener

So I have an array of strings that will turn into buttons,
//At start
function acceptSuggestion() {
console.log(`clicked`)
console.log(this.textContent);
}
//Else where
suggestions.couldBe.innerHTML = ``;
list.suggestions.forEach(function (item) {
let button = document.createElement(`button`);
button.textContent = item;
button.addEventListener(`click`, acceptSuggestion);//before append
button.style = `text-align:center; width:50%`;
suggestions.couldBe.appendChild(button);
button.addEventListener(`click`, acceptSuggestion);//after append
suggestions.couldBe.innerHTML+=`<br>`;
});
It creates the buttons fine
But clicking them does nothing.
Why is this? I know I have the event right cuz of this: https://www.w3schools.com/js/js_htmldom_eventlistener.asp
If it matters, I am using electron.js to create an webpage like application, and not a browser.
The reason this is happening is because of this line:
suggestions.couldBe.innerHTML+="<br>";
What is happening is your Browser element is generating all new fresh HTML each loop because of the += on the innerHTML.
Basically in pseudo code:
var temp = suggestions.couldBe.innerHTML + "<br>;
suggestions.couldBe.innerHTML = temp;
This causes your element that was added via the suggestions.couldBe.appendChild(button); to be converted to html, then re-parsed and all new elements created from HTML each iteration of the loop. Because your Button event handler was created in JS; it is lost when it recreated the button from the HTML version.
You want to do this either all via JS; not mixing it. So my suggestion would be to change this line:
suggestions.couldBe.innerHTML+="<br>";
to
suggestions.couldBe.appendChild(document.createElement('br'));

CKEditor select as a single element

I'd like to have an element in a CKEditor editable div be treated like an input for the purposes of mouse selection. The element is a span but I want to make it so that a user cannot select part of its content along with content outside of it. For instance, if it has the following DOM:
Foo <span>gobbledigook</span> bar
the user should be able to select within the span, within "Foo" or "bar", or starting from "Foo" and extending into "bar", but no select from "Foo" into the span content. For these purposes, <span> should be treated like an <input /> (see this jsbin on how that works).
The span is actually using CKEditor's widget plugin, which appears to satisfy the other direction (that is, you can select within the span, but dragging from within the span to outside the span doesn't extend the selection outside the span). It's just the outside -> inside that's not working.
I have a workaround for this:
editor.widgets.on("checkSelection", function(event) {
var range = editor.getSelection().getRanges()[0];
var start = range.startContainer;
var end = range.endContainer;
// widgetRepository.getByElement() chokes if the argument is a text node
if (start.type === CKEditor.NODE_TEXT) {
start = start.getParent();
}
if (end.type === CKEditor.NODE_TEXT) {
end = end.getParent();
}
var endWidget = editor.widgets.getByElement(end);
if (
// We only worry about selecting from outside of a widget to the inside of one
endWidget
// Selection ends inside a widget and the start is not in a widget *or* is within a different widget
&& editor.widgets.getByElement(start) !== endWidget
) {
range.setEndBefore(endWidget.wrapper);
range.select();
}
});
Basically, if I detect that a selection is ending within a widget that it didn't start in, I move the end to right before the widget wrapper.

How to make HTML5 contenteditable div allowing only text in firefox?

I want to make div with contentEditable attribute which is allowing only text. It's easily achievable in Chrome by using:
<div contenteditable="plaintext-only"></div>
However it doesn't work in Firefox. Is there a way how to make text-only contenteditable div in Firefox ? I know it is possible, because Google Plus has such div, but I don't know how they do it.
I ran into this problem myself. Here is my solution which I have tested in Firefox and Chrome:
Ensure the contenteditable div has the css white-space: pre, pre-line or pre-wrap so that it displays \n as new lines.
Override the "enter" key so that when we are typing, it does not create any <div> or <br> tags
myDiv.addEventListener("keydown", e => {
//override pressing enter in contenteditable
if (e.keyCode == 13)
{
//don't automatically put in divs
e.preventDefault();
e.stopPropagation();
//insert newline
insertTextAtSelection(myDiv, "\n");
}
});
Secondly, override the paste event to only ever fetch the plaintext
//override paste
myDiv.addEventListener("paste", e => {
//cancel paste
e.preventDefault();
//get plaintext from clipboard
let text = (e.originalEvent || e).clipboardData.getData('text/plain');
//insert text manually
insertTextAtSelection(myDiv, text);
});
And here is the supporting function which inserts text into the textContent of a div, and returns the cursor to the proper position afterwards.
function insertTextAtSelection(div, txt) {
//get selection area so we can position insert
let sel = window.getSelection();
let text = div.textContent;
let before = Math.min(sel.focusOffset, sel.anchorOffset);
let after = Math.max(sel.focusOffset, sel.anchorOffset);
//ensure string ends with \n so it displays properly
let afterStr = text.substring(after);
if (afterStr == "") afterStr = "\n";
//insert content
div.textContent = text.substring(0, before) + txt + afterStr;
//restore cursor at correct position
sel.removeAllRanges();
let range = document.createRange();
//childNodes[0] should be all the text
range.setStart(div.childNodes[0], before + txt.length);
range.setEnd(div.childNodes[0], before + txt.length);
sel.addRange(range);
}
https://jsfiddle.net/1te5hwv0/
Sadly, you can’t. As this answer points out the spec only specifies true, false and inherit as valid parameters. The subject seems to have been discussed but if I’m not mistaken only Webkit implements support for plaintext-only.

Is that any option for search tabs in chrome?

that is we have opened many tabs.In that tabs i want to search specific tab. Please tell if any ext or option or add-on in chrome or firefox.
Firefox has this functionality built in. If you just start typing in the URL bar and the first character you type is % followed by a space, the rest of what you type will be treated as a search on the titles and urls of open tabs in all Firefox windows.
I'm not sure if this is the site to be asking for help finding extensions that do end user tasks such as this so I'll answer your question explicitly as well as explain how to do it programatically.
The short answer is, yes one extension that will allow you to do this can be found here:
Tab Title Search
The long answer is, in order to find all tabs with a certain name, you need to use the chrome tabs API
I whipped up a short piece of javascript to demonstrate how to have an extension that will create a popup with a search box that you type the desired tab title into. If the tab is found, it will be listed below the search box. If you click on the listing, you will switch to the tab.
// Function to search for tabs
function searchtabs() {
chrome.tabs.query({
title: ""
},
// Callback to process results
function(results) {
// Place holder for the tab to process
var foundTab = null;
// Text to match against
var queryText = document.getElementById("textToSearchInput").value;
// Div to place divs of matched title in
var queryAnswerDiv = document.getElementById("foundTabsDiv");
// Clear the current children
while (queryAnswerDiv.hasChildNodes()) {
queryAnswerDiv.removeChild(queryAnswerDiv.lastChild);
}
// Iterate over all the results
for (var i = 0; i < results.length; i++) {
// Keep track of the tab that is currently being processed
foundTab = results[i];
// If we have a title containing our string...
if (foundTab.title.indexOf(queryText) > -1) {
// Create a new div
var tabDiv = document.createElement("div");
// Set its content to the tabs title
tabDiv.innerHTML = foundTab.title;
// Let it know what the tabs id is
tabDiv.tabToSwitchTo = results[i].id;
// Allow for users to click on the representing div to switch to it
tabDiv.onclick = function() {
// Make the tab selected
chrome.tabs.update(this.tabToSwitchTo, {
selected: true
});
};
// Append the created div to our answer div
queryAnswerDiv.appendChild(tabDiv);
}
}
});
}
document.addEventListener('DOMContentLoaded', function() {
var inputField = document.getElementById("textToSearchInput");
inputField.focus();
inputField.onkeydown = searchtabs;
});
Also, if this is more what you are looking for rather than the extension that I linked, let me know and I can pack this extension.
Edit:
Fixed an error in using the wrong ID to get the input field as well as not getting the first letter of the title (use indexOf() > -1)
An extension that does this is Tab Hero for Chrome ($0.99 Chrome extension). It searches through all of the open tabs (across multiple windows) and offers to switch to the filtered tab. Try and see if it works for you.

Insert Text at Cursor Position in Ajax HTML Editor, using client Script

I have an Ajax HTML editor and a Dropdown above it.
On choosing an item form the Dropdown I want the Text of the selected item in the Dropdown to get pasted at the current cursor position in the AJAX HTML editor.
Any ideas..?
Yeah at the end of the Third day I finally got a solution for my problem, posting it here so that someone can save there precious time from re-inventing the wheel.
This is my Ajax ATML Editor:
<Ajax:Editor ID="EdtrHTML" runat="server" />
I want the selected text from the dropdown to be pasted at the current cursor position in the HTML editor,so I'm calling the function to insert text(InsertAtCursor) on the "change" event of the dropdown.
As a parameter to the function InsertAtCursor i'm passing the ID of the IFrame which gets created while rendering HTML editor.
$(document).ready(function () {
$('#<%:DropDownID.ClientID%>').change(function () {
var ddltext = $('#<%:DropDownID.ClientID%> option:selected').text();
var ddltext = ' [' + ddltext + '] '
InsertAtCursor(idofHTMLEditorIFrame, ddltext);//Function for Insertion
});
});
This is the function which inserts Text from the dropdown at the cursor position of Ajax HTML Editor.
function InsertAtCursor(myField, myValue) {
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
else if (myField.selectionStart == 0 || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos) + myValue +
myField.value.substring(endPos, myField.value.length);
}
else {
myField.value += myValue;
}
}
In my case my Ajax Editor was inside an Update panel and so after a partial post back the script stopped working, and i found help here.
Hope this works for you too...Cheers..!!