Here's a conundrum I've discovered.
I have a script that opens a file in InDesign, does some work to it, then closes it. To help speed it up, I have turned off displaying the file by using the false argument while opening the file, like so:
var document = app.open(oFile, false);
Sometimes, while doing some work on an open file, the script may need to need to resize a certain page from 11 inches tall to 12.5 inches tall, thusly:
if (padPrinted) {
for (var p = 0; p < outputRangeArray.length; p++) {
var padPage = document.pages.item(outputRangeArray[p]);
if (padPage.bounds[2] - padPage.bounds[0] === 11) {
padPage.select();
var myY1 = padPage.bounds[0] -= 0.75;
var myX1 = padPage.bounds[1];
var myY2 = padPage.bounds[2] += 0.75;
var myX2 = padPage.bounds[3];
padPage.reframe(CoordinateSpaces.INNER_COORDINATES, [[myX1*72, myY1*72], [myX2*72, myY2*72]]);
}
}
}
This has been working flawlessly for me for quite some time, but now it sometimes errors on the line padPage.select() with the message:
No document windows are open.
If I go back to the line which opens the file and delete the false argument, then the script works fine.
So, I'd like to know if there's any way to get around this. I'd like to have the documents open without displaying them, but still have the ability to resize a page when I need to. Any ideas?
Why do you call padPage.select();? It doesn't look like your code needs it.
Edit:
On page to page 42 of the Adobe InDesign CS6 Scripting Guide: Javascript, there is a sample snippet that reframes the page and doesn't call select(). The snippet comes from a sample script in the InDesign CS6 Scripting SDK (scroll to the bottom).
The path of the sample script is Adobe InDesign CS6 Scripting SDK\indesign\scriptingguide\scripts\JavaScript\documents\PageReframe.jsx
Inspecting this script, we see that it never calls select(). In fact, the PageResize.jsx never calls select() either.
Also, while InDesign Server can resize and reframe pages, you'll notice that the select() function is missing entirely. It would seem that select() affects only the GUI.
In the face of all this evidence, I would wager that the scripting guide is wrong when it says "you must select the page". Try removing that line and see if it works.
Edit 2
On an unrelated note, the following lines might be troublesome:
var myY1 = padPage.bounds[0] -= 0.75;
var myX1 = padPage.bounds[1];
var myY2 = padPage.bounds[2] += 0.75;
The += and -= operators will attempt to modify the bounds directly, but the bounds are read-only and can only be modified with methods such as resize or reframe. I would recommend changing it to this:
var myY1 = padPage.bounds[0] - 0.75;
var myX1 = padPage.bounds[1];
var myY2 = padPage.bounds[2] + 0.75;
Related
I have more than 20 js files like jQuery etc in my project, when I scroll it gets hung as it loads very lazily. How to find which file creates the problem?
It may be one of several things and without looking at your code I couldn't possibly say what the cause would actually be. You've asked an extremely subjective comment. There's no silver bullet when it comes to debugging and problem solving.
I've always found the Occams Razor approach the most effective.
"When you remove all other options, whatever remains, however unlikely, must be the problem/solution/answer."
Firstly, before you start removing JS files, have you tried doing a full-search of your project for .scroll? There's a high likelihood that there are several functions which run on-scroll which are causing reflows, a common problem which such code.
Once you've assessed your code, you can verify exactly what happens when the code executes using the "Performance" tab in Google Chrome to do this (Learn how to use the Performance Tab here). You can take the appropriate action.
Assuming that your code suffers from the same problem I've encountered in my formative years using jQuery - multiple or problematic on-scroll events - you can de-bounce the ones which can run after scrolling has completed. You can do this by using the following pattern.
Scenario 1:
This would run many times. 'N' times for each scrollwheel drag (dependent on settings - mine is 10) and even more times when using the scrollbar.
function someFunc() {
let someArr = [];
for(var i = 0; i < 1000000; i++ {
someArr.push((i * 2));
}
for(var i = 0; i < someArr.length; i++ {
someArr[i] /= 0.25;
}
}
$(window).on("scroll", function() {
someFunc();
});
Scenario 2:
This would run once after scrolling has finished. Waiting for 200ms before executing to ensure the user has completely finishing scrolling.
function someFunc() {
let someArr = [];
for(var i = 0; i < 1000000; i++ {
someArr.push((i * 2));
}
for(var i = 0; i < someArr.length; i++ {
someArr[i] /= 0.25;
}
}
let debouncedTimeout = null;
$(window).on("scroll", function() {
if (debouncedTimeout) {
clearTimeout(debouncedTimeout);
}
debouncedTimeout = setTimeout(someFunc(), 200);
});
Add a console.log("Check") with numbers (check1, check2) and so on in every file. Check your console in your browser, look in which series they load in console. If it takes a while to load the next log you know its the previous file with the number you logged.
Your console should say everything.
But loading so many js files is bad practice.
Try to fit everything in to one, so in further bckend development can go to an .min.js
But if you keep doing this. The simplest way is to keep track of the funcioncesequences with console.log, so that you evrything works how it is supposed to
:)
I know this is going to be difficult to get help for, but anyway:
In short: this page renders OK the first time on Safari (both Mac and iPhone/iPad), the second (after refresh) time some things are not shown. Opening the page in Private mode -> works always. Opening it in Chrome -> works always
In long: the page is a temporary solution and hacked together... Currently it is driven by Caspio (a no-code rapid development environment). The no-code comes at a price however of a limited possibilities. We are rewriting the system in a proper front-end/back-end environment but for the time-being we should get this page to work.
The page consists of 2 blocks rendered by Caspio. I need to get some elements from block 2 and put them into an element of block 1 (and hide block 2 then) with JS. Again the options on how to get the elements are limited by what Caspio is providing, it's very dirty code which I hope to get rid of asap!
<script type="text/javascript">
window.addEventListener("load", function (e) {
const dataPageId = "46629000bb2da6866c8b4cc09dc1";
// Default image for the promotion (in case no image uploaded)
var theImage = document.createElement("img");
theImage.setAttribute("src", "images/noImageFound.png");
theImage.setAttribute("alt", "No Image");
// get the text form the placeholder virtual fields and hide it (not possible in Caspio to hide it)
// First get the title
var promoTitleVirtual = document.querySelectorAll("[id*='cbParamVirtual1']");
var promoTitleParagraph = document.createElement("h3");
var promoTitle = document.createTextNode(promoTitleVirtual[0].value);
promoTitleParagraph.appendChild(promoTitle);
promoTitleVirtual[0].style.display = "none";
// Now the description
var promoDescriptionVirtual = document.querySelectorAll("[id*='cbParamVirtual2']");
var promoDescriptionParagraph = document.createElement("span");
promoDescriptionParagraph.classList.add("w-screen")
var promoDescription = document.createTextNode(promoDescriptionVirtual[0].value);
promoDescriptionParagraph.appendChild(promoDescription);
promoDescriptionVirtual[0].style.display = "none";
// The Image
var images = document.getElementsByTagName("img");
for (i = 0; i < images.length; i++) {
if (images[i].src.includes(dataPageId)) {
theImage = images[i];
}
}
var promotionImage = document.getElementById("promotionImage");
// reposition the radio so it looks better
var promoAnswers = document.querySelectorAll(
"[class*='cbFormBlock24']"
);
promotionImage.appendChild(promoTitleParagraph);
promotionImage.appendChild(theImage);
promotionImage.appendChild(promoDescriptionParagraph);
theImage.parentNode.lastChild.style.width = theImage.width + "px";
promotionImage.appendChild(promoAnswers[0]);
});```
The image is always shown, the Title and the Description only the first time
Found the problem... can be interesting for those using the Caspio environment!
Apparently Caspio doesn't load all the data immediately so even though I wait until everything is loaded :
window.addEventListener("load", function (e)
it is not...
Hacky (but this code is it anyway, can't wait until we have this re-written) I added a :
setTimeout(function() {
...
}, 300)
to my code so it waits until Caspio is done with its business. (200 was ok, just put 300 to be on the safe side)
I get "can't convert undefined to object" error while trying to run this piece of code. I'm not a programmer and can barely code therefore my question might be quite stupid/unanswerable for what I'm deeply sorry.
Code:
if (path == F[0])
{
//go N
if (pointAy > 0)
{
if (!(PS.BeadData(pointAx, pointAy - 1) === "blocked"))
{
// Set bead to Previous State
PS.BeadColor(pointAx, pointAy, previous_bead_NPC[NPCid][2]);
PS.BeadData(pointAx, pointAy, 0);
PS.BeadGlyph(pointAx, pointAy, " ");
// Increment
pointAy -= 1;
// Place NPC
MakeNPC(pointAx, pointAy, NPC[NPCid][2], NPC[NPCid][3], NPC[NPCid][4], NPC[NPCid][5], 1);
}
}
}
Can't really tell if this is enough to find an answer for you - I can post more of the code if it would help.
Maybe there is some generic answer to such an error a normal programmer would know, but such a noob like me will be oblivious to?
UPDATE
Ok, through step-by-step execution I found out that the error pops out in a different function even though disabling above piece of code makes the error not pop up. This is the function that makes the error pop up:
PS.Tick = function ()
{
"use strict";
for (var NPCid = 0; NPCid < 10; NPCid++)
{
NPCAI(NPCid);
};
};
This function is called every second and it calls AI logic function to move 10 NPC on a grid by supplying the NPCid to the AI function. Script fails here, but not always - usually one or two of the NPCs makes a step and only then the function fails.
If you are using Chrome or Firebug you can step through the JavaScript code. On Chrome, open up the tools icon (wrench in the upper right corner), then enable the developer tools by selecting "Tools" from the drop down menu and the "Developer Tools". At the bottom you should see a button in the lower part of your screen for scripts. Click on that and navigate to your page. When you see your JavaScript file open it and put a breakpoint at the "if" statement. Reload your page and then look at the values of PS and NPC when the debugger stops your code.
I have some JScript code (converted from some old VBScript) that starts like this:
var Word = new ActiveXObject("Word.Basic");
Word.FileNew(); // opens new Word document
Word.Insert(IncorrectText);
Word.ToolsSpelling(); // opens spell check behind IE
The idea is to utilize the MS Word spell check for browser use, and it works well in XP, but the spell check box opens in the background in Windows 7 / IE 8 (this question tells me that the problem started in Vista and is probably an OS issue, not a browser or Office issue).
So my question is, how can I bring this window to the foreground? One important note is that the last line, Word.ToolsSpelling();, locks up my script, so anything I do will need to be before that.
I've tried
var wshShell = new ActiveXObject("WScript.Shell");
wshShell.AppActivate("Document1 - Microsoft Word"); // or some other text
before the ToolsSpelling call, but this does not do anything (maybe because the Word document is not actually revealed at this point?). Of course, this will only work if no "Document1" is already opened, so this is a questionable thought to begin with.
Per this answer, I tried using window.blur(); in order to blur IE, but this will only work if the IE window is the only one opened. Maybe there's some way I can loop through all opened windows and apply this?
SetForegroundWindow looked promising, but I don't know how to use it in JSript.
Any ideas?
Note: Browser permissions will be completely open for this site.
Update: Turns out if you use Word.Application, the spell check comes up in front as it should. Only the Word.Basic method has this problem (I don't expect to know why this side of eternity):
var wordApp = new ActiveXObject("Word.Application");
wordApp.Documents.Add();
wordDoc = wordApp.ActiveDocument;
... // safety checks before insertion
wordSelection.TypeText(IncorrectText);
wordDoc.CheckSpelling();
wordApp.Visible = false; // CheckSpelling makes the document visible
You might be able to jigger the window state. When the window is maximized after having been minimized, Windows will stack that in front (zIndex to top).
Something like:
var WIN_MAX = 2;
var WIN_MIN = 1;
var Word = new ActiveXObject("Word.Application");
Word.Visible = true;
// minimize the app
Word.WindowState = WIN_MIN ;
// in 500ms, maximize
setTimeout(function () {
Word.WindowState = WIN_MAX;
}, 500);
The setTimeout call seeks to work around a timing issue; Windows will sometimes "get confused" when a programmatic minimize/maximize happens in immediate succession. You might have to extend that delay a little, test it repeatedly and see what kind of results you get.
I have a fairly large HTML/JS/CSS application that works great when running as a web application with Safari on the iPhone.
When running this same application in an UIWebView within a native iPhone application calls within jQuery to create HTML fragments fail silently (ie: $("<div>HELLO WORLD</div>"); will not create the element.
I've tracked this down to the following equivalent code snippet in clean jQuery method:
var div = document.createElement(“div”);
div.innerHTML = “<div>HELLO WORLD</div>”;
When I look at div.outerHTML I see
<div>/<div>
div.innerHTML returns an empty string.
This does not appear to be a jQuery problem, nor does this happen 100% of the time. I haven’t been able to find a pattern, but in some cases it works 2-3 times in a row, sometimes if fails 5-6 times consecutively. This seems to only shows up when running the application inside a UIWebView in an Objective-C application. Also I’ve only seen this on an actual device running iOS 4.2, not the emulator.
Has anyone run into anything similar? Does anyone have a fix?
I had this problems too. It happens when the CPU of the phone is very busy (say 100%). Then the rendering engine sometimes forget about innerHTML settings.
The solution included in my unify project is to test if there is an element in childNodes, otherwise apply it again.
var target = document.createElement("div");
var text = "<div>Hello World</div>";
target.innerHTML = text;
var self = this;
self.__intervalHandle = window.setInterval(function() {
target.innerHTML = text:
if (target.firstChild) {
window.clearInterval(self.__intervalHandle);
self.__intervalHandle = null;
}
}, 100);
This forces the rendering engine to apply the innerHTML to the DOM and gives the rendering engine some time (100 ms in this example, a good value in our tests) to handle it.
Well, the solution [NOT a production quality solution] posted by Sebastian worked, but I couldn’t confirm if CPU load would cause this issue. I generated a lot of background load on the iOS host and couldn’t reproduce this issue.
Upon further investigation, the rendering issue seems to be a side effect of iOS shell canceling the navigation. Once the navigation is canceled by the iOS shell, the rendering engine probably take that as not needing to render more UI [basically doesn’t render anything for a small period].
One way to fix this would be to send commands to iOS shell as hash (#) parameters instead of a URL. This way iOS shell will get the commands and doesn’t need to cancel the navigation. This approach seems to work in the test code below. So, if window.location is set to location1, it alerts “At: 1” and element e2 has no value. And if the window.location is set to location2, it alerts “At: 0” and element e2 has the value.
#Kevin, could you confirm that you were canceling the navigation on iOS host when this behavior happened.
Test Code:
Javascript:
var location1 = "myApp://Test";
var location2 = "#myApp://Test";
$("#change").live("click", function (e) {
var element = document.getElementById("e1");
window.location = location1; var i = 0;
element.innerHTML = "At: " + i;
window.__intervalHandle = window.setInterval(function () {
var html = element.innerHTML;
if (html) {
alert(html);
window.clearInterval(window.__intervalHandle);
window.__intervalHandle = null;
} else {
element.innerHTML = "At: " + ++i;
}
}, 1);
document.getElementById("e2").innerHTML = "Test";
});
iOS pseudo code:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL* u = [ request URL];
if( [[u scheme] compare:#"myapp" ] == NSOrderedSame) {
{
return NO; // don’t navigate
}
return YES; // navigate
}
You should take a look at http://blog.techno-barje.fr/post/2010/10/06/UIWebView-secrets-part3-How-to-properly-call-ObjectiveC-from-Javascript.
It turns out that cancelling navigation as part of the -webView:shouldStartLoadWithRequest: delegate method may cause issues with innerHTML. I updated our JS code to use the method recommended in that article and I haven't seen the innerHTML issue crop up in a while.