InDesign CS6 javascript: importXML and remove empty pages - javascript

I use InDesign CS6. I wrote a javascript to add an option into menu: it first imports an XML in a document, then removes empty pages.
As run, before it actually imports an XML file, it removes empty pages. So there aren't enough pages for the XML.
How to excute these 2 functions as wanted? Here is my program:
var menuItem = "XML";
var smaTitle1 = "Import XML";
var sma1 = app.scriptMenuActions.add(smaTitle1);
// Add an Event Listener
sma1.addEventListener(
/*event type*/ 'onInvoke',
/*event handler*/ function(){
importXML(xmlPath);
}
);
sma1.addEventListener(
/*event type*/ 'afterInvoke',
/*event handler*/ function(){
// Remove empty pages
alert("remove pages");
removeEmptyPages();
}
);
function importXML(xmlPath){
if (app.documents.length != 0){
var myDocument = app.documents.item(0);
//import the entire XML structure in the document.
var myXMLImportPreferences = myDocument.xmlImportPreferences;
myXMLImportPreferences.allowTransform = false;
myXMLImportPreferences.ignoreWhitespace = true;
myXMLImportPreferences.removeUnmatchedExisting = false;
myXMLImportPreferences.importStyle = XMLImportStyles.MERGE_IMPORT;
myXMLImportPreferences.repeatTextElements = true;
var path = new File(xmlPath);
var file = path.openDlg("Importer XML", "XML:*.xml", false);
if (file != null) {
myDocument.importXML(file);
}
}
}
function removeEmptyPages(){
...
// a loop to remove empty pages
pages[i].remove();
...
}

Why don't you just call your removeEmptyPages function at the end of your importXML function ?
function importXML(xmlPath) {
…
removeEmptyPages();
}

Related

Why can't I use a script function to affect variables in html written out by a JSON file?

Hopefully a quick question.
I'm using a JSON file to write out some html and populate with variables from the JSON and append it to part of my html file. This works and is fine. However, I now want to use a different script to apply show and hide filters based on class attributes to the html that has been printed. For some reason, this isn't working. If I just copy and paste the html with variables back into the original document after its been printed out, then the script works though. Is this an issues of synchronicity?
Here's the second script I'm looking to execute if it helps:
$(document).ready(function(){
var targets = $('.filter'),
buttons = $('.filter-button');
buttons.click(function(){
var value = $(this).data('filter');
if(value == "all")
{
buttons.removeClass('checked');
targets.show();
}
else
{
if($(this).hasClass('checked'))
{
$(this).removeClass('checked');
var checkedClasses = buttons.filter('.checked').toArray().map(function(btn){return $(btn).data('filter');});
if(checkedClasses.length == 0)
{
buttons.removeClass('checked');
targets.show();
}
else
{
checkedClasses = $.grep(checkedClasses, function(n, i){ return n != value }),
selector = '.' + checkedClasses.join('.'),
show = targets.filter(selector);
targets.not(show).hide();
show.show();
}
}
else
{
$(this).addClass('checked');
var checkedClasses = buttons.filter('.checked').toArray().map(function(btn){return $(btn).data('filter');}),
selector = '.' + checkedClasses.join('.'),
show = targets.filter(selector);
targets.not(show).hide();
show.show();
}
}
});
});

JS script dynamic loading inconsitent

