Indesign (Javascript) footnote as crossref destination destroys numbering - javascript

yeah i have a problem.
So i have a script which puts all footnotes at the end of the document and makes crossreferences from the little number in text to the fitting endnote.
now i want to add a backlink, so when i have a long document(book) i dont have to scroll back by hand, but can just click on the endnote and get back.
by now i have managed to get the endnotes as crossref sources, but i struggle with the crossrefdestination
when i use footnote.storyOffset as destination, it screws up the numbering of the footnotes in text.
for example the first footnote just disappears from text, then there comes 1,3,3,4,5,7... and so on. why does this happen?? im just using this insertion point as destination and suddenly it screws up everything.
it would also be enough to put the footnote numbers manually into the text, but i dont know how to delete the scrambled numbers in the text.
i could also use the next or previous character as insertionPoint, but how do i get there?
Im pretty new to that indesign script stuff. hope somebody can help me.
here is the critical part of the source:
stories[j].insertionPoints[-1].contents = SpecialCharacters.PAGE_BREAK; // add new page for notes
stories[j].insertionPoints[-1].contents = 'Notes';// title
footn = stories[j].footnotes;
for (var i = 0; i < footn.length; i++)
{
stories[j].insertionPoints[-1].contents = '\r';
endnote = footn[i].texts[0].move (LocationOptions.after, stories[j].insertionPoints[-1]);
endnote.applyParagraphStyle (note_styles.first, false);
if (i === 0)
{
endnote.numberingContinue = false;
endnote.numberingStartAt = 1;
}
if (endnote.paragraphs.length > 1)
{
endnote.paragraphs.itemByRange (1,-1).applyParagraphStyle (note_styles.next, false);
}
//var stoff = footn[i].storyOffset;
//stoff.contents = ''+(i+1);
//stoff.applyCharacterStyle(note_styles.char_style_in_text);
//stoff.appliedCharacterStyle.position= Position.superscript;
backlink_destination = doc.paragraphDestinations.add (footn[i].storyOffset); // position of footnote in text
endnote_destination = doc.paragraphDestinations.add (endnote.insertionPoints[0]);
try
{
crb = app.activeDocument.crossReferenceFormats.add({name:'backlink'+i});
crb.appliedCharacterStyle = note_styles.char_style_endnote;
crb.buildingBlocks.add (BuildingBlockTypes.customStringBuildingBlock);
crb.buildingBlocks.anyItem().customText = endnote.contents;
}
catch(_)
{
crb = app.activeDocument.crossReferenceFormats.item ('backlink'+i);
};
backlink_source = doc.crossReferenceSources.add (endnote, crb); // position of note at end of story
endnote_source = doc.crossReferenceSources.add (footn[i].storyOffset, note_styles.cr_format);
doc.hyperlinks.add(backlink_source, backlink_destination, {visible: false}); //add link from notes to text
doc.hyperlinks.add(endnote_source, endnote_destination, {visible: false});
} // for

fixed it:
i just flipped the order of making the crossrefs.
i flipped the following lines
backlink_destination = doc.paragraphDestinations.add (footn[i].storyOffset);
endnote_destination = doc.paragraphDestinations.add (endnote.insertionPoints[0]);
to
endnote_destination = doc.paragraphDestinations.add (endnote.insertionPoints[0]);
backlink_destination = doc.paragraphDestinations.add (footn[i].storyOffset);
and
backlink_source = doc.crossReferenceSources.add (endnote, crb);
endnote_source = doc.crossReferenceSources.add (footn[i].storyOffset, note_styles.cr_format);
to
endnote_source = doc.crossReferenceSources.add (footn[i].storyOffset, note_styles.cr_format);
backlink_source = doc.crossReferenceSources.add (endnote, crb);
and
doc.hyperlinks.add(backlink_source, backlink_destination, {visible: false});
doc.hyperlinks.add(endnote_source, endnote_destination, {visible: false});
to
doc.hyperlinks.add(endnote_source, endnote_destination, {visible: false});
doc.hyperlinks.add(backlink_source, backlink_destination, {visible: false});
i dont know why, but it works when put in this order... this doesnt testify to good software...
how could i expect good software for that price?

Related

Strange flickering after manipulating html with JS

I am stuck with a problem and I cannot figure out what the cause is, I have created a small js script that modifies a table element, but every time it does I see flickering of the elements, I checked the HTML elements and there is no white space or whatsoever.
Short video: https://i.imgur.com/86RODJL.mp4
Is it possible an css property that causes this behavior ?
Tried to troubleshoot by inspecting the html elements for white space or similar.
JS function:
function correctOrderQtyMinus(element) {
var elementTR = element.parentNode.parentNode.parentNode;
var totalExBTW = document.getElementById('totalExBTW');
var totalBtw = document.getElementById('totalBtw');
var btwAmount = document.getElementById('btwAmount');
if(document.getElementById('checkoutForm')) {
if(element.parentNode.querySelector('#productQty').value > 1) {
var newAmount =+ parseFloat(elementTR.querySelector('#productPriceTotalBtw').innerText) - parseFloat(elementTR.querySelector('#productPriceWithBtw').innerText);
elementTR.querySelector('#productPriceTotalBtw').innerText =+ newAmount.toFixed(2);
totalExBTW.innerText =+ (parseFloat(totalExBTW.innerText)- parseFloat(elementTR.querySelector('#productPriceExBtw').innerText)).toFixed(2);
totalBtw.innerText =+ (parseFloat(totalBtw.innerText) - parseFloat(elementTR.querySelector('#productPriceWithBtw').innerText)).toFixed(2);
btwAmount.innerText = parseFloat(totalBtw.innerText - totalExBTW.innerText).toFixed(2);
totalBtw.innerText = parseFloat(totalBtw.innerText).toFixed(2);
totalExBTW.innerText = parseFloat(totalExBTW.innerText).toFixed(2);
elementTR.querySelector('#productPriceTotalBtw').innerText = parseFloat(elementTR.querySelector('#productPriceTotalBtw').innerText).toFixed(2);
} else {
console.log('Cannot go less than 1');
}
}
event.preventDefault();
}

Detect weather user clicked on text or white space inside textarea

I have a textarea that can be draged around in which text should still be selectable by draging over it. In order to distinguish a "over text drag" from a "move drag" I have to know weather the point where the user started its drag (i.e. mousedown position) was white space or text.
The only thing I can come up with to figure this out is calculating using character width and line height, which I would like to avoid.
Not really sure what you're asking, but here's my attempt to translate the insanity into working code:
let doc, htm, bod, I; // for use on other loads
addEventListener('load', ()=>{
doc = document; htm = doc.documentElement; bod = doc.body; I = id=>doc.getElementById(id);
// magic under here
const test = I('test');
function whiteStart(string){
if(string.match(/^\s+/)){
return true;
}
return false;
}
test.oncopy = test.ondragstart = function(){
let s = getSelection().toString();
if(whiteStart(s)){
console.log('"'+s+'" starts with one or more white spaces');
}
else{
console.log('"'+s+'" starts without a white space');
}
}
}); // end load
<div id='test'>I&apos;m just going to put some text in here so we can run a very basic test. I hope this helps!</div>

Openlayers 5: Modify interaction, how to get vertex pointed to