I need help on getting some dynamic js loading working properly. the issue I'm having now is that it is not consistently loading the js script when loading the page. here is the script that I have at the bottom of the page that I'm opening:
function getJSOnload() {
var element;
var parent = document.body;
var cdn = [
LoadFormValidationScript(LoginFormValidator),
LoadFormValidationScript(SetFormLocaleLang)
];
var i = 0, file;
for (i;i<cdn.length;i++) {
file = cdn[i];
element = document.createElement("script");
element.type = "text/javascript";
element.src = file;
parent.appendChild(element);
//free file's value
file = null;
}
};
if (window.addEventListener) {
window.addEventListener("load", getJSOnload(), false);
}
else if (window.attachEvent) {
window.attachEvent("onload", getJSOnload());
}
else window.onload = getJSOnload();
this is the LoadFormValidationScript that i have in an external js file
function LoadFormValidationScript(callback){
function LoadValidationScripts() {
$.getScript('/plugins/script1.min.js', function() {
$.getScript('/plugins/script2.min.js', function() {
$.getScript('/plugins/script3.addons.min.js', function() {
$.getScript('/plugins/script.es_ES.js', function() {
$.getScript('/plugins/script4.fr_FR.js', function() {
$.getScript('/plugins/script5.de_DE.js', callback);
});
});
});
});
});
}
if (!$.fn.formValidation){
LoadValidationScripts();
} else {
if (callback && typeof(callback) === "function") {
callback();
}
}
}
and this is the "setFormLocaleLang" function as an example since it is short one
function SetFormLocaleLang(){
var nberOfForm = document.forms.length; //get number of forms on the page
// if there are no forms in the page don't waist your time
if (nberOfForm > 0) {
var Locale = "en_US"; //default formVlaidation language
//var lang = $('html').attr('lang'); // get the page language
var lang = $("#selectedLanguage").attr('data-lang-id');
// assign the Locale depending on page language
switch (lang) {
case "en" : Locale = 'en_US'; break;
case "fr" : Locale = 'fr_FR'; break;
case "es" : Locale = 'es_ES'; break;
case "de" : Locale = 'de_DE'; break;
default : break;
};
//set the locale for all the forms in the page
for (var i = 0; i < nberOfForm; i++) {
var strFormID = "#" + document.forms[i].id;
$(strFormID).formValidation('setLocale', Locale);
}
}
}
like is said it does work and load the scripts but not all the time, sometimes i have to refresh the page like 3 time for the script to load and sometimes it loads on the first try as soon as i open the page. not sure what is going on and why i get this behaviour.
You're attaching the handlers incorrectly - you're calling getJSOnload() immediately, instead of waiting for document-loaded, as you intend. Reference, don't call, the function:
if (window.addEventListener) {
window.addEventListener("load", getJSOnload, false);
}
else if (window.attachEvent) {
window.attachEvent("onload", getJSOnload);
}
else window.onload = getJSOnload;

jQuery Example: Reseting an input file element in case of non-allowed file-extensions

If someone tries to upload a file with a non-allowed file-extension, this input-file-element should get "reseted".
That is the input-file-element
<input type="file" id="image1">
These are the corresponding jQuery-statements (document is ready) and I get "TypeError: myElement.clone is not a function" (while I am trying this solution here: Clearing <input type='file' /> using jQuery)
$(document).ready(function() {
$('#image1').change(function(event) {
checkExtensions(this.files[0].name, $(this).get());
});
function checkExtensions (fileName, element) {
var myElement = element;
var allowedExtensions = new Array ('pdf','gif','jpg','png');
var currentExtension = fileName.split('.').pop();
if ($.inArray (currentExtension, allowedExtensions) > -1) {
// everythins is OK, further instructions take place
} else {
// reset the file input element
myElement.replaceWith( myElement = myElement.clone( true ) );
}
}
});
You are passing the native DOM element to your function instead of the jQuery object containing the element. Native DOM elements do not have the function clone() (or replaceWith either). Try this instead:
$('#image1').change(function(event) {
checkExtensions(this.files[0].name, $(this)); // note, I removed .get()
});
function checkExtensions (fileName, $element) {
var allowedExtensions = new Array ('pdf','gif','jpg','png');
var currentExtension = fileName.split('.').pop();
if ($.inArray (currentExtension, allowedExtensions) > -1) {
// everything is OK, further instructions take place
} else {
// reset the file input element
$element.replaceWith($element.clone(true).val(''));
}
}
Example fiddle

jQuery queue in Chrome userscript with popups?