When modifying a feature, there is the option to delete a single vertex. According to the docs it says:
removePoint(){boolean}:
Removes the vertex currently being pointed.
(https://openlayers.org/en/latest/apidoc/ol.interaction.Modify.html)
Since I work on mobile devices, I would like to present a popup with a delete button next to the a vertex if a user clicks or hovers over it. Therefore I need the coordinates of this vertex. I can see the vertex indicated on the map with a different style, but how can I get it or its coordinates?
It must be somewhere in some selection because the automatic "pointing to" style and removePoint method works per se fine.
Here is a solution that use a button to delete a vertex.
The button is shown or hidden if there is a vertex to delete (it could be a popup).
It uses:
condition option to show the button if there is a point near the click
insertVertexCondition option to hide the button (there is no vertex here)
modifystart and modifyend event to hide the button (we are moving and we don't want the button to be visible)
removePoint function when click on the button
The button is not show if you're moving or if there is no point to delete.
It doesn't rely on features that are not documented or private.
You can see it in action here.
var btElt = document.getElementById("delete");
// Modify interaction
var mod = new ol.interaction.Modify({
source: vector.getSource(),
// Show on select
condition: function(e){
// Check if there is a feature to select
var f = this.getMap().getFeaturesAtPixel(e.pixel,{
hitTolerance:5
});
if (f) {
var p0 = e.pixel;
var p1 = f[0].getGeometry().getClosestPoint(e.coordinate);
p1 = this.getMap().getPixelFromCoordinate(p1);
var dx = p0[0]-p1[0];
var dy = p0[1]-p1[1];
if (Math.sqrt(dx*dx+dy*dy) > 8) {
f = null;
}
}
if (f) btElt.style.display = "inline-block";
else btElt.style.display = "none";
return true;
},
// Hide on insert
insertVertexCondition: function(e) {
btElt.style.display = "none";
return true;
}
});
// Hide on modifying
mod.on(['modifystart','modifyend'], function(){
btElt.style.display = "none";
});
map.addInteraction (mod);
// Delete vertex when click the button
function deleteVertex() {
mod.removePoint();
btElt.style.display = "none";
}
Alright digging into the source code I came up with a kinda ugly but so far working solution. For the record, this is the code.
this.modify = new Modify({
features: new Collection([this.selectedFeature]),
pixelTolerance:30,
condition: (event)=>{
if(this.modify["lastPointerEvent_"] && this.modify["vertexFeature_"])
this.removePointPopup.setPosition(this.modify["lastPointerEvent_"].coordinate);
else
this.removePointPopup.setPosition(undefined);
return true;
}
});
this.modify.on("modifyend",ev=>{
this.removePointPopup.setPosition(ev.target["lastPointerEvent_"].coordinate);
})
[...]
removePoint(){
this.modify.removePoint()
this.removePointPopup.setPosition(undefined);
}
If someone knows about a nicer solution, feel free to post it.

Is it efficient to scan the page for a keyword every second?

So I am working on a personal userscript for myself and a few friends. The userscript is used to block keywords on a page.
To search for the keywords on the page I use:
var filter = ["worda", "wordb", "wordc"];
var found = false;
var check =
function () {
//Stores the content of the head and body in the document.
var head = $("head").html();
var body = $("body").html();
$.each(filter, function(index, item) {
if ((head + body).toString().toLowerCase().contains(item.toLowerCase())) {
window.clearInterval(interval);
console.log("Found: " + item);
found = true;
return false;
}
});
if (found) {
$("body").hide();
var originalTitle = $(document).prop("title");
$(document).prop("title", "Blocked");
window.setTimeout(function() {
if (confirm("This page contains a blocked keyword, are you sure you'd like to continue?")) {
$(document).prop("title", originalTitle);
$("body").show();
return;
}
}, 1);
}
};
And then I set it to repeat every second through:
var interval = window.setInterval(check, 1000);
The reason I re-check the page every second is because new content may have been dynamically created through Javascript, and I need to make sure that it is also filtered.
However, I'd like to know if this is the most efficient way to scan the page for keywords, or if there is a more efficient method which does not require me to re-check the entire page (possibly only need to re-check new elements).
Also I'd like to push the interval as low as I can (I'm thinking around 100ms), however I do not know if this will be very resource-friendly.
Thank you for the help.
You're correct that scanning the content of the page periodically is an inefficient approach to the problem. That being said, if it's only running once a second, it probably isn't a huge deal.
Still, there's a better option. The MutationObserver interface can be used to fire events when a document, or a part of a document, is modified. This is perfect for what you're trying to do:
var observer = new MutationObserver(function() {
… scan the document for your keywords …
});
observer.observe(document, {
childList: true,
characterData: true,
subtree: true
});

getting only last class assigned with this.class

Please can anyone see what is wrong in this code,
I have 2 class images with .man and .girl which contains 10 images in each.
next I have 2 div's #manCount and #girlCount which display total images number (10 in each)
when I move one image to #drop, It decrease 1 number from #manCount. So ther are total 10 images with class name .man, When the last image is moved to #drop I get a pop up that all images are processed.
now I also wants to process .girl class images but when i have both classess initialize it only work with .girl class.
function Dragger(c){
this.classname = c;
}
Dragger.prototype.Init = function(){
var classM = this.classname;
var manCount = parseInt($("#"+classM+"Count").text());
$("."+classM).draggable();
$("#drop").droppable({
drop: function() {
if(manCount <= 0){
alert("There are no more pictures left. " + classM );
return false;
}
manCount -= 1;
$("#"+classM+"Count").text(manCount);
}
});
};
var man = new Dragger("man");
man.Init();
above code runs just fine but when I initilize a new object
var man = new Dragger("man");
man.Init();
var girl = new Dragger("girl");
girl.Init();
It always pick girl object, any help where I am doing wrong?
It always return me female object on drag.
A screenshot of display: http://screensnapr.com/v/SrsyGz.png
Here is problem: http://screensnapr.com/v/hxrZYa.png
Thanks
Edit:
Ok i have fixed this issue by adding mouseover event, i am not sure how perfect it is thogh as i am pretty new to it but it works as expected
$(".man").mouseover(function(){
var man = new Dragger("man");
man.Init();
});
$(".girl").mouseover(function(){
var girl = new Dragger("girl");
girl.Init();
});
Maybe it’s because you are calling $('#drop').droppable() in the Init function, so it gets initiated more than once on the same element (#drop).

Categories