I would like to ask if it is possible to build Chrome or Greasemonkey script witch could open all popups in queue. So far i have 2 seperate scripts for this, but that is not working well since popups have anti-spam feature that don't allow too much of them at the same time.
What i would like to do is to process array of popup links in queue fashion and only open next when previous is closed. I have no expirience when it goes down to queues and any kind of event binding.
So resources i got:
1) Array of links already prepared
var URL_Array = [];
$('form[name="form_gallery"] .img img').each(function(i,e){
// Format URL array here
if($(this).closest('.object').children('.phs_voted_count').length == 0){
var string = e.src;
var nowBrake = string.substring(string.length-7,7);
var splited = nowBrake.split('/');
var urlStr = '/window/friend/gallery_view/'+splited[3]+'/'+splited[4]+'.html';
URL_Array[i] = urlStr;
}
});
2) Script that votes on image in popup
/*######################################################*/
var voteBy = '#vte_mark_12'; // Prefered vote icon
var voteDefault = '#vte_mark_5'; // Default vote icon
var voteFormLoc = 'image_voting'; // Image voting popups form
var buyExtraVote = 'image_voting_buy'; // If run out of votes buy more
var captchaLoc = 'input[name="captcha"]'; // Captcha input field
var captchaTxt = 'Enter captcha text!'; // Captcha alert text
var simpatyFormId = '#sym_send'; // Simpaty window form
var startScript = true;
var formProcessedAlready = false; // Used to check if image already was voted
/*######################################################*/
$(function(){
if(startScript){
if($(captchaLoc).length > 0){
alert(captchaTxt);
$(captchaLoc).focus().css('border', '2px solid red');
return false;
}else{
if($('#50').length > 0){
$('#50').attr('checked', true);
$('form').attr('id', buyExtraVote);
$('#'+buyExtraVote).submit();
}else{
$('form').attr('id', voteFormLoc);
if($(voteBy).length > 0){
$(voteBy).attr('checked', true);
setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
}else if($(voteDefault).length > 0){
$(voteDefault).attr('checked', true);
setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
}else{
// If we have simpaty box autocast submit
if($(simpatyFormId).length > 0){
if($(captchaLoc).length > 0){
alert(captchaTxt);
$(captchaLoc).focus().css('border', '2px solid red');
return false;
}else{
$(simpatyFormId).submit();
formProcessedAlready = true;
}
}else{
formProcessedAlready = true;
}
}
}
}
if(formProcessedAlready){
self.close();
}
}
});
As far as i can understand it should go like this:
1) Get all unvoted urls and form array (done)
2) Queue all popups to open
3) Start first popup
4) Voting done and popup closes (done)
5) Start second popup
6) When array finished switch to next page (done)
What you think?
What are the exact URL's of the main page(s) and also of the popups?
What version of jQuery are you using, and how are you including it?
The exact URLs are important because the script needs to handle both the main pages and the popups and operate differently on each.
Their are 2 main ways to handle this. Either:
Use include directives to make sure that the script runs on both the main page and the popup, but switches its behavior depending on the page type. This will have two different instances of the script running simultaneously, which is not a problem.
Use include and possibly exclude directives to ensure that the script only runs on the main page. Then have the popup-opening code manipulate the form.
Here's how to do approach 1:
(1) Suppose the main pages were like:
    somewhere.com/main/*
    and the popup pages were like:
    somewhere.com/window/friend/gallery_view/*
    Make sure the script's include-directives fire on both sets of pages.
(2) Ensure that jQuery is available on both kinds of pages. jQuery 1.5.1 is recommended. jQuery 1.3.2 probably won't work for the following code.
(3) Then code like the following should work:
var URL_Array = [];
var PopupQueue = $({}); //-- jQuery on an empty object - a perfect queue holder
//--- Is this a popup window or the main page?
if ( /\/window\/friend\/gallery_view\//i.test (window.location.href) )
{
//--- This is a popup page
/*######################################################*/
var voteBy = '#vte_mark_12'; // Prefered vote icon
var voteDefault = '#vte_mark_5'; // Default vote icon
var voteFormLoc = 'image_voting'; // Image voting popups form
var buyExtraVote = 'image_voting_buy'; // If run out of votes buy more
var captchaLoc = 'input[name="captcha"]'; // Captcha input field
var captchaTxt = 'Enter captcha text!'; // Captcha alert text
var simpatyFormId = '#sym_send'; // Simpaty window form
var startScript = true;
var formProcessedAlready = false; // Used to check if image already was voted
/*######################################################*/
$(function(){
if(startScript){
if($(captchaLoc).length > 0){
alert(captchaTxt);
$(captchaLoc).focus().css('border', '2px solid red');
return false;
}else{
if($('#50').length > 0){
$('#50').attr('checked', true);
$('form').attr('id', buyExtraVote);
$('#'+buyExtraVote).submit();
}else{
$('form').attr('id', voteFormLoc);
if($(voteBy).length > 0){
$(voteBy).attr('checked', true);
setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
}else if($(voteDefault).length > 0){
$(voteDefault).attr('checked', true);
setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
}else{
// If we have simpaty box autocast submit
if($(simpatyFormId).length > 0){
if($(captchaLoc).length > 0){
alert(captchaTxt);
$(captchaLoc).focus().css('border', '2px solid red');
return false;
}else{
$(simpatyFormId).submit();
formProcessedAlready = true;
}
}else{
formProcessedAlready = true;
}
}
}
}
if(formProcessedAlready){
self.close();
}
}
});
}
else
{ //--- This is a main page
$('form[name="form_gallery"] .img img').each(function(i,e){
// Format URL array here
if($(this).closest('.object').children('.phs_voted_count').length == 0){
var string = e.src;
var nowBrake = string.substring(string.length-7,7);
var splited = nowBrake.split('/');
var urlStr = '/window/friend/gallery_view/'+splited[3]+'/'+splited[4]+'.html';
URL_Array[i] = urlStr;
}
});
//--- Load up the queue.
$.each (URL_Array, function (PopupNum, PopupURL) {
PopupQueue.queue ('Popups', function (NextQ_Item) {
OpenPopupFromQueue (NextQ_Item, PopupNum+1, PopupURL);
} );
} );
//--- Launch the Popups, one at a time.
PopupQueue.dequeue ('Popups');
}
function OpenPopupFromQueue (NextQ_Item, PopupNum, PopupURL)
{
var PopupWin = window.open (PopupURL, "_blank");
if (!PopupWin)
{
console.log ('Bad URL ' + PopupURL)
setTimeout (function() { NextQ_Item (); }, 2003);
return;
}
/*--- Only after the popup has loaded can we do any processing.
*/
PopupWin.addEventListener (
"load",
function () {
/*--- Setup the listener for when the popup has closed.
We fire the next popup from the queue, there.
*/
PopupWin.addEventListener (
"unload",
function () {
PopupClosed (NextQ_Item);
},
false
);
/*--- We could process the popup here, but it's better to let another instance of this
script do it, instead.
*/
},
false
);
}
function PopupClosed (NextQ_Item)
{
//--- Launch the next popup from the queue.
NextQ_Item ();
}
You could do something like:
var links = get_your_links();
function process_one() {
if(links.length > 0) {
show_popup(links.pop(), process_one);
}
}
function show_popup(link, callback) {
var popup = window.open(link, "mywindow", "width=100,height=100");
$(popup).bind("beforeunload", function() {
process_one();
return true;
})
}
I hope it helps...

Updating page HTML causes endless loop

I'm writing a Firefox extension. The extension replaces certain words on the page with other words. Here's the basic code I'm using:
function startup() {
gBrowser.addEventListener("load", pageLoad, true);
}
function pageLoad(event) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
}
The problem is that this code is causing an endless loop. When I set the innerHTML property of the body, it sends another load event, which causes the endless loop.
How can I modify the page when it loads without causing the page load event to fire again?
You could use the following code to check if it has already been run before.
var loaded = false;
function pageLoad(event) {
if (!loaded) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
loaded = true;
}
}
Alternatively, if you wanted to keep the loaded variable out of global scope, you could use a closure:
var pageLoad = (function () {
var loaded = false;
return function(event) {
if (!loaded) {
if (event.originalTarget instanceof HTMLDocument) {
var ht = content.document.body.innerHTML;
ht = ht.replace(/\bthe\b/g,"el");
content.document.body.innerHTML = ht;
}
loaded = true;
}
}
}();
The outer function gets executed immediately and returns the inner function which will have visibility of the loaded variable due to closure.
Would having a div or span tag immediately inside of your body tag be an option? Then you could just update the innerHTML of that element, and not the entire body...

Categories