Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2802 lines
95 KiB

  1. <HTML XMLNS:IE>
  2. <HEAD>
  3. <?import namespace="ie" implementation="#default">
  4. <META HTTP-EQUIV="MSThemeCompatible" CONTENT="Yes">
  5. <TITLE>Print Preview</TITLE>
  6. #include "preview.h"
  7. <STYLE>
  8. .divPage
  9. {
  10. position: absolute;
  11. top: -20000px;
  12. border-left: 1 solid black;
  13. border-top: 1 solid black;
  14. border-right: 4 solid black;
  15. border-bottom: 4 solid black;
  16. }
  17. .page
  18. {
  19. background: white; // pages are rendered over a white background
  20. width: 8.5in;
  21. height: 11in;
  22. margin: 0px;
  23. overflow: hidden;
  24. }
  25. .mRect
  26. {
  27. position: absolute;
  28. margin: 1in;
  29. width: 6.5in;
  30. height: 9in;
  31. border: none;
  32. overflow : hidden;
  33. }
  34. .divHead
  35. {
  36. position: absolute;
  37. overflow: hidden;
  38. top: 0in;
  39. left: 0in;
  40. width: 8.5in;
  41. }
  42. .divFoot
  43. {
  44. position: absolute;
  45. overflow: hidden;
  46. bottom: 0in;
  47. left: 0in;
  48. width: 8.5in;
  49. }
  50. BODY { overflow: hidden; padding: 0; margin: 0; background: threedface; }
  51. TABLE { margin: 0px; padding: 0px; background: threedface; }
  52. .THeader { border: none; background: white; color: black; } // white to match .page
  53. .TFooter { border: none; background: white; color: black; } // white to match .page
  54. TD { padding: 0; margin: 0; border: none; }
  55. TD.UIPane { width: 20px; border: none; font-family: 'ms sans serif'; font-size: 8pt; }
  56. TD.UISeparator { width: 1px; border-left: 2px threedhighlight ridge; }
  57. BUTTON { border: 1px solid threedface; background: threedface; font-family: 'ms sans serif'; font-size: 8pt; color: buttontext;}
  58. </STYLE>
  59. <SCRIPT DEFER>
  60. #define NUM_ABSTRACT_ZOOMS 3
  61. #define ZOOM_PAGE_WIDTH -1
  62. #define ZOOM_WHOLE_PAGE -2
  63. #define ZOOM_TWO_PAGES -3
  64. #define FRAMESET_LAID_OUT 0
  65. #define FRAMESET_SELECTED 1
  66. #define FRAMESET_SEPARATE 2
  67. #define STR_ZOOM_PAGE_WIDTH "-1"
  68. #define STR_ZOOM_WHOLE_PAGE "-2"
  69. #define STR_ZOOM_TWO_PAGES "-3"
  70. #define STR_FRAMESET_LAID_OUT "0"
  71. #define STR_FRAMESET_SELECTED "1"
  72. #define STR_FRAMESET_SEPARATE "2"
  73. #define HEADFOOTHEIGHT 27
  74. var g_aDocTree = new Object(); // Array of CPrintDoc's... using IDispatch expandos
  75. var g_nDispPage = -1; // 0...n Which of the pages is currently being previewed?
  76. var g_nZoomFactor = 0; // What level of zoom is currently applying to the page?
  77. var g_cLeftToPrint = 0; // How many documents are left to print? (Used in printing).
  78. var g_fRTL;
  79. var g_fPreview;
  80. // HACKHACK (greglett) (IE6#17478)
  81. // When printing WebOC apps from a nonbrowse thread (hyperlink "Print Target", PrintHTML API, File->Print + AllLinkedDocuments)
  82. // we instantiate the WebOC on the background thread and call in IPrint::Print (via CTemplatePrinter::printNonNative).
  83. // When that (asynchronously) returns, we close the printing thread... and the WebOC that is trying to print.
  84. // This produces a vareity of interesting effects, all bad, and some dire.
  85. // Note that we don't do this for Print Preview, Print All Linked Documents, because it would look very bad to the user.
  86. var g_fDelayClose = false; // Delay window.close()
  87. // Global value caches - mainly used to make sure we don't need to do any extra work:
  88. // Require FULL REPAGINATION:
  89. var g_nMarginTop = 0;
  90. var g_nMarginBottom = 0;
  91. var g_nMarginLeft = 0;
  92. var g_nMarginRight = 0;
  93. var g_nPageWidth = 0;
  94. var g_nPageHeight = 0;
  95. // Require only HEADER/FOOTER REAPPLICATION
  96. var g_nUnprintTop = 0;
  97. var g_nUnprintBottom = 0;
  98. var g_strHeader = "";
  99. var g_strFooter = "";
  100. var g_fTableOfLinks = false;
  101. // keep track of page layout space
  102. var g_cPagesDisplayed = 0;
  103. var g_cxDisplaySlots = 1;
  104. var g_cyDisplaySlots = 1;
  105. // keep track of whether the mouse is over any buttons
  106. var g_imgUnderMouse = null;
  107. // keep track of frameset layout-related stuff
  108. var g_nFramesetLayout = FRAMESET_LAID_OUT; // Which of the frameset layouts is currently active?
  109. var g_strActiveFrame = null; // Which frame "C_x_x," or null, is the active frame?
  110. var g_nTotalPages = 0; // How many total pages will be printed if the user
  111. var g_nDocsToCalc = 0;
  112. var g_nFramesLeft = 0; // # of frames currently being processed
  113. // selects FRAMESET_SEPARATE?
  114. #ifdef DEBUG
  115. g_fReallyClose = true; // Close template when Close() is called?
  116. #endif
  117. //----------------------------------------------------------------------
  118. // Functions GetRuleFromSelector()
  119. //
  120. // Synopsis: Gets the first rule in the first stylesheet on the document
  121. // that applies to the given selector.
  122. // This will do the job for us so long as we have only one
  123. // stylesheet and only one rule per selector.
  124. //
  125. // Returns: the rule or null if no match was found.
  126. //----------------------------------------------------------------------
  127. function GetRuleFromSelector(strSelector)
  128. {
  129. var i;
  130. var oRule;
  131. var oSS = document.styleSheets[0]; // Assume one style sheet
  132. // Linear search.
  133. for (i=0;;i++)
  134. {
  135. oRule = oSS.rules[i];
  136. if (oRule == null)
  137. break;
  138. if (oRule.selectorText == strSelector)
  139. break;
  140. }
  141. // Either null (no match found) or a rule.
  142. return oRule;
  143. }
  144. function UnprintableURL(strLink)
  145. {
  146. var fUnprintable = false;
  147. var cIndex;
  148. // Sniff the URL scheme prefix to make sure we can print it.
  149. cIndex = strLink.indexOf(":");
  150. switch (cIndex)
  151. {
  152. case 4:
  153. if (strLink.substr(0, cIndex) == "news")
  154. fUnprintable = true;
  155. break;
  156. case 5:
  157. if (strLink.substr(0, cIndex) == "snews")
  158. fUnprintable = true;
  159. break;
  160. case 6:
  161. if ( strLink.substr(0, cIndex) == "telnet"
  162. || strLink.substr(0, cIndex) == "mailto")
  163. fUnprintable = true;
  164. break;
  165. case 8:
  166. if (strLink.substr(0,cIndex) == "vbscript")
  167. fUnprintable = true;
  168. break;
  169. case 10:
  170. if (strLink.substr(0,cIndex) == "javascript")
  171. fUnprintable = true;
  172. break;
  173. }
  174. // (greglett) If we ever choose to check MIME type from script (unlikely),
  175. // this is the place to do it.
  176. return fUnprintable;
  177. }
  178. #ifdef DEBUG
  179. function StatusToString(nStatus)
  180. {
  181. var strStatus;
  182. switch (nStatus)
  183. {
  184. case 0:
  185. strStatus="LOADING_OEHEADER";
  186. break;
  187. case 1:
  188. strStatus="LOADING_CONTENT";
  189. break;
  190. case 2:
  191. strStatus="LOADING_TABLEOFLINKS";
  192. break;
  193. case 3:
  194. strStatus="PAGING_COMPLETE";
  195. break;
  196. case 4:
  197. strStatus="READY_TO_PRINT";
  198. break;
  199. default:
  200. strStatus="??? (" + nStatus + ")";
  201. break;
  202. }
  203. return strStatus;
  204. }
  205. function Log(strEntry)
  206. {
  207. var oDate = new Date();
  208. LogContainer.insertAdjacentHTML("beforeEnd", "[" + oDate.getTime() + "] " + strEntry + "<BR>");
  209. }
  210. #endif
  211. function OnKeyPress()
  212. {
  213. if (event.keyCode == 27) // esc
  214. {
  215. Close();
  216. }
  217. #ifdef DEBUG
  218. else if (event.keyCode == 126) // '~'
  219. {
  220. LogContainer.style.display = (LogContainer.currentStyle.display == "none") ? "block" : "none";
  221. }
  222. else if (event.keyCode == 33) // '!'
  223. {
  224. var strDocNew = prompt("(DEBUG only!) Command to execute?", "");
  225. eval(strDocNew);
  226. }
  227. else if (event.keyCode == 64) // '@'
  228. {
  229. g_fReallyClose = !g_fReallyClose;
  230. butClose.style.color = (g_fReallyClose) ? "" : "red";
  231. }
  232. #endif
  233. }
  234. function OnKeyDown()
  235. {
  236. if (event.altKey)
  237. {
  238. switch (event.keyCode)
  239. {
  240. case 37: // left arrow
  241. ChangeDispPage(g_nDispPage-1);
  242. break;
  243. case 39: // right arrow
  244. ChangeDispPage(g_nDispPage+1);
  245. break;
  246. case 107: // number pad +
  247. case 187: // keyboard +
  248. HandleZoom(-1);
  249. break;
  250. case 109: // number pad -
  251. case 189: // keyboard -
  252. HandleZoom(1);
  253. break;
  254. case 35: // end
  255. HandleLastPage();
  256. break;
  257. case 36: //home
  258. HandleFirstPage();
  259. break;
  260. }
  261. }
  262. }
  263. function ShowHelp()
  264. {
  265. window.showHelp("iexplore.chm::/print_preview.htm");
  266. }
  267. function AttachDialogEvents()
  268. {
  269. // Attach events. This is done here to:
  270. // 1. Prevent UI before we're able to handle it
  271. // 2. Load the dialog faster.
  272. // Attach button events
  273. butPrint.onclick = HandlePrintClick;
  274. butPageSetup.onclick = HandlePageSetup;
  275. butFirstPage.onclick = HandleFirstPage;
  276. butBackPage.onclick = HandleBackPage;
  277. butNextPage.onclick = HandleForwardPage;
  278. butLastPage.onclick = HandleLastPage;
  279. butZoomIn.onclick = HandleZoomInButton;
  280. butZoomOut.onclick = HandleZoomOutButton;
  281. butClose.onclick = Close;
  282. butHelp.onclick = ShowHelp;
  283. document.onhelp = ShowHelp;
  284. butPrint.onmousedown = buttonDown;
  285. butPageSetup.onmousedown = buttonDown;
  286. butFirstPage.onmousedown = buttonDown;
  287. butBackPage.onmousedown = buttonDown;
  288. butNextPage.onmousedown = buttonDown;
  289. butLastPage.onmousedown = buttonDown;
  290. butZoomIn.onmousedown = buttonDown;
  291. butZoomOut.onmousedown = buttonDown;
  292. butClose.onmousedown = buttonDown;
  293. butHelp.onmousedown = buttonDown;
  294. // Attach image UI events
  295. printCtl.onmouseover = buttonOver;
  296. printCtl.onmouseout = buttonOut;
  297. begin.onmouseover = buttonOver;
  298. begin.onmouseout = buttonOut;
  299. prev.onmouseover = buttonOver;
  300. prev.onmouseout = buttonOut;
  301. next.onmouseover = buttonOver;
  302. next.onmouseout = buttonOut;
  303. end.onmouseover = buttonOver;
  304. end.onmouseout = buttonOut;
  305. zoomIn.onmouseover = buttonOver;
  306. zoomIn.onmouseout = buttonOut;
  307. zoomOut.onmouseover = buttonOver;
  308. zoomOut.onmouseout = buttonOut;
  309. butPrint.onmouseover = new Function("buttonRaise(this);");
  310. butPrint.onmouseout = new Function("buttonLower(this);");
  311. butClose.onmouseover = new Function("buttonRaise(this);");
  312. butClose.onmouseout = new Function("buttonLower(this);");
  313. butHelp.onmouseover = new Function("buttonRaise(this);");
  314. butHelp.onmouseout = new Function("buttonLower(this);");
  315. // Attach input events
  316. inputPageNum.onkeypress = HandleInputKeyPress;
  317. inputPageNum.onchange = HandlePageSelect;
  318. selectZoom.onchange = HandleZoomSelect;
  319. selectFrameset.onchange = HandleFramesetSelect;
  320. // Attach document events
  321. window.onresize = OnResizeBody;
  322. window.onerror = HandleError;
  323. // Focus maintenance: anytime we return from another dialog (page setup, help, etc.),
  324. // push the focus back onto the document body (for scrolling and accessibility).
  325. window.onfocus = new Function("MasterContainer.focus()");
  326. document.body.onkeypress = OnKeyPress;
  327. document.body.onkeydown = OnKeyDown;
  328. }
  329. //----------------------------------------------------------------------
  330. // Body event handlers.
  331. //----------------------------------------------------------------------
  332. function OnLoadBody()
  333. {
  334. g_fRTL = (document.body.currentStyle.direction.toLowerCase() == "rtl");
  335. g_fPreview = dialogArguments.__IE_PrintType == "Preview";
  336. // For "printTarget" on an unprintable link URL on the body, we can have a bad URL.
  337. // Sniff it for printability, and bail if not so good. (greglett) (103361)
  338. if (UnprintableURL(dialogArguments.__IE_ContentDocumentUrl))
  339. {
  340. // JurgenE , variables for localization must be in the form L_someIDtext_Text_
  341. var L_Invalid_Text = "Unable to print URL. Please navigate directly to this page and select Print.";
  342. alert(L_Invalid_Text);
  343. window.close();
  344. }
  345. // Set up "base" values for each of the arrow images - the image source will be different for LTR vs. RTL sy1stems.
  346. // This assumes all images will be initialized to *_inactive.gif
  347. // We could avoid doing all this string mangling by adding an inline "base" property on the IMG and localizing it.
  348. var str;
  349. str = begin.src;
  350. begin.base = str.slice(str.lastIndexOf("/")+1,str.indexOf("_"));
  351. str = end.src;
  352. end.base = str.slice(str.lastIndexOf("/")+1,str.indexOf("_"));
  353. str = next.src;
  354. next.base = str.slice(str.lastIndexOf("/")+1,str.indexOf("_"));
  355. str = prev.src;
  356. prev.base = str.slice(str.lastIndexOf("/")+1,str.indexOf("_"));
  357. ChangeZoom(75);
  358. // Do this H/F switch before EnsureDocuments
  359. if (dialogArguments.__IE_HeaderString)
  360. Printer.header = dialogArguments.__IE_HeaderString
  361. if (dialogArguments.__IE_FooterString)
  362. Printer.footer = dialogArguments.__IE_FooterString
  363. EnsureDocuments(); // Get defaults (no documents means little work)
  364. // Make the cursor look like an hourglass while we wait for the frames to build
  365. window.document.body.style.cursor="wait";
  366. CreateDocument("document", "C", true);
  367. ChangeDispPage(1);
  368. // Set up the counter of remaning frames to load, and begin the iterative process
  369. g_nFramesLeft = 1;
  370. // Build those frames
  371. // (greglett) We may want to revise how and when we do this for the printing only,
  372. // i.e. non-preview situations. This may have a significant perf hit on how long
  373. // it takes the print to happen, and most of the time, we don't really need to
  374. // generate all those frames for a printout. We only do it this way so that we're
  375. // prepared if a user decides to try the FRAMESET_SEPARATE option in preview.
  376. OnBuildAllFrames("C");
  377. if (g_fPreview)
  378. {
  379. AttachDialogEvents();
  380. // make sure the display region is sized properly
  381. OverflowContainer.style.top = idDivToolbar.offsetHeight;
  382. OverflowContainer.style.height = document.body.clientHeight - idDivToolbar.offsetHeight;
  383. }
  384. else
  385. {
  386. PrintNow(dialogArguments.__IE_PrintType == "Prompt");
  387. }
  388. }
  389. function BuildAllFramesComplete()
  390. {
  391. AssertSz(g_nFramesLeft == 0, "BuildAllFramesComplete when not complete?");
  392. // Restore the cursor to its normal operation
  393. window.document.body.style.cursor="auto";
  394. // (t-svoida) Not sure this is the best or final place for this step to happen.
  395. // (greglett) It almost certainly isn't: we wait for all frames to be built to allow someone to
  396. // do the frameset selection thing.
  397. UpdateFramesetSelect();
  398. }
  399. function CalcDocsComplete()
  400. {
  401. AssertSz(g_nDocsToCalc == 0, "CalcDocsComplete when not complete?");
  402. // If we're currently laid out as FRAMESET_SEPARATE, we need to recompute our frame/page table
  403. if (g_nFramesetLayout == FRAMESET_SEPARATE)
  404. {
  405. ChangeFramesetLayout(g_nFramesetLayout, true) // FORCE update
  406. }
  407. }
  408. function OnResizeBody()
  409. {
  410. // make sure the display region is sized properly
  411. OverflowContainer.style.height = Math.max(0, document.body.clientHeight - idDivToolbar.offsetHeight);
  412. // make sure zoom gets updated if we're in an abstract zoom mode
  413. HandleDynamicZoom();
  414. // make sure a relayout happens, because the layout space changed
  415. PositionPages(g_nDispPage);
  416. }
  417. //+-------------------------------------------------------------------
  418. //
  419. // Synopsis: Turns off error messages in dialogs
  420. //
  421. // Arguments: none
  422. //
  423. // returns: true (tells browser not to handle message)
  424. //
  425. //--------------------------------------------------------------------
  426. function HandleError(message, url, line)
  427. {
  428. #ifdef DEBUG
  429. var str = "";
  430. if (url == document.URL)
  431. str += "Template ";
  432. // Debug only, no need to localize
  433. str += "Error (" + url + ":" + line + "): " + message;
  434. alert(str);
  435. #else
  436. var L_Internal_ErrorMessage = "There was an internal error, and Internet Explorer is unable to print this document.";
  437. alert(L_Internal_ErrorMessage);
  438. window.close();
  439. #endif
  440. return true;
  441. }
  442. // TODO (greglett) (TASK 5182)
  443. // Q: So, why two RectComplete handlers, one called with a setTimeout from the other?
  444. // A: Because otherwise we spend *all* of our time processing RectCompletes, and never give Trident a chance
  445. // to do any redrawing, &c... In order to provide a somewhat interactive UI, we need this delay.
  446. // Work to fix this should accompany incremental pagination.
  447. function OnRectComplete( strDoc )
  448. {
  449. if (!g_aDocTree[strDoc])
  450. {
  451. // No need to localize the string - it is only displayed in debug mode.
  452. HandleError("Document " + strDoc + " does not exist.", document.URL, "OnRectComplete");
  453. return;
  454. }
  455. #ifdef DEBUG
  456. Log("OnRectComplete " + event.srcElement.id + " " + event.contentOverflow);
  457. #endif
  458. window.setTimeout("OnRectCompleteNext('" + strDoc + "', " + event.contentOverflow + ",'" + event.srcElement.id + "');", 25);
  459. }
  460. function OnRectCompleteNext( strDoc, fOverflow, strElement)
  461. {
  462. #ifdef DEBUG
  463. Log("OnRectCompleteNext " + strElement + " " + fOverflow);
  464. #endif
  465. g_aDocTree[strDoc].RectComplete(fOverflow, strElement);
  466. }
  467. //----------------------------------------------------------------------
  468. // utilities for managing widget state
  469. //----------------------------------------------------------------------
  470. function enableButton(btn, img)
  471. {
  472. btn.disabled = false;
  473. if (g_imgUnderMouse == img)
  474. {
  475. img.src = img.base + "_hilite.gif";
  476. buttonRaise(btn);
  477. }
  478. else
  479. {
  480. img.src = img.base + ".gif";
  481. buttonLower(btn);
  482. }
  483. }
  484. function disableButton(btn, img)
  485. {
  486. btn.disabled = true;
  487. buttonLower(btn);
  488. // accept null because some buttons share
  489. // a common inactive image and this
  490. // generic naming scheme is broken
  491. if (img != null)
  492. {
  493. img.src = img.base + "_inactive.gif";
  494. }
  495. }
  496. function updateNavButtons()
  497. {
  498. //
  499. // disable any nav buttons that need to be
  500. //
  501. if (g_nDispPage == 1)
  502. {
  503. disableButton(butFirstPage, begin);
  504. disableButton(butBackPage, prev);
  505. }
  506. else
  507. {
  508. enableButton(butFirstPage, begin);
  509. enableButton(butBackPage, prev);
  510. }
  511. if (TotalDisplayPages() - g_nDispPage < g_cxDisplaySlots * g_cyDisplaySlots)
  512. {
  513. disableButton(butNextPage, next);
  514. disableButton(butLastPage, end);
  515. }
  516. else
  517. {
  518. enableButton(butNextPage, next);
  519. enableButton(butLastPage, end);
  520. }
  521. }
  522. function updateZoomButtons()
  523. {
  524. var fZoomOutDisabled = false;
  525. var fZoomInDisabled = false;
  526. //
  527. // disable any zoom buttons necessary
  528. //
  529. var oOptions = selectZoom.options;
  530. if (g_nZoomFactor >= parseInt(oOptions[0].value))
  531. {
  532. // we're on the largest zoom or larger, so disable zoom in
  533. disableButton(butZoomIn, null);
  534. zoomIn.src = "zoom_inactive.gif";
  535. fZoomInDisabled = true;
  536. }
  537. else if (g_nZoomFactor <= parseInt(oOptions[oOptions.length-1-NUM_ABSTRACT_ZOOMS].value))
  538. {
  539. // we're on the smallest zoom or smaller, so disable zoon out
  540. disableButton(butZoomOut, null);
  541. zoomOut.src = "zoom_inactive.gif";
  542. fZoomOutDisabled = true;
  543. }
  544. //
  545. // and enable any zoom buttons that are left
  546. //
  547. if (!fZoomOutDisabled)
  548. {
  549. enableButton(butZoomOut, zoomOut);
  550. }
  551. if (!fZoomInDisabled)
  552. {
  553. enableButton(butZoomIn, zoomIn);
  554. }
  555. }
  556. //----------------------------------------------------------------------
  557. // Function Synopsis
  558. // UpdateFramesetSelect()
  559. // Preps frameset layout select for user interaction, by
  560. // pruning off the SELECTED option if there's no selection
  561. // and hiding the control altogether if it's not a frameset
  562. // page.
  563. //----------------------------------------------------------------------
  564. function UpdateFramesetSelect()
  565. {
  566. // Check main document's frameset status first
  567. if ( g_aDocTree["C"]._fFrameset )
  568. {
  569. // Pare the "Only the selected frame" option if there's no selected frame
  570. // (and the list is still at its original length)
  571. if (!g_strActiveFrame)
  572. {
  573. selectFrameset.options.remove(1);
  574. }
  575. // Show both the control and the preceding separator
  576. separatorFrameset.style.display = "inline";
  577. cellFrameset.style.display = "inline";
  578. }
  579. #ifdef DEBUG
  580. else
  581. {
  582. // Hide both the control and the preceding separator
  583. // separatorFrameset.style.display = "none";
  584. // cellFrameset.style.display = "none";
  585. // (greglett) They should already be hidden. Let's make this an assert.
  586. AssertSz( separatorFrameset.currentStyle.display == "none"
  587. && cellFrameset.currentStyle.display == "none", "UI Visible when it shouldn't be?");
  588. }
  589. #endif
  590. }
  591. //----------------------------------------------------------------------
  592. // Function Synopses
  593. // getPageWidth, getPageHeight
  594. // Returns the global size of each page - assumes constant sized pages.
  595. // Return value is in screen CSS pixels.
  596. //----------------------------------------------------------------------
  597. function getPageWidth()
  598. {
  599. return g_aDocTree["C"].Page(1).offsetWidth;
  600. }
  601. function getPageHeight()
  602. {
  603. return g_aDocTree["C"].Page(1).offsetHeight;
  604. }
  605. //----------------------------------------------------------------------
  606. // UndisplayPages()
  607. // Undisplays all visible pages
  608. //----------------------------------------------------------------------
  609. function UndisplayPages()
  610. {
  611. while (g_cPagesDisplayed > 0)
  612. {
  613. var oPage = DisplayPage(g_nDispPage + g_cPagesDisplayed - 1);
  614. if (oPage != null)
  615. {
  616. oPage.style.top = "-20000px";
  617. if (g_fRTL)
  618. oPage.style.right = "10px";
  619. else
  620. oPage.style.left = "10px";
  621. }
  622. g_cPagesDisplayed--;
  623. }
  624. }
  625. //----------------------------------------------------------------------
  626. // PositionPages(nDispPage)
  627. // Sets the x and y positioning for the pages currently being
  628. // displayed. If the given # is outside valid bounds, the
  629. // nearest valid boundary is selected instead.
  630. // PERF (greglett) We may want to make redisplay smarter - right now, all
  631. // pages are redisplayed every time the window is resized. We really should
  632. // have the funtion check if pages need to be redisplayed, with a force flag option.
  633. //----------------------------------------------------------------------
  634. function PositionPages(nDispPage)
  635. {
  636. // Cache the current display doc
  637. var strDispDoc = DisplayDocument(nDispPage);
  638. if ( g_aDocTree != null
  639. && g_aDocTree[strDispDoc] != null
  640. && g_aDocTree[strDispDoc].Pages() > 0)
  641. {
  642. // first clear the old pages
  643. UndisplayPages();
  644. //
  645. // now draw the new pages with the new settings
  646. //
  647. // figure out how many pages we can show this time
  648. var xPageWidth = getPageWidth();
  649. var yPageHeight = getPageHeight();
  650. var nMaxPage = TotalDisplayPages();
  651. g_cxDisplaySlots = Math.max(1, Math.floor((OverflowContainer.offsetWidth*100)/(g_nZoomFactor*(xPageWidth+10))));
  652. g_cyDisplaySlots = Math.max(1, Math.floor((OverflowContainer.offsetHeight*100)/(g_nZoomFactor*(yPageHeight+10))));
  653. // Trim nDispPage to be inside a valid page range.
  654. var nMaxPageRequest = Math.max(nMaxPage - g_cxDisplaySlots * g_cyDisplaySlots + 1, 1);
  655. if ( nDispPage < 1 )
  656. nDispPage = 1;
  657. else if (nDispPage > nMaxPageRequest)
  658. nDispPage = nMaxPageRequest;
  659. // now start using the new (bounded) page index
  660. g_nDispPage = nDispPage;
  661. // Update the page display to show the right numbers
  662. document.all.spanPageTotal.innerText = nMaxPage;
  663. document.all.inputPageNum.value = g_nDispPage;
  664. // fix the begin, prev, next, end arrows
  665. updateNavButtons();
  666. //
  667. // set up pages until we run out of pages
  668. // or run out of rows of slots to fill
  669. //
  670. var xDisplaySlot = 1;
  671. var yDisplaySlot = 1;
  672. var iPage = g_nDispPage;
  673. g_cPagesDisplayed = 0;
  674. // PERF We really don't need to do a DisplayPage each time
  675. // We could loop through the DisplayDocuments, and loop through
  676. // each of their pages to many multiple lookups inherent in calling
  677. // DisplayPage each iteration of the loop (greglett)
  678. while (iPage <= nMaxPage && yDisplaySlot <= g_cyDisplaySlots)
  679. {
  680. var xPos = xDisplaySlot*10 + (xDisplaySlot-1)*xPageWidth;
  681. var yPos = yDisplaySlot*10 + (yDisplaySlot-1)*yPageHeight;
  682. var oPage = DisplayPage(iPage);
  683. if (g_fRTL)
  684. oPage.style.right = xPos;
  685. else
  686. oPage.style.left = xPos;
  687. oPage.style.top = yPos;
  688. iPage++;
  689. if (++xDisplaySlot > g_cxDisplaySlots)
  690. {
  691. xDisplaySlot = 1;
  692. yDisplaySlot++;
  693. }
  694. g_cPagesDisplayed++;
  695. }
  696. }
  697. }
  698. function ChangeDispPage(nDispPageNew)
  699. {
  700. if (isNaN(nDispPageNew))
  701. {
  702. // make sure the UI shows a valid number
  703. inputPageNum.value = g_nDispPage;
  704. }
  705. else
  706. {
  707. // Range check
  708. if (nDispPageNew < 1)
  709. nDispPageNew = 1;
  710. else if (nDispPageNew > TotalDisplayPages())
  711. nDispPageNew = TotalDisplayPages();
  712. // make sure the top of the page is showing
  713. OverflowContainer.scrollTop = 0;
  714. PositionPages(nDispPageNew);
  715. }
  716. return g_nDispPage;
  717. }
  718. //----------------------------------------------------------------------
  719. // Function Synopsis
  720. // DisplayDocument()
  721. // As below. Only valid when not FRAMESET_SELECT.
  722. // DisplayDocument(nWhichPage)
  723. // Returns either the current display document (indicated by
  724. // g_nDispPage) in the format "C_x_x", or, when passed a page
  725. // number from 1...total pages (includes all frames in SEPARATE
  726. // frameset layout), returns the display document shown on that
  727. // page. Will return null if the page number passed is out
  728. // of range.
  729. //----------------------------------------------------------------------
  730. function DisplayDocument(nWhichPage)
  731. {
  732. switch (g_nFramesetLayout)
  733. {
  734. case FRAMESET_LAID_OUT:
  735. // In LAID_OUT case, display doc is always the master, "C"
  736. return "C";
  737. break;
  738. case FRAMESET_SELECTED:
  739. // In SELECTED casem display doc is always the active frame
  740. return g_strActiveFrame;
  741. break;
  742. case FRAMESET_SEPARATE:
  743. var i;
  744. if (!nWhichPage)
  745. return null;
  746. AssertSz(nWhichPage > 0 && nWhichPage <= g_nTotalPages, "DisplayDocument called with invalid page: " + nWhichPage);
  747. // Otherwise, count to find correct document
  748. for (i in g_aDocTree)
  749. {
  750. if ( nWhichPage >= g_aDocTree[i]._nStartingPage
  751. && nWhichPage < (g_aDocTree[i]._nStartingPage + g_aDocTree[i].Pages()))
  752. return i;
  753. }
  754. default:
  755. // Should never happen!
  756. // Don't localize this string, debug code only
  757. HandleError("Display document cannot be found!", document.URL, "DisplayDocument");
  758. }
  759. }
  760. //----------------------------------------------------------------------
  761. // Member TotalDisplayPages
  762. //
  763. // Synopsis: With multiple page arrays per CPrintDoc, these functions
  764. // are to provide the illusion of one array. Unlike Pages(),
  765. // this returns the number of pages in this CPrintDoc if the
  766. // frameset layout is LAID_OUT or SELECTED, or the total
  767. // number of pages in all individual frames if the frameset
  768. // layout is SEPARATE. To make this closer to user UI, this
  769. // virtual array is 1 based, not 0 based.
  770. //----------------------------------------------------------------------
  771. function TotalDisplayPages()
  772. {
  773. if (g_nFramesetLayout == FRAMESET_SEPARATE)
  774. return g_nTotalPages;
  775. AssertSz(DisplayDocument(), "TotalDisplayPages: No DisplayDocument!") // DEBUG only: don't localize.
  776. return g_aDocTree[DisplayDocument()].Pages();
  777. }
  778. //----------------------------------------------------------------------
  779. // DisplayPage(nWhichPage)
  780. // Returns the specified page of the displayed set
  781. //
  782. // The only situation this is different than the DisplayDocument
  783. // is for "all frames individually." Imagine two two page frames.
  784. // Then, the function would return:
  785. // nWhichPage Return
  786. // 1-2 Frame1.Page(nWhichPage)
  787. // 3-4 Frame2.Page(nWhichPage - 2)
  788. //----------------------------------------------------------------------
  789. function DisplayPage(nWhichPage)
  790. {
  791. AssertSz(nWhichPage >= 0, "Negative or null display page requested: " + nWhichPage);
  792. // Local page numbers are always the same as total page
  793. // numbers unless the layout is SEPARATE
  794. if (g_nFramesetLayout != FRAMESET_SEPARATE)
  795. return g_aDocTree[DisplayDocument(nWhichPage)].Page(nWhichPage);
  796. // Compute the page offset into the current document, and ask for that page.
  797. return g_aDocTree[DisplayDocument(nWhichPage)].Page(nWhichPage - g_aDocTree[DisplayDocument(nWhichPage)]._nStartingPage + 1);
  798. }
  799. //----------------------------------------------------------------------
  800. // Function ChangeZoom
  801. // Checks the bounds and changes the document zoom level to the new value.
  802. //----------------------------------------------------------------------
  803. function ChangeZoom(nNewVal)
  804. {
  805. if (nNewVal < 10)
  806. nNewVal = 10;
  807. else if (nNewVal > 1000)
  808. nNewVal = 1000;
  809. else if (isNaN(nNewVal))
  810. nNewVal = g_nZoomFactor;
  811. if (nNewVal != g_nZoomFactor)
  812. {
  813. MasterContainer.style.zoom = nNewVal + "%";
  814. g_nZoomFactor = nNewVal;
  815. updateZoomButtons();
  816. PositionPages(g_nDispPage);
  817. }
  818. return g_nZoomFactor;
  819. }
  820. //----------------------------------------------------------------------
  821. // Function BuildTableOfLinks
  822. //
  823. // Synopsis: These function takes a document, and uses its links collection
  824. // to create another document with a table of links.
  825. // Returns the document, or null if no links were encountered.
  826. //----------------------------------------------------------------------
  827. function BuildTableOfLinks( docSource )
  828. {
  829. var aLinks = docSource.links;
  830. var nLinks = aLinks.length;
  831. if (nLinks > 0)
  832. {
  833. var fDuplicate;
  834. var i;
  835. var j;
  836. var newHTM;
  837. var docLinkTable = document.createElement("BODY");
  838. var L_LINKSHEADER1_Text = "Shortcut Text";
  839. var L_LINKSHEADER2_Text = "Internet Address";
  840. newHTM = "<CENTER><TABLE BORDER=1>";
  841. newHTM += "<THEAD style=\"display:table-header-group\"><TR><TH>"
  842. + L_LINKSHEADER1_Text
  843. + "</TH><TH>" + L_LINKSHEADER2_Text + "</TH></TR></THEAD><TBODY>";
  844. // Old behvaior: Print each linked URL only once. Do include a self link.
  845. // Ack! Yes, this is a dreaded N-squared algorithm. This is what we used to do, though, so we're no worse.
  846. // If we deem it important enough, we can pare it down to NlogN via a more efficient sorting algorithm. (greglett)
  847. for (i = 0; i < nLinks; i++)
  848. {
  849. fDuplicate = false;
  850. for (j = 0; (!fDuplicate) && (j < i); j++)
  851. {
  852. if (aLinks[i].href == aLinks[j].href)
  853. fDuplicate = true;
  854. }
  855. if (!fDuplicate)
  856. newHTM += ("<TR><TD>" + aLinks[i].innerText + "</TD><TD>" + aLinks[i].href + "</TD></TR>");
  857. }
  858. newHTM += "</TBODY></TABLE></CENTER>";
  859. docLinkTable.innerHTML = newHTM;
  860. return docLinkTable.document;
  861. }
  862. return null;
  863. }
  864. //----------------------------------------------------------------------
  865. // Function CreateDocument
  866. //
  867. // Synopsis: Allocates and initializes a new CPrintDoc with the
  868. // given contentURL and documentID. Also passed: Should
  869. // we pay attention to any existing stream header.
  870. //----------------------------------------------------------------------
  871. function CreateDocument( docURL, strDocID, fUseStreamHeader )
  872. {
  873. if (g_aDocTree[strDocID])
  874. return;
  875. g_aDocTree[strDocID] = new CPrintDoc( strDocID, docURL );
  876. g_aDocTree[strDocID].InitDocument( fUseStreamHeader );
  877. }
  878. function ChangeFramesetLayout( nNewLayout, fForce )
  879. {
  880. // Don't do any work if none is needed
  881. if ( g_nFramesetLayout == nNewLayout
  882. && !fForce)
  883. return;
  884. // Hide the currently displayed page view
  885. UndisplayPages();
  886. // Grab the new frameset layout setting
  887. g_nFramesetLayout = nNewLayout;
  888. switch ( nNewLayout )
  889. {
  890. case FRAMESET_LAID_OUT:
  891. case FRAMESET_SELECTED:
  892. break;
  893. case FRAMESET_SEPARATE:
  894. // Recount all individual pages and assign starting page
  895. // numbers to each. If a page has no starting page number,
  896. // i.e. _nStartingPage = 0, then it's either a frameset page
  897. // or the selection bit, and we don't want to include it in
  898. // the SEPARATE-type frameset previews. We have to do this
  899. // computation each time, or else we can get errors after
  900. // repaginations.
  901. g_nTotalPages = 0;
  902. for (i in g_aDocTree)
  903. {
  904. if ( g_aDocTree[i]._fFrameset
  905. || i == "S")
  906. g_aDocTree[i]._nStartingPage = 0;
  907. else
  908. {
  909. g_aDocTree[i]._nStartingPage = g_nTotalPages + 1;
  910. g_nTotalPages += g_aDocTree[i].Pages();
  911. }
  912. }
  913. break;
  914. default:
  915. // Should never happen!
  916. //Don't localize this string, debug code only
  917. HandleError("Impossible frameset layout type: " + nNewLayout, document.URL, "ChangeFramesetLayout");
  918. }
  919. // Allow the logic in ChangeDispPage to select the correct page
  920. // and page number, and then display it.
  921. ChangeDispPage(1);
  922. }
  923. //----------------------------------------------------------------------
  924. // Function EnsureDocuments()
  925. //
  926. // Synopsis: This function picks up and applies style changes, resetting all
  927. // the documents states so they do enough work to reflow.
  928. //
  929. // Returns: nothing
  930. //----------------------------------------------------------------------
  931. function EnsureDocuments()
  932. {
  933. var i;
  934. var tmp;
  935. // Units received are 1/100"; convert to 1"
  936. // Changes in these require repagination:
  937. var top = Printer.marginTop / 100;
  938. var bottom = Printer.marginBottom / 100;
  939. var left = Printer.marginLeft / 100;
  940. var right = Printer.marginRight / 100;
  941. var pageWidth = Printer.pageWidth / 100;
  942. var pageHeight = Printer.pageHeight / 100;
  943. // Changes in these require repagination of the table of links:
  944. var linktable = Printer.tableOfLinks;
  945. // Changes in these require reapplication of headers/footers:
  946. var upTop = Printer.unprintableTop / 100;
  947. var upBottom = Printer.unprintableBottom / 100;
  948. var header = Printer.header;
  949. var footer = Printer.footer;
  950. // Handle case where (unprintable) + (header/footer size) > (specified margin)
  951. // Just autoincrease the margin...
  952. // TODO (greglett) For now, use a guesstimation for the H/F size, as it is always one
  953. // line of the same font. Frontload work to prevent reflow, and use a constant.
  954. // Fixing this is REQUIRED for HTML headers/footers.
  955. // TODO (greglett) (99287)
  956. // On top of that, we are sizing the page slightly wrong - our "page size"
  957. // should not include the 1px/4px borders on the page for UI. This could be amended by surrounding
  958. // the page in a DIV contiainer (the UI page), and printing/sizing the inner page, while positioning
  959. // the outer page. This has some difficulties due to interaction of absolutely positioning stuff.
  960. if (header)
  961. {
  962. tmp = upTop + (HEADFOOTHEIGHT / 100);
  963. if (tmp > top)
  964. top = tmp;
  965. }
  966. if (footer)
  967. {
  968. tmp = upBottom + (HEADFOOTHEIGHT / 100);
  969. if (tmp > bottom)
  970. bottom = tmp;
  971. }
  972. if (upTop != g_nUnprintTop)
  973. {
  974. g_nUnprintTop = upTop;
  975. // Set styles on Header
  976. oRule = GetRuleFromSelector(".divHead");
  977. if (oRule == null)
  978. {
  979. // Should never happen!
  980. //Don't localize this string, debug code only
  981. HandleError("'.divHead' rule does not exist!", document.URL, "CPrintDoc::EnsureDocuments");
  982. }
  983. oRule.style.top = upTop + "in";
  984. }
  985. if (upBottom != g_nUnprintBottom)
  986. {
  987. g_nUnprintBottom= upBottom;
  988. // Set styles on Footer
  989. oRule = GetRuleFromSelector(".divFoot");
  990. if (oRule == null)
  991. {
  992. // Should never happen!
  993. //Don't localize this string, debug code only
  994. HandleError("'.divFoot' rule does not exist!", document.URL, "CPrintDoc::EnsureDocuments");
  995. }
  996. oRule.style.bottom = upBottom + "in";
  997. }
  998. // Check if something has changed that will force work on the document.
  999. if ( top != g_nMarginTop
  1000. || bottom != g_nMarginBottom
  1001. || left != g_nMarginLeft
  1002. || right != g_nMarginRight
  1003. || pageWidth != g_nPageWidth
  1004. || pageHeight != g_nPageHeight
  1005. || header != g_strHeader
  1006. || footer != g_strFooter )
  1007. {
  1008. var conWidth = pageWidth - left - right;
  1009. var conHeight = pageHeight - top - bottom;
  1010. var oStyleSheet = document.styleSheets[0];
  1011. var oRule;
  1012. if (conWidth < 0)
  1013. conWidth = 0;
  1014. if (conHeight < 0)
  1015. conHeight = 0;
  1016. // Hide currently displayed pages - they're about to become invalid.
  1017. UndisplayPages();
  1018. // Clear page numbering for FRAMESET_SEPARATE layout
  1019. g_nTotalPages = 0;
  1020. g_nDocsToCalc = 0;
  1021. // All documents are about to be repaginated!
  1022. for (i in g_aDocTree)
  1023. {
  1024. g_nDocsToCalc++;
  1025. g_aDocTree[i].ResetDocument();
  1026. }
  1027. // Cache new values.
  1028. g_nMarginTop = top;
  1029. g_nMarginBottom = bottom;
  1030. g_nMarginLeft = left;
  1031. g_nMarginRight = right;
  1032. g_nPageWidth = pageWidth;
  1033. g_nPageHeight = pageHeight;
  1034. g_fTableofLinks = linktable;
  1035. g_strHeader = header;
  1036. g_strFooter = footer;
  1037. HeadFoot.textHead = g_strHeader;
  1038. HeadFoot.textFoot = g_strFooter;
  1039. // Set styles on pages.
  1040. oRule = GetRuleFromSelector(".page");
  1041. if (oRule == null)
  1042. {
  1043. // Should never happen!
  1044. //Don't localize this string, debug code only
  1045. HandleError("'.page' rule does not exist!", document.URL, "CPrintDoc::EnsureDocuments");
  1046. }
  1047. oRule.style.width = pageWidth + "in";
  1048. oRule.style.height = pageHeight + "in";
  1049. // Set styles on layout rects.
  1050. oRule = GetRuleFromSelector(".mRect");
  1051. if (oRule == null)
  1052. {
  1053. // Should never happen!
  1054. //Don't localize this string, debug code only
  1055. HandleError("'.mRect' rule does not exist!", document.URL, "CPrintDoc::EnsureDocuments");
  1056. }
  1057. oRule.style.marginLeft = left + "in";
  1058. oRule.style.marginRight = right + "in";
  1059. oRule.style.marginTop = top + "in";
  1060. oRule.style.marginBottom = bottom + "in";
  1061. oRule.style.width = conWidth + "in";
  1062. oRule.style.height = conHeight + "in";
  1063. // Set styles on Header
  1064. oRule = GetRuleFromSelector(".divHead");
  1065. if (oRule == null)
  1066. {
  1067. // Should never happen!
  1068. //Don't localize this string, debug code only
  1069. HandleError("'.divHead' rule does not exist!", document.URL, "CPrintDoc::EnsureDocuments");
  1070. }
  1071. oRule.style.left = left + "in";
  1072. oRule.style.width = conWidth + "in";
  1073. // Set styles on Header
  1074. oRule = GetRuleFromSelector(".divFoot");
  1075. if (oRule == null)
  1076. {
  1077. // Should never happen!
  1078. //Don't localize this string, debug code only
  1079. HandleError("'.divHead' rule does not exist!", document.URL, "CPrintDoc::EnsureDocuments");
  1080. }
  1081. oRule.style.left = left + "in";
  1082. oRule.style.width = conWidth + "in";
  1083. // HACKHACK (greglett) 94479
  1084. // The viewchain is not capable of recalcing if the layout rect properties are changed right now.
  1085. // So, we unhook the LR, change the properties (ABOVE) and then reload/reparse the entire document (HERE)
  1086. for (i in g_aDocTree)
  1087. {
  1088. // Reinit document - and pass whether or not we're using an OE header.
  1089. g_aDocTree[i].InitDocument((g_aDocTree[i]._anMerge[LOADING_CONTENT] == 1));
  1090. }
  1091. // Repagination screws up the delicate frame page table used to figure out how
  1092. // many pages are in which documents. Force update.
  1093. if (g_nFramesetLayout == FRAMESET_SEPARATE)
  1094. ChangeFramesetLayout(g_nFramesetLayout, true);
  1095. // Repaint the current page(s) that we hid above with UndisplayPages()
  1096. PositionPages(g_nDispPage);
  1097. }
  1098. else if (linktable != g_fTableOfLinks)
  1099. {
  1100. // Cache new values.
  1101. g_fTableOfLinks = linktable;
  1102. // All documents are about to be table of linked! (?)
  1103. for (i in g_aDocTree)
  1104. {
  1105. g_aDocTree[i].ResetTableOfLinks();
  1106. }
  1107. }
  1108. }
  1109. //----------------------------------------------------------------------
  1110. // Functions: Button utilities.
  1111. //
  1112. // Synopsis: These various & sundry functions are button UI utilities
  1113. // and provide basic toolbar UI
  1114. //----------------------------------------------------------------------
  1115. function buttonRaise( elem )
  1116. {
  1117. elem.style.borderStyle = "outset";
  1118. elem.style.borderColor = "threedhighlight";
  1119. }
  1120. function buttonLower( elem )
  1121. {
  1122. elem.style.borderStyle = "solid";
  1123. elem.style.borderColor = "threedface";
  1124. }
  1125. function buttonDepress(elem)
  1126. {
  1127. elem.style.borderStyle = "inset";
  1128. elem.style.borderColor = "threedshadow";
  1129. }
  1130. // PERF (greglett)
  1131. // We don't need to do a whole updateXXXButtons!
  1132. function buttonOver()
  1133. {
  1134. var imgSrc = event.srcElement;
  1135. g_imgUnderMouse = imgSrc;
  1136. if (imgSrc == begin ||
  1137. imgSrc == prev ||
  1138. imgSrc == next ||
  1139. imgSrc == end)
  1140. {
  1141. updateNavButtons();
  1142. }
  1143. else if (imgSrc == zoomIn ||
  1144. imgSrc == zoomOut)
  1145. {
  1146. updateZoomButtons();
  1147. }
  1148. else
  1149. {
  1150. imgSrc.src= "" + imgSrc.id + "_hilite.gif";
  1151. buttonRaise( imgSrc.parentNode );
  1152. }
  1153. }
  1154. // PERF (greglett)
  1155. // We don't need to do a whole updateXXXButtons!
  1156. function buttonOut()
  1157. {
  1158. var imgSrc = event.srcElement;
  1159. g_imgUnderMouse = null;
  1160. if (imgSrc == begin ||
  1161. imgSrc == prev ||
  1162. imgSrc == next ||
  1163. imgSrc == end)
  1164. {
  1165. updateNavButtons();
  1166. }
  1167. else if (imgSrc == zoomIn ||
  1168. imgSrc == zoomOut)
  1169. {
  1170. updateZoomButtons();
  1171. }
  1172. else
  1173. {
  1174. imgSrc.src= "" + imgSrc.id + ".gif";
  1175. buttonLower( imgSrc.parentNode );
  1176. }
  1177. }
  1178. function buttonDown()
  1179. {
  1180. buttonDepress(event.srcElement);
  1181. }
  1182. // --------------------------------------------------------
  1183. function HandlePageSelect()
  1184. {
  1185. event.srcElement.value = ChangeDispPage(parseInt(inputPageNum.value));
  1186. // Force focus back to the preview document so keyboard
  1187. // accelerators work as expected
  1188. MasterContainer.focus();
  1189. }
  1190. function HandlePageSetup()
  1191. {
  1192. if (Printer.showPageSetupDialog())
  1193. EnsureDocuments();
  1194. }
  1195. function HandleForwardPage()
  1196. {
  1197. ChangeDispPage(g_nDispPage + 1);
  1198. // Force focus back to the preview document so keyboard
  1199. // accelerators work as expected
  1200. MasterContainer.focus();
  1201. }
  1202. function HandleBackPage()
  1203. {
  1204. ChangeDispPage(g_nDispPage - 1);
  1205. // Force focus back to the preview document so keyboard
  1206. // accelerators work as expected
  1207. MasterContainer.focus();
  1208. }
  1209. function HandleFirstPage()
  1210. {
  1211. ChangeDispPage(1);
  1212. // Force focus back to the preview document so keyboard
  1213. // accelerators work as expected
  1214. MasterContainer.focus();
  1215. }
  1216. function HandleLastPage()
  1217. {
  1218. ChangeDispPage(TotalDisplayPages());
  1219. // Force focus back to the preview document so keyboard
  1220. // accelerators work as expected
  1221. MasterContainer.focus();
  1222. }
  1223. function NumericFromSpecialZoom(fnBounder)
  1224. {
  1225. var iMaxNumericZoom = selectZoom.options.length-1-NUM_ABSTRACT_ZOOMS; // specials zooms follow numeric zooms
  1226. var iBelow = -1;
  1227. var nBelow = 0;
  1228. var iAbove = iMaxNumericZoom + 1;
  1229. var i;
  1230. // establish iBelow and iAbove so that they are the selection indices just
  1231. // below and above the current value of g_nZoomFactor. if there's an
  1232. // exact match, then iBelow and iAbove have to both be the index whose
  1233. // value matches
  1234. // get iBelow
  1235. for (i = 0; i <= iMaxNumericZoom; i++)
  1236. {
  1237. var nThisIndex = parseInt(selectZoom.options[i].value);
  1238. if (nThisIndex >= g_nZoomFactor)
  1239. {
  1240. iBelow = i;
  1241. nBelow = nThisIndex;
  1242. }
  1243. else
  1244. {
  1245. break;
  1246. }
  1247. }
  1248. // get iAbove
  1249. if (nBelow > g_nZoomFactor)
  1250. {
  1251. iAbove = iBelow + 1;
  1252. }
  1253. else
  1254. {
  1255. iAbove = iBelow;
  1256. }
  1257. return fnBounder(iBelow, iAbove);
  1258. }
  1259. function HandleZoom(nZoomIndexDelta)
  1260. {
  1261. var iCurrZoom = selectZoom.selectedIndex;
  1262. var iMaxNumericZoom = selectZoom.options.length-1-NUM_ABSTRACT_ZOOMS; // specials zooms follow numeric zooms
  1263. if (iCurrZoom > iMaxNumericZoom)
  1264. {
  1265. var fnRemapBounder = null;
  1266. // we're on a special zoom setting and now need to
  1267. // remap back into numeric zoom mode
  1268. if (nZoomIndexDelta == 1)
  1269. {
  1270. // we're going to be moving down the list
  1271. // so the index returned by NFSZ needs
  1272. // to be the vertically highest index
  1273. // which is the min index
  1274. fnRemapBounder = Math.min;
  1275. }
  1276. else
  1277. {
  1278. // moving up the list, need vertically lowest index
  1279. fnRemapBounder = Math.max;
  1280. }
  1281. iCurrZoom = NumericFromSpecialZoom(fnRemapBounder);
  1282. }
  1283. // move up or down the selection list as indicated by nZoomIndexDelta
  1284. selectZoom.selectedIndex = Math.min(Math.max(0, iCurrZoom + nZoomIndexDelta), iMaxNumericZoom);
  1285. ChangeZoom(parseInt(selectZoom.options[selectZoom.selectedIndex].value));
  1286. }
  1287. function HandleDynamicZoom()
  1288. {
  1289. var nZoomType = parseInt(selectZoom.options[selectZoom.selectedIndex].value);
  1290. if (nZoomType < 0)
  1291. {
  1292. var nZoomFactor = 100;
  1293. var xPageWidth = getPageWidth();
  1294. switch (nZoomType)
  1295. {
  1296. // page width
  1297. case ZOOM_PAGE_WIDTH:
  1298. nZoomFactor = Math.floor(((OverflowContainer.offsetWidth - 20) * 100) / xPageWidth);
  1299. break;
  1300. // whole page
  1301. case ZOOM_WHOLE_PAGE:
  1302. var xZoom = Math.floor(((OverflowContainer.offsetWidth - 20) * 100) / xPageWidth);
  1303. var yZoom = Math.floor(((OverflowContainer.offsetHeight - 20) * 100) / getPageHeight());
  1304. nZoomFactor = Math.min(xZoom, yZoom);
  1305. break;
  1306. // two pages
  1307. case ZOOM_TWO_PAGES:
  1308. nZoomFactor = Math.floor(((OverflowContainer.offsetWidth - 30) * 100) / (2 * xPageWidth));
  1309. break;
  1310. // eh?
  1311. default:
  1312. nZoomFactor = 100;
  1313. break;
  1314. }
  1315. ChangeZoom(nZoomFactor);
  1316. }
  1317. }
  1318. function HandleZoomSelect()
  1319. {
  1320. var nZoomFactor = parseInt(selectZoom.options[selectZoom.selectedIndex].value);
  1321. if (nZoomFactor < 0)
  1322. {
  1323. HandleDynamicZoom();
  1324. }
  1325. else
  1326. {
  1327. ChangeZoom(nZoomFactor);
  1328. }
  1329. // The selects require a user to be able to arrow between values, selecting each in succession.
  1330. // As such, we cannot refocus the master container here.
  1331. }
  1332. function HandleFramesetSelect()
  1333. {
  1334. ChangeFramesetLayout(parseInt(selectFrameset.options[selectFrameset.selectedIndex].value), false);
  1335. // The selects require a user to be able to arrow between values, selecting each in succession.
  1336. // As such, we cannot refocus the master container here.
  1337. }
  1338. function HandleZoomInButton()
  1339. {
  1340. HandleZoom(-1);
  1341. // Force focus back to the preview document so keyboard
  1342. // accelerators work as expected
  1343. MasterContainer.focus();
  1344. }
  1345. function HandleZoomOutButton()
  1346. {
  1347. HandleZoom(1);
  1348. // Force focus back to the preview document so keyboard
  1349. // accelerators work as expected
  1350. MasterContainer.focus();
  1351. }
  1352. function HandleInputKeyPress()
  1353. {
  1354. var keyStroke = event.keyCode;
  1355. if (keyStroke == 13) // Enter
  1356. {
  1357. event.srcElement.onchange();
  1358. }
  1359. else if (keyStroke < 48 || keyStroke > 57)
  1360. {
  1361. // only allow numeric input
  1362. event.returnValue = false;
  1363. }
  1364. }
  1365. function Close()
  1366. {
  1367. // (greglett) The point of this is to give the host an update on the page# we're
  1368. // printing. Since it's slow, and noone uses it now anyway except as a boolean,
  1369. // we just use it as an on/off for the printer status icon.
  1370. Printer.updatePageStatus(-1); // Display the printing icon in the browser
  1371. // HACKHACK (greglett) See defnition of this variable above for details.
  1372. if (g_fDelayClose)
  1373. {
  1374. g_fDelayClose = false;
  1375. window.setTimeout("Close()", 120000); // Allow 2 minutes
  1376. return;
  1377. }
  1378. #ifdef DEBUG
  1379. if (!g_fReallyClose)
  1380. return;
  1381. #endif
  1382. window.close();
  1383. }
  1384. //----------------------------------------------------------------------
  1385. // Function PrintAll()
  1386. //
  1387. // Synopsis: This function ensures that all settings are current,
  1388. // creates all linked documents (if the user has specified that
  1389. // print option), and asks each CPrintDoc to print itself.
  1390. //----------------------------------------------------------------------
  1391. function PrintAll()
  1392. {
  1393. var i;
  1394. var nFirstDoc;
  1395. // (greglett) If we're printing frames in any way other than as shown, we should
  1396. // wait on all the little frameset documents to load. Consider a better way?
  1397. if ( g_nFramesLeft > 0
  1398. && Printer.framesetDocument
  1399. && !Printer.frameAsShown )
  1400. {
  1401. // The OnBuildFrames timeout should be smaller than this one's - since this is gating on a variable that
  1402. // only changes when OnBuildFrames has had a chance to spin.
  1403. window.setTimeout("PrintAll()", 100); // Poll every tenth of a second.
  1404. return;
  1405. }
  1406. EnsureDocuments();
  1407. // Nothing to do if we have no copies
  1408. if (Printer.copies <= 0)
  1409. {
  1410. Close();
  1411. }
  1412. // Some OS's don't force this restriction in the Print dialog. We do it posthumously.
  1413. else if ( Printer.selectedPages
  1414. && Printer.pageFrom > Printer.pageTo )
  1415. {
  1416. var L_PAGERANGE_ErrorMessage = "The 'From' value cannot be greater than the 'To' value.";
  1417. alert(L_PAGERANGE_ErrorMessage);
  1418. // A "Preview" print should just exit the function. The user can click print again.
  1419. // A "NoPrompt" print should never be here.
  1420. AssertSz(dialogArguments.__IE_PrintType != "NoPrompt", "From > To with no possible UI?");
  1421. // A "Prompt" print will leak the template if we just let it leave the function!
  1422. // Throw the dialog again.
  1423. if (!g_fPreview)
  1424. PrintNow(true);
  1425. }
  1426. else
  1427. {
  1428. // How do we know when to close the window (all docs done printing)?
  1429. // Right now, we have each doc decrement the g_cLeftToPrint until
  1430. // it hits zero; the last one then closes the window.
  1431. g_cLeftToPrint = 1;
  1432. // (greglett) The point of this is to give the host an update on the page# we're
  1433. // printing. Since it's slow, and noone uses it now anyway except as a boolean,
  1434. // we just use it as an on/off for the printer status icon.
  1435. Printer.updatePageStatus(1); // Display the printing icon in the browser
  1436. PrintSentinel(((Printer.selection)
  1437. ? "S"
  1438. : (Printer.frameActive && !!g_strActiveFrame)
  1439. ? g_strActiveFrame
  1440. : "C"),
  1441. true);
  1442. }
  1443. }
  1444. // No syncrohization mechanism exists in JScript except for brute force. Instead of pure busy waiting,
  1445. // let's at least sleep for fixed time periods.
  1446. function PrintSentinel( strDoc, fRecursionOK )
  1447. {
  1448. // Gate on the document being ready to print.
  1449. if ( !g_aDocTree[strDoc]
  1450. || !g_aDocTree[strDoc].ReadyToPrint() )
  1451. {
  1452. window.setTimeout("PrintSentinel('" + strDoc + "'," + fRecursionOK + ");", 500);
  1453. return;
  1454. }
  1455. g_aDocTree[strDoc].Print(fRecursionOK);
  1456. }
  1457. function PrintDocumentComplete()
  1458. {
  1459. g_cLeftToPrint--;
  1460. if (g_cLeftToPrint <= 0)
  1461. {
  1462. Close();
  1463. }
  1464. }
  1465. //----------------------------------------------------------------------
  1466. // PrintNow()
  1467. // We've either been called without preview or from the preview
  1468. // helper function, HandlePrintClick(). In either case, just do
  1469. // that printing thing now. In preview situations, the user should
  1470. // always get a print dialog and the template should NOT close
  1471. // if the user clicks 'Cancel' in the dialog. In straight-print
  1472. // situations with a print dialog, a 'Cancel' selection will close
  1473. // the template.
  1474. //----------------------------------------------------------------------
  1475. function PrintNow( fWithPrompt)
  1476. {
  1477. // We have to gate on the loading of the original document right now for
  1478. // frameset information.
  1479. if ( !g_aDocTree["C"]
  1480. || !g_aDocTree["C"]._aaRect[LOADING_CONTENT][0]
  1481. || !g_aDocTree["C"]._aaRect[LOADING_CONTENT][0].contentDocument.body) // 89002 - may not exist yet.
  1482. {
  1483. window.setTimeout("PrintNow('" + fWithPrompt + "');", 100); // Poll every tenth of a second.
  1484. return;
  1485. }
  1486. var oDoc = g_aDocTree["C"]._aaRect[LOADING_CONTENT][0].contentDocument;
  1487. var fConfirmed;
  1488. var fFramesetDocument = (oDoc.body.tagName.toUpperCase() == "FRAMESET");
  1489. // fActiveFrame includes:
  1490. // FRAMESET documents (which will have a g_strActiveFrame)
  1491. // IFRAME documents (which will not!)
  1492. var fActiveFrame = (oDoc.all.tags("HTML").item(0).__IE_ActiveFrame != null);
  1493. Printer.framesetDocument = fFramesetDocument;
  1494. Printer.frameActiveEnabled = fActiveFrame;
  1495. if (g_fPreview)
  1496. {
  1497. Printer.frameActive = (g_nFramesetLayout == FRAMESET_SELECTED);
  1498. Printer.frameAsShown = (g_nFramesetLayout == FRAMESET_LAID_OUT);
  1499. Printer.currentPageAvail = true;
  1500. }
  1501. else
  1502. {
  1503. Printer.frameActive = fActiveFrame;
  1504. Printer.frameAsShown = false;
  1505. Printer.currentPageAvail = false;
  1506. }
  1507. // The selection document may not be created yet. Directly check the dialogArguments.
  1508. Printer.selectionEnabled = !!(dialogArguments.__IE_ContentSelectionUrl);
  1509. Printer.selection = false; // Never default to selection.
  1510. #ifdef DEBUG
  1511. Log("ShowingPrintDialog " + eval(fWithPrompt));
  1512. #endif
  1513. fConfirmed = (eval(fWithPrompt)) ? Printer.showPrintDialog() : Printer.ensurePrintDialogDefaults();
  1514. if ( fConfirmed )
  1515. {
  1516. if ( Printer.selection
  1517. && dialogArguments.__IE_ContentSelectionUrl ) // (greglett) Check this too, in case the dlg was mishandled
  1518. {
  1519. // NB: (greglett)
  1520. // We always loaded the selection document in IE55
  1521. CreateDocument(dialogArguments.__IE_ContentSelectionUrl, "S", true);
  1522. }
  1523. #ifdef DEBUG
  1524. Log("Printer: Copies:" + Printer.deviceSupports("copies") + " Collate:" + Printer.deviceSupports("collate"));
  1525. #endif
  1526. Printer.usePrinterCopyCollate = ( Printer.deviceSupports("copies") >= Printer.copies
  1527. && ( !Printer.collate
  1528. || Printer.deviceSupports("collate") ));
  1529. PrintAll();
  1530. }
  1531. else
  1532. {
  1533. if ( !g_fPreview )
  1534. {
  1535. Close();
  1536. }
  1537. else
  1538. {
  1539. // TODO (greglett) (104826 - but really task level work)
  1540. // We may theoretically have changes even with a Cancel for two reasons:
  1541. // 1. In NT5, the Apply button may have been clicked, followed by Cancel.
  1542. // Right now, this doesn't work because the DHUI doesn't deal with this correctly.
  1543. // 2. The user may be printing to file, have clicked OK, then Cancel on the
  1544. // file query dialog. Right now, this doesn't work in CTemplatePrinter.
  1545. // Do we want this to work like this?
  1546. // The template is not currently robust enough to survive this, even if it were to
  1547. // work correctly. TableOfLinks has problems, as does AllLinkedDocs.
  1548. Printer.tableoflinks = false;
  1549. }
  1550. }
  1551. }
  1552. //----------------------------------------------------------------------
  1553. // HandlePrintClick()
  1554. // this is just a helper fucntion so that we close the window properly
  1555. // even when we are using this template to print with preview.
  1556. //----------------------------------------------------------------------
  1557. function HandlePrintClick()
  1558. {
  1559. // Call the PrintNow function, but indicate that we always want a
  1560. // print dialog and never want to close preview on completion.
  1561. PrintNow(true, true);
  1562. }
  1563. //----------------------------------------------------------------------
  1564. //----------------------------------------------------------------------
  1565. // CLASS CPrintDoc FUNCTIONS BEGIN HERE
  1566. //----------------------------------------------------------------------
  1567. //----------------------------------------------------------------------
  1568. //----------------------------------------------------------------------
  1569. // Member CPrintDoc::ReadyToPrint
  1570. //
  1571. // Synopsis: Is the print doc in a state where we can call print?
  1572. //----------------------------------------------------------------------
  1573. function CPrintDoc_ReadyToPrint()
  1574. {
  1575. if ( this._nStatus == READY_TO_PRINT
  1576. && this._aaRect[LOADING_CONTENT][0].contentDocument.readyState == "complete")
  1577. {
  1578. return true;
  1579. }
  1580. return false;
  1581. }
  1582. //----------------------------------------------------------------------
  1583. // Member CPrintDoc::Print
  1584. //
  1585. // Synopsis: Prints the document, taking into acount # of copies, a page
  1586. // range, and collation.
  1587. //----------------------------------------------------------------------
  1588. function CPrintDoc_Print( fRecursionOK )
  1589. {
  1590. if (!this.ReadyToPrint())
  1591. {
  1592. // Don't localize this debug string
  1593. HandleError("Printing when not ready!", document.URL, "CPrintDoc::Print");
  1594. return;
  1595. }
  1596. var nCount = (Printer.usePrinterCopyCollate) ? 1 : Printer.copies;
  1597. var nFrom;
  1598. var nTo;
  1599. AssertSz(nCount > 0, "Printing 0 or less copies"); // We should have already checked this.
  1600. // Attempt to recurse if necessary (activeFrame, allLinkedDocuments, &c...)
  1601. if (fRecursionOK)
  1602. {
  1603. var fFrameset = (this._aaRect[LOADING_CONTENT][0].contentDocument.body.tagName.toUpperCase() == "FRAMESET");
  1604. if (Printer.frameActive) // Print active frame
  1605. {
  1606. var n = parseInt(this._aaRect[LOADING_CONTENT][0].contentDocument.all.tags("HTML").item(0).__IE_ActiveFrame);
  1607. if (n >= 0)
  1608. {
  1609. var oTargetFrame = (fFrameset)
  1610. ? this._aaRect[LOADING_CONTENT][0].contentDocument.all.tags("FRAME").item(n)
  1611. : this._aaRect[LOADING_CONTENT][0].contentDocument.all.tags("IFRAME").item(n);
  1612. // Load active frame
  1613. if ( IsPersistedDoc()
  1614. && ( oTargetFrame.src == "res://SHDOCLC.DLL/printnof.htm" // FRAME
  1615. || oTargetFrame.src == "about:blank" )) // IFRAME
  1616. {
  1617. // Immediate subframe is a WebOC hosted document. Use special
  1618. // interface to print it (Trident couldn't marshall it due to external bugs)
  1619. Printer.printNonNativeFrames(this._aaRect[LOADING_CONTENT][0].contentDocument, true); // true for ActiveFrame
  1620. }
  1621. else
  1622. {
  1623. // Immediate subframe is an HTML document. Recurse.
  1624. this.CreateSubDocument(oTargetFrame.src, true);
  1625. this.PrintAllSubDocuments(true);
  1626. }
  1627. // Finish printing this document...
  1628. PrintDocumentComplete();
  1629. return;
  1630. }
  1631. }
  1632. if (fFrameset)
  1633. {
  1634. if (!Printer.frameAsShown) // Print all frames
  1635. {
  1636. this.PrintAllSubDocuments(true);
  1637. if (IsPersistedDoc())
  1638. {
  1639. // Print all Word document frames, too
  1640. Printer.printNonNativeFrames(this._aaRect[LOADING_CONTENT][0].contentDocument, false); // false for all frames
  1641. }
  1642. // Finish printing this document...
  1643. PrintDocumentComplete();
  1644. return;
  1645. }
  1646. else
  1647. {
  1648. // Print all Word document frames in addition to the as laid out
  1649. Printer.printNonNativeFrames(this._aaRect[LOADING_CONTENT][0].contentDocument, false); // false for all frames
  1650. }
  1651. }
  1652. else // BODY document.
  1653. {
  1654. // Build all linked documents, if necessary.
  1655. if (Printer.allLinkedDocuments)
  1656. {
  1657. this.BuildAllLinkedDocuments();
  1658. this.PrintAllSubDocuments(false);
  1659. }
  1660. }
  1661. }
  1662. // We may be a WebOC document. If we are, and it prints itself, we're done.
  1663. if (Printer.printNonNative(this._aaRect[LOADING_CONTENT][0].contentDocument) )
  1664. {
  1665. // HACKHACK (greglett) See defnition of this variable above for details.
  1666. g_fDelayClose = !g_fPreview;
  1667. PrintDocumentComplete();
  1668. return;
  1669. }
  1670. // Clip page range to this document/subdocument.
  1671. // NB (greglett)
  1672. // Selected Page/CurrentPage don't work as expected with AllLinkedDocuments.
  1673. // (We don't print only the linked documents on the given page)
  1674. // It can't unless we can get a collection with only with particular pages on it.
  1675. // NB (greglett)
  1676. // If asked to print a table of links and a page range, do we:
  1677. // 1. Always print a table of links (for the whole document).
  1678. // 2. Print whole TOL if the page range and the TOL range is nonintersecting
  1679. // or only the intersection if the range intersects.
  1680. // 3. Print only the part of the TOL that intersects the page range.
  1681. // Remember, NT5+ has an apply button and should be able to preview the TOL (though
  1682. // they can't yet, because we don't support Apply).
  1683. // We currently take the path of least resistance: #3.
  1684. if (Printer.selectedPages)
  1685. {
  1686. nFrom = Printer.pageFrom;
  1687. nTo = Printer.pageTo;
  1688. if (nFrom < 1)
  1689. nFrom = 1;
  1690. if (nTo > this.Pages())
  1691. nTo = this.Pages();
  1692. }
  1693. // CurrentPage only applies to the document being previewed. Any subdocuments that are
  1694. // printed should print in their entirity.
  1695. else if ( Printer.currentPage
  1696. && this._strDoc == DisplayDocument())
  1697. {
  1698. nFrom = (this.Pages() >= g_nDispPage) ? g_nDispPage : this.Pages();
  1699. nTo = nFrom;
  1700. }
  1701. else
  1702. {
  1703. // Normal print job - print the whole kit n' kabootle
  1704. nFrom = 1;
  1705. nTo = this.Pages();
  1706. }
  1707. // In this case, we've been asked to print a valid range, but the document does not have
  1708. // any pages in the range. (ex: 2 to 3 of a 1 page document - nFrom = 2, nTo = 1)
  1709. // (We really only need to do this in selected pages above.)
  1710. if (nTo < nFrom)
  1711. {
  1712. PrintDocumentComplete();
  1713. return;
  1714. }
  1715. AssertSz(nFrom <= nTo, "pageTo is smaller than pageFrom!");
  1716. AssertSz(nFrom > 0, "pageFrom value 0 or less!");
  1717. AssertSz(nTo <= this.Pages(), "pageTo greater than number of pages in document!");
  1718. // The display URL goes onto the system spooler as a job title.
  1719. if (Printer.startDoc(this._aaRect[LOADING_CONTENT][0].contentDocument.URL))
  1720. {
  1721. if (Printer.collate)
  1722. {
  1723. // (greglett) (10084)
  1724. // Printing collated, multiple documents, we need to ensure the document has an even # of pages;
  1725. // This may require an extra page.
  1726. // [1|2] [3| ] [1|2] [3| ]
  1727. var fExtraPage = ( Printer.duplex
  1728. && ((nFrom - nTo) % 2 == 0) );
  1729. for (j = 0; j < nCount; j++)
  1730. {
  1731. for (i = nFrom; i <= nTo; i++)
  1732. {
  1733. Printer.printPage(this.Page(i).children[0]);
  1734. }
  1735. if (fExtraPage)
  1736. Printer.printBlankPage();
  1737. }
  1738. }
  1739. else
  1740. {
  1741. // (greglett) (10084)
  1742. // If we are printing duplex, multiple documents, we need to print pairs of pages.
  1743. // We print front-to-back, producing the output (for a 3 page, 2 copies):
  1744. // [1|2] [1|2] [3| ] [3| ]...
  1745. var fDuplex = Printer.duplex;
  1746. for (i = nFrom; i <= nTo; i++)
  1747. {
  1748. for (j = 0; j < nCount; j++)
  1749. {
  1750. Printer.printPage(this.Page(i).children[0]);
  1751. if (fDuplex)
  1752. {
  1753. if (i < nTo)
  1754. Printer.printPage(this.Page(i+1));
  1755. else
  1756. Printer.printBlankPage();
  1757. }
  1758. }
  1759. if (fDuplex)
  1760. i++;
  1761. }
  1762. }
  1763. Printer.stopDoc();
  1764. }
  1765. // All done.
  1766. PrintDocumentComplete();
  1767. }
  1768. //----------------------------------------------------------------------
  1769. // Member CPrintDoc::RectComplete
  1770. //
  1771. // Synopsis: Called whenever an onlayout complete fires for this document's
  1772. // layout rects. Requires a "callback" function OnRectComplete,
  1773. // above.
  1774. // This function determines when a document is complete, and adds
  1775. // a table of links/headers/footers if necessary.
  1776. //----------------------------------------------------------------------
  1777. function CPrintDoc_RectComplete(fOverflow, strElement)
  1778. {
  1779. var nStatus = parseInt(strElement.substr(5,1));
  1780. var nPage = parseInt(strElement.substr(strElement.lastIndexOf("p") + 1));
  1781. AssertSz((nStatus >= LOADING_OEHEADER) && (nStatus <= LOADING_TABLEOFLINKS), "Status within recognized bounds");
  1782. AssertSz(nPage < this._aaRect[nStatus].length, "Page # not created!");
  1783. // Ignore premature event calls. We'll deal with them when we're good and ready.
  1784. if (nStatus > this._nStatus)
  1785. return false;
  1786. // Ignore event calls from pages before this one on the sheaf
  1787. if (nPage != this._acPage[nStatus] - 1 + this._anMerge[nStatus])
  1788. return false;
  1789. // If this is from a previous document within this one...
  1790. if (nStatus != this._nStatus)
  1791. {
  1792. // ...and it's just telling us again that we're done, ignore it...
  1793. if (!fOverflow)
  1794. return false;
  1795. // ...but if there's new content, dynamically switch back into this pagination.
  1796. this.StopFixupHF(); // Stop H/F fixup - we need to do it again.
  1797. if (this._nStatus == READY_TO_PRINT) // Add ourselves back into the queue of repaginating docs
  1798. g_nDocsToCalc++;
  1799. Transition(nStatus, "Status backslide - RectComplete"); // Backslide status.
  1800. }
  1801. // Need another page...
  1802. if (fOverflow)
  1803. {
  1804. this.AddPage();
  1805. }
  1806. else
  1807. {
  1808. // No more pages needed in this phase of document calculation.
  1809. // Move into the next calculation phase.
  1810. switch (this._nStatus)
  1811. {
  1812. case LOADING_OEHEADER:
  1813. // Stream header has finished - begin content calculation.
  1814. Transition(LOADING_CONTENT, "RectComplete");
  1815. this.AddFirstPage();
  1816. this._aaRect[this._nStatus][0].contentSrc = this._strDocURL;
  1817. break;
  1818. case LOADING_CONTENT:
  1819. // Content has finished calcing - create a table of links if requested.
  1820. Transition(LOADING_TABLEOFLINKS, "RectComplete");
  1821. this.AddTableOfLinks();
  1822. break;
  1823. case LOADING_TABLEOFLINKS:
  1824. // All done with pagination. Headers and Footers, please.
  1825. Transition(PAGING_COMPLETE, "RectComplete");
  1826. if (this._strDoc == DisplayDocument())
  1827. ChangeDispPage(g_nDispPage); // Clip to the maximum page, in case we are reflowing & have fewer pages.
  1828. this.FixupHF();
  1829. break;
  1830. }
  1831. }
  1832. // Update the display to reflect the correct # of pages.
  1833. if (this._strDoc == DisplayDocument())
  1834. {
  1835. spanPageTotal.innerText = this.Pages();
  1836. // make sure the nav buttons are in an appropriate state
  1837. updateNavButtons();
  1838. }
  1839. }
  1840. //----------------------------------------------------------------------
  1841. // Member CPrintDoc::AddPage
  1842. //
  1843. // Synopsis: Adds a page to the end of the current document.
  1844. //----------------------------------------------------------------------
  1845. function CPrintDoc_AddPage()
  1846. {
  1847. var newHTM = "";
  1848. var aPage = this._aaPage[this._nStatus];
  1849. var aRect = this._aaRect[this._nStatus];
  1850. AssertSz(this._nStatus < PAGING_COMPLETE, "Adding page when pagination done!");
  1851. // Increment page count in this section of the print document
  1852. (this._acPage[this._nStatus])++;
  1853. HeadFoot.URL = this.EnsureURL();
  1854. HeadFoot.title = this.EnsureTitle();
  1855. HeadFoot.pageTotal = this.Pages();
  1856. HeadFoot.page = HeadFoot.pageTotal;
  1857. // We conserve layout rects - if this page has already been created, use it.
  1858. if (this._acPage[this._nStatus] <= aPage.length)
  1859. {
  1860. // Reset H/F - it may have changed.
  1861. var oPage = aPage[this._acPage[this._nStatus] - 1];
  1862. oPage.children("header").innerHTML = HeadFoot.HtmlHead;
  1863. oPage.children("footer").innerHTML = HeadFoot.HtmlFoot;
  1864. }
  1865. else
  1866. {
  1867. // TODO: (greglett) (108939) We have to parse in the nextRect right now because it is
  1868. // the CGenericElement::Notify (ENTERTREE) that hooks up the LayoutRect. Changing
  1869. // this value *after* the EnterTree has no effect.
  1870. // NB (greglett)
  1871. // Q: Why wrap the DeviceRect in a DIV instead of just using the DeviceRect?
  1872. // A: Because the OM on the DeviceRect is messed up such that it does do a resolution change scale.
  1873. // Instead, it returns CSS pixels *within* the rect. Because we also screw up sizing the rect, this
  1874. // turns out to work for a 96DPI screen. However, for 120DPI (large fonts), we off by 1.25 (120/96).
  1875. // Since the DIV has no resolution issues, we don't have the problem when we wrap the DeviceRect in a DIV.
  1876. newHTM = "<DIV class=divPage><IE:DeviceRect media=\"print\" class=page id=mDiv" + this._nStatus + this._strDoc + "p" + aPage.length + ">";
  1877. newHTM += "<IE:LAYOUTRECT id=mRect" + this._nStatus + this._strDoc + "p" + aRect.length;
  1878. newHTM += " class=mRect nextRect=mRect" + this._nStatus + this._strDoc + "p" + (aRect.length + 1);
  1879. newHTM += " onlayoutcomplete=OnRectComplete('" + this._strDoc + "')";
  1880. newHTM += " tabindex=-1 onbeforefocusenter='event.returnValue=false;' ";
  1881. newHTM += " /><DIV class=divHead id=header>";
  1882. newHTM += HeadFoot.HtmlHead;
  1883. newHTM += "</DIV><DIV class=divFoot id=footer>";
  1884. newHTM += HeadFoot.HtmlFoot;
  1885. newHTM += " </DIV></IE:DeviceRect></DIV>";
  1886. MasterContainer.insertAdjacentHTML("beforeEnd", newHTM);
  1887. aPage[aPage.length] = eval( "document.all.mDiv" + this._nStatus + this._strDoc + "p" + aPage.length);
  1888. aRect[aRect.length] = eval("document.all.mRect" + this._nStatus + this._strDoc + "p" + aRect.length);
  1889. }
  1890. }
  1891. //----------------------------------------------------------------------
  1892. // Member CPrintDoc::AddFirstPage
  1893. //
  1894. // Synopsis: Adds a page to the end of the current document.
  1895. //----------------------------------------------------------------------
  1896. function CPrintDoc_AddFirstPage()
  1897. {
  1898. this._acPage[this._nStatus] = 0;
  1899. if (this._anMerge[this._nStatus] == 0)
  1900. {
  1901. this.AddPage();
  1902. }
  1903. else
  1904. {
  1905. var aRect = this._aaRect[this._nStatus];
  1906. var oPage = this._aaPage[this._nStatus - 1][this._acPage[this._nStatus - 1] - 1];
  1907. var oTop = this._aaRect[this._nStatus - 1][this._acPage[this._nStatus - 1] + this._anMerge[this._nStatus - 1] - 1];
  1908. var nTop = oTop.offsetTop + oTop.scrollHeight;
  1909. var nHeight = oTop.clientHeight - oTop.scrollHeight;
  1910. AssertSz(this._nStatus < PAGING_COMPLETE, "Merging page when pagination done!");
  1911. AssertSz(this._anMerge[this._nStatus] > 0, "Merging page when not requested!");
  1912. // We cannot dynamically get a stream header. Ergo, if we have content layout rects,
  1913. // we must be repaginating, and already have a content layout rect on a stream page.
  1914. // We (may) simply need to resize and reparent it.
  1915. if (aRect.length > 0)
  1916. {
  1917. var oNode = aRect[0];
  1918. oNode.style.marginTop = nTop + "px";
  1919. oNode.style.pixelHeight = nHeight;
  1920. // Reparent, if necessary.
  1921. if (oNode.parentElement != oPage)
  1922. oPage.insertBefore(oNode);
  1923. }
  1924. // We need to actually size & create the content layout rect to merge onto the stream page.
  1925. else
  1926. {
  1927. var newHTM;
  1928. var oNode;
  1929. // TODO: (greglett) (108939) We have to parse in the nextRect right now because it is
  1930. // the CGenericElement::Notify (ENTERTREE) that hooks up the LayoutRect. Changing
  1931. // this value *after* the EnterTree has no effect.
  1932. newHTM = "<IE:LAYOUTRECT id=mRect" + this._nStatus + this._strDoc + "p0";
  1933. newHTM += " class=mRect nextRect=mRect" + this._nStatus + this._strDoc + "p1";
  1934. newHTM += " onlayoutcomplete=OnRectComplete('" + this._strDoc + "')";
  1935. newHTM += " tabindex=-1 onbeforefocus='event.returnValue=false;' />";
  1936. oPage.insertAdjacentHTML("beforeEnd", newHTM);
  1937. oNode = eval("document.all.mRect" + this._nStatus + this._strDoc + "p0");
  1938. aRect[0] = oNode;
  1939. oNode.style.marginTop = nTop + "px";
  1940. oNode.style.height = nHeight + "px";
  1941. }
  1942. }
  1943. }
  1944. //----------------------------------------------------------------------
  1945. // Member CPrintDoc::InitDocument
  1946. //
  1947. // Synopsis: Begins pagination of document. This could be merged with
  1948. // the constructor.
  1949. //----------------------------------------------------------------------
  1950. function CPrintDoc_InitDocument( fUseStreamHeader )
  1951. {
  1952. var fReallyUseStreamHeader = (fUseStreamHeader && (dialogArguments.__IE_OutlookHeader != null));
  1953. this._anMerge[LOADING_CONTENT] = (fReallyUseStreamHeader) ? 1 : 0;
  1954. Transition((fReallyUseStreamHeader) ? LOADING_OEHEADER : LOADING_CONTENT, "Initialize Status");
  1955. this.AddFirstPage();
  1956. this._aaRect[this._nStatus][0].contentSrc = (fReallyUseStreamHeader)
  1957. ? dialogArguments.__IE_OutlookHeader
  1958. : this._strDocURL;
  1959. }
  1960. function CPrintDoc_PrintAllSubDocuments( fRecursionOK )
  1961. {
  1962. if (!this._aDoc)
  1963. return;
  1964. var nDocs = this._aDoc.length;
  1965. var i;
  1966. g_cLeftToPrint += nDocs;
  1967. for (i = 0; i < nDocs; i++)
  1968. {
  1969. PrintSentinel(this._aDoc[i]._strDoc, fRecursionOK);
  1970. }
  1971. }
  1972. function CPrintDoc_BuildAllLinkedDocuments()
  1973. {
  1974. var strURL = this._aaRect[LOADING_CONTENT][0].contentDocument.URL;
  1975. var aLinks = this._aaRect[LOADING_CONTENT][0].contentDocument.links;
  1976. var nLinks = aLinks.length;
  1977. var i;
  1978. var j;
  1979. var strLink;
  1980. for (i = 0; i < nLinks; i++)
  1981. {
  1982. strLink = aLinks[i].href;
  1983. // Check against our own URL.
  1984. // Check to make sure we are not opening a bad URL
  1985. if ( (strURL == strLink)
  1986. || UnprintableURL(strLink) )
  1987. continue;
  1988. // Check for a duplicate in the list. Yes, this is n^2... as in IE4+
  1989. for (j = 0; j < i; j++)
  1990. {
  1991. if (strLink == aLinks[j].href)
  1992. break;
  1993. }
  1994. if (j < i) // Duplicate found.
  1995. continue;
  1996. this.CreateSubDocument(strLink, false);
  1997. }
  1998. }
  1999. function OnBuildAllFrames( strDoc )
  2000. {
  2001. // We have to gate on the loading of the original document right now for
  2002. // frameset information.
  2003. if ( !g_aDocTree[strDoc]
  2004. || !g_aDocTree[strDoc]._aaRect[LOADING_CONTENT][0]
  2005. || !g_aDocTree[strDoc]._aaRect[LOADING_CONTENT][0].contentDocument.body) // 89002 - may not exist yet.
  2006. {
  2007. window.setTimeout("OnBuildAllFrames('" + strDoc + "');", 100);
  2008. return;
  2009. }
  2010. g_aDocTree[strDoc].BuildAllFrames();
  2011. }
  2012. function IsPersistedDoc()
  2013. {
  2014. // Since this is only called while printing, we can be sure the following exists...
  2015. return (!!g_aDocTree["C"]._aaRect[LOADING_CONTENT][0].contentDocument.all.tags("HTML")[0].__IE_DisplayURL);
  2016. }
  2017. function CPrintDoc_BuildAllFrames()
  2018. {
  2019. var aFrames = this._aaRect[LOADING_CONTENT][0].contentDocument.all.tags("FRAME");
  2020. var nFrames = aFrames.length;
  2021. var nActive = parseInt(this._aaRect[LOADING_CONTENT][0].contentDocument.all.tags("HTML").item(0).__IE_ActiveFrame);
  2022. var i;
  2023. var strSrc;
  2024. var strDoc;
  2025. if (nFrames > 0)
  2026. this._fFrameset = true;
  2027. for (i = 0; i < nFrames; i++)
  2028. {
  2029. strSrc = aFrames[i].src;
  2030. // This URL was created by Trident replacing a WebOC frame that it couldn't marshall.
  2031. // These will be printed via a call to "Printer.printNonNativeFrames(false)" in the caller.
  2032. if (strSrc == "res://SHDOCLC.DLL/printnof.htm")
  2033. continue;
  2034. // Make a document for the new URL.
  2035. // We can't use the markup because it's already slaved (to the frame)
  2036. strDoc = this.CreateSubDocument(strSrc, true);
  2037. if (i == nActive)
  2038. g_strActiveFrame = strDoc;
  2039. // Increment the semaphore, indicating that we're building a deeper branch of frames
  2040. // (see OnLoadBody() for more info)
  2041. g_nFramesLeft++;
  2042. // And then recurse to build its children frames
  2043. OnBuildAllFrames(strDoc);
  2044. }
  2045. // Decrement the semaphore, indicating that we've finished building this branch
  2046. // (see OnLoadBody() for more info)
  2047. g_nFramesLeft--;
  2048. if (g_nFramesLeft <= 0)
  2049. BuildAllFramesComplete();
  2050. }
  2051. function CPrintDoc_CreateSubDocument( docURL, fUseStreamHeader )
  2052. {
  2053. if (!this._aDoc)
  2054. this._aDoc = new Array();
  2055. var nDoc = this._aDoc.length;
  2056. var strDoc = this._strDoc + "_" + nDoc;
  2057. CreateDocument(docURL, strDoc, fUseStreamHeader);
  2058. this._aDoc[nDoc] = g_aDocTree[strDoc];
  2059. return (strDoc);
  2060. }
  2061. //----------------------------------------------------------------------
  2062. // Member CPrintDoc::AddTableOfLinks
  2063. //
  2064. // Synopsis: Appends a table of links to the end of the current document
  2065. // (this uses the documents current page value to determine the
  2066. // "end" - do not call if this number is not determined).
  2067. //----------------------------------------------------------------------
  2068. function CPrintDoc_AddTableOfLinks()
  2069. {
  2070. AssertSz(this._nStatus == LOADING_TABLEOFLINKS, "Call to AddTableOfLinks when not ready!");
  2071. // No table of links requested. Transition to header/footer work.
  2072. if (!g_fTableOfLinks)
  2073. {
  2074. Transition(PAGING_COMPLETE, "AddTableOfLinks, no table of links requested");
  2075. ChangeDispPage(g_nDispPage); // Clip to the maximum page, in case we are reflowing & have fewer pages.
  2076. this.FixupHF();
  2077. }
  2078. else
  2079. {
  2080. var oTableOfLinks = BuildTableOfLinks(this._aaRect[LOADING_CONTENT][0].contentDocument);
  2081. if (oTableOfLinks != null)
  2082. {
  2083. // NB (greglett)
  2084. // The markup for the oTableOfLinks document becomes null across the
  2085. // AddFirstPage below. The issue is timing related. A workaround is to store the body.
  2086. var oBody = oTableOfLinks.body;
  2087. this.AddFirstPage()
  2088. this._aaRect[this._nStatus][0].contentSrc = oBody.document;
  2089. }
  2090. else
  2091. {
  2092. // Table of links does not exist. Move straight to the HeadersAndFooters thing.
  2093. Transition(PAGING_COMPLETE, "AddTableOfLinks, no table");
  2094. ChangeDispPage(g_nDispPage); // Clip to the maximum page, in case we are reflowing & have fewer pages.
  2095. this.FixupHF();
  2096. }
  2097. }
  2098. }
  2099. //----------------------------------------------------------------------
  2100. // Member CPrintDoc::FixupHF
  2101. //
  2102. // Synopsis: Goes through all pages in the document, updating/creating
  2103. // their header/footers.
  2104. //----------------------------------------------------------------------
  2105. function OnTickHF( strDoc )
  2106. {
  2107. if (!g_aDocTree[strDoc])
  2108. {
  2109. // No need to localize the string - it is only displayed in debug mode.
  2110. HandleError("Document " + strDoc + " does not exist.", document.URL, "OnRectComplete");
  2111. return;
  2112. }
  2113. g_aDocTree[strDoc].TickHF();
  2114. }
  2115. // There are two magic numbers in this function - the n in the line iTo = nStartPage + n and the setTimeout delay.
  2116. // The first is directly proportional to the contiguous block of processor time we'll take at a time, but inversely proportional
  2117. // to the # of timeouts we'll have to set and the total amount of time required to do the job.
  2118. // The timeout delay is how long we allow Trident to update and process UI (button highlights, &c...).
  2119. function CPrintDoc_TickHF()
  2120. {
  2121. var i, j;
  2122. var iTo, jTo;
  2123. var aTok;
  2124. var oTok;
  2125. var nStartPage = this._nNextHF;
  2126. var cPages = this.Pages();
  2127. iTo = nStartPage + 2;
  2128. if (iTo > cPages)
  2129. iTo = cPages;
  2130. for (i = nStartPage; i <= iTo; i++)
  2131. {
  2132. // (greglett) Why first child? See comments in CPrintDoc_AddPage.
  2133. aTok = this.Page(i).children[0].getElementsByTagName("SPAN");
  2134. for (j=0, jTo = aTok.length; j < jTo; j++)
  2135. {
  2136. oTok = aTok[j];
  2137. if (oTok.className == "hfPageTotal")
  2138. oTok.innerText = cPages;
  2139. else if ( oTok.className == "hfUrl"
  2140. && oTok.innerText == "" )
  2141. oTok.innerText = this.EnsureURL();
  2142. else if ( oTok.className == "hfTitle"
  2143. && oTok.innerText == "" )
  2144. oTok.innerText = this.EnsureTitle();
  2145. }
  2146. }
  2147. // Update page # of next HF we need to fixup.
  2148. this._nNextHF = i;
  2149. #ifdef DEBUG
  2150. // DEBUG ONLY - Track H/F fixup speed visually.
  2151. spanDebugHF.innerText = this._nNextHF - 1;
  2152. #endif
  2153. // If we're not done crowning & shoeing the document yet, we need to set a timeout to get back to it.
  2154. // Timeout should be long enough to process UI.
  2155. if (iTo == cPages)
  2156. {
  2157. Transition(READY_TO_PRINT, "AddHAndF");
  2158. if (--g_nDocsToCalc == 0)
  2159. CalcDocsComplete();
  2160. }
  2161. else
  2162. {
  2163. this._nTimerHF = window.setTimeout("OnTickHF('" + this._strDoc + "');", 250);
  2164. }
  2165. }
  2166. //----------------------------------------------------------------------
  2167. // Member CPrintDoc::FixupHF
  2168. //
  2169. // Synopsis: Kicks off the
  2170. // their header/footers.
  2171. //----------------------------------------------------------------------
  2172. function CPrintDoc_FixupHF()
  2173. {
  2174. AssertSz(this._nStatus == PAGING_COMPLETE, "Call to FixupHF when not ready!");
  2175. #ifdef DEBUG
  2176. // DEBUG ONLY - Track H/F fixup speed visually.
  2177. spanDebugHF.innerText = this._nNextHF;
  2178. #endif
  2179. // Kick off the header/footer pass on the document.
  2180. this.TickHF();
  2181. }
  2182. //----------------------------------------------------------------------
  2183. // Member CPrintDoc::Pages, Page
  2184. //
  2185. // Synopsis: With multiple page arrays per CPrintDoc, these functions
  2186. // are to provide the illusion of one array. To make this
  2187. // closer to user UI, this virtual array is 1 based, not 0 based.
  2188. //----------------------------------------------------------------------
  2189. function CPrintDoc_Pages()
  2190. {
  2191. var i;
  2192. var c;
  2193. for (i = 0, c = 0; i < PAGING_COMPLETE; i++)
  2194. {
  2195. c += this._acPage[i];
  2196. }
  2197. return c;
  2198. }
  2199. function CPrintDoc_Page(nPage)
  2200. {
  2201. var i;
  2202. var n = nPage;
  2203. if (n <= 0)
  2204. return null;
  2205. for (i = 0; i < PAGING_COMPLETE; i++)
  2206. {
  2207. // (greglett) Why parentElement? See comments in CPrintDoc_AddPage.
  2208. if (n <= this._acPage[i])
  2209. return this._aaPage[i][n - 1].parentElement;
  2210. n -= this._acPage[i];
  2211. }
  2212. return null;
  2213. }
  2214. function CPrintDoc_EnsureURL()
  2215. {
  2216. if (this._strURL == null)
  2217. {
  2218. if ( this._aaRect[LOADING_CONTENT][0]
  2219. && this._aaRect[LOADING_CONTENT][0].contentDocument)
  2220. {
  2221. this._strURL = this._aaRect[LOADING_CONTENT][0].contentDocument.URL;
  2222. }
  2223. // We must return a string.
  2224. if (this._strURL == null)
  2225. return "";
  2226. }
  2227. return this._strURL;
  2228. }
  2229. function CPrintDoc_EnsureTitle()
  2230. {
  2231. if (this._strTitle == null)
  2232. {
  2233. if ( this._aaRect[LOADING_CONTENT][0]
  2234. && this._aaRect[LOADING_CONTENT][0].contentDocument)
  2235. {
  2236. this._strTitle = this._aaRect[LOADING_CONTENT][0].contentDocument.title;
  2237. }
  2238. // We must return a string.
  2239. if (this._strTitle == null)
  2240. return "";
  2241. }
  2242. return this._strTitle;
  2243. }
  2244. //----------------------------------------------------------------------
  2245. // Member CPrintDoc::ResetXXXX
  2246. //
  2247. // Synopsis: If the given quantity (Document, TableOfLinks... &c...) has been
  2248. // calculated, this will force it to be recalculated. If not, the
  2249. // functions essentially do nothing (because the quantity will be
  2250. // created as the document finishes loading).
  2251. //----------------------------------------------------------------------
  2252. function CPrintDoc_ResetDocument()
  2253. {
  2254. var i;
  2255. for (i = 0; i < PAGING_COMPLETE; i++)
  2256. {
  2257. this._acPage[i] = 0;
  2258. // HACKHACK (greglett) 94479
  2259. // The viewchain is not capable of recalcing if the layout rect properties are changed right now.
  2260. // So, we unhook the LR (HERE) change the properties, and then reload/reparse the entire document (LATER)
  2261. if (this._aaRect[i][0])
  2262. this._aaRect[i][0].contentSrc = "";
  2263. }
  2264. this.StopFixupHF();
  2265. }
  2266. function CPrintDoc_ResetTableOfLinks()
  2267. {
  2268. // A table of links will be generated as part of the document when we get to it.
  2269. if (this._nStatus <= LOADING_TABLEOFLINKS)
  2270. return;
  2271. this.StopFixupHF();
  2272. Transition(LOADING_TABLEOFLINKS, "ResetTableOfLinks");
  2273. this.AddTableOfLinks();
  2274. }
  2275. function CPrintDoc_StopFixupHF()
  2276. {
  2277. if (this._nTimerHF != -1)
  2278. window.clearTimeout(this._nTimerHF);
  2279. this._nTimerHF = -1;
  2280. this._nNextHF = 1; // Could be higher, to only reget the TOL pages.
  2281. }
  2282. //
  2283. // CPRINTDOC MEMBER FUNCTIONS
  2284. //
  2285. // This function is a constructor for the CPrintDoc Object.
  2286. // CPrintDoc contains per document information.
  2287. function CPrintDoc( nDocNum, strDocURL )
  2288. {
  2289. var i;
  2290. this._aDoc = null; // Array of frames/linked documents.
  2291. this._strDoc = nDocNum; // Document id of this document (in form "C_2_3")
  2292. this._strDocURL = strDocURL; // "Real" URL of document (for LayoutRect's contentSrc).
  2293. // _nStatus stores the phase of pagination/flow completion that the document is in:
  2294. // The values are defined in preview.h, and initialized in InitDocument
  2295. this._nStatus = 0;
  2296. this._aaPage = new Array(PAGING_COMPLETE);
  2297. this._aaRect = new Array(PAGING_COMPLETE);
  2298. this._acPage = new Array(PAGING_COMPLETE);
  2299. this._anMerge = new Array(PAGING_COMPLETE);
  2300. for (i=0; i<PAGING_COMPLETE; i++)
  2301. {
  2302. this._aaPage[i] = new Array();
  2303. this._aaRect[i] = new Array();
  2304. this._acPage[i] = 0;
  2305. this._anMerge[i] = 0;
  2306. }
  2307. this._nNextHF = 1;
  2308. this._nTimerHF = -1;
  2309. this._strURL = null;
  2310. this._strTitle = null;
  2311. this._fFrameset = false;
  2312. this._nStartingPage = 0;
  2313. }
  2314. // Pagination functions
  2315. MEMBER(CPrintDoc, RectComplete);
  2316. MEMBER(CPrintDoc, AddPage);
  2317. MEMBER(CPrintDoc, AddFirstPage);
  2318. MEMBER(CPrintDoc, AddTableOfLinks);
  2319. MEMBER(CPrintDoc, FixupHF);
  2320. MEMBER(CPrintDoc, StopFixupHF);
  2321. MEMBER(CPrintDoc, TickHF);
  2322. // Document status functions
  2323. MEMBER(CPrintDoc, InitDocument);
  2324. MEMBER(CPrintDoc, ResetDocument);
  2325. MEMBER(CPrintDoc, ResetTableOfLinks);
  2326. // Recursive document functions
  2327. MEMBER(CPrintDoc, BuildAllLinkedDocuments);
  2328. MEMBER(CPrintDoc, BuildAllFrames);
  2329. MEMBER(CPrintDoc, CreateSubDocument);
  2330. // Printing functions
  2331. MEMBER(CPrintDoc, Print);
  2332. MEMBER(CPrintDoc, PrintAllSubDocuments);
  2333. MEMBER(CPrintDoc, ReadyToPrint);
  2334. // Data access functions
  2335. MEMBER(CPrintDoc, Page);
  2336. MEMBER(CPrintDoc, Pages);
  2337. MEMBER(CPrintDoc, EnsureURL);
  2338. MEMBER(CPrintDoc, EnsureTitle);
  2339. </SCRIPT>
  2340. </HEAD>
  2341. <BODY onload="setTimeout('OnLoadBody()', 400);">
  2342. <!-- Controls for printing -->
  2343. <IE:TemplatePrinter id=Printer />
  2344. <IE:HeaderFooter id=HeadFoot />
  2345. <DIV id=idDivToolbar style="width:100%; overflow:hidden;">
  2346. <DIV style="width=100%; border:'thin threedhighlight groove';">
  2347. <TABLE><TR>
  2348. <TD class="UIPane"> <BUTTON id="butPrint" title="Print Document (Alt+P)" accesskey=p><U>P</U>rint...</BUTTON></TD>
  2349. <TD class="UISeparator"><IMG width=0 height=0></TD>
  2350. <TD class="UIPane"> <BUTTON id="butPageSetup" accesskey=u><IMG id="printCtl" src="printctl.gif" alt="Page Setup (Alt+U)"></BUTTON></TD>
  2351. <TD class="UISeparator"><IMG width=0 height=0></TD>
  2352. <TD class="UIPane"> <BUTTON id="butFirstPage"><IMG id="begin" src="begin_inactive.gif" alt="First Page (Alt+Home)"></BUTTON></TD>
  2353. <TD class="UIPane"> <BUTTON id="butBackPage"> <IMG id="prev" src="prev_inactive.gif" alt="Previous Page (Alt+LeftArrow)"></BUTTON></TD>
  2354. <TD class="UIPane"><SPAN style="color:windowtext;"><NOBR Loc>&nbsp;<ID id=idTdPageXofYLocText1>P<U>a</U>ge</ID>&nbsp;<INPUT type=text id="inputPageNum" title="Preview Page (Alt+A)" value="1" style="height:1.5em; width: 2em; color:windowtext;" accesskey=a><ID id=idTdPageXofYLocText2> of </ID><SPAN id="spanPageTotal"></SPAN>
  2355. #ifdef DEBUG
  2356. <SPAN id="spanDebugHF" style="color: red"></SPAN>
  2357. #endif
  2358. &nbsp;</SPAN></NOBR></TD>
  2359. <TD class="UIPane"> <BUTTON id="butNextPage"> <IMG id="next" src="next_inactive.gif" alt="Next Page (Alt+RightArrow)"></BUTTON></TD>
  2360. <TD class="UIPane"> <BUTTON id="butLastPage"> <IMG id="end" src="end_inactive.gif" alt="Last Page (Alt+End)"></BUTTON></TD>
  2361. <TD class="UISeparator"><IMG width=0 height=0></TD>
  2362. <TD class="UIPane"> <BUTTON id="butZoomOut"> <IMG id="zoomOut" base="zoomOut" src="zoomout.gif" alt="Zoom Out (Alt+Minus)"></BUTTON></TD>
  2363. <TD class="UIPane"> <BUTTON id="butZoomIn"> <IMG id="zoomIn" base="zoomIn" src="zoomin.gif" alt="Zoom In (Alt+Plus)"></BUTTON></TD>
  2364. <TD class="UIPane"> <SELECT id="selectZoom" accesskey=z>
  2365. <OPTION VALUE="500" >500%
  2366. <OPTION VALUE="200" >200%
  2367. <OPTION VALUE="150" >150%
  2368. <OPTION VALUE="100" >100%
  2369. <OPTION VALUE="75" SELECTED >75%
  2370. <OPTION VALUE="50" >50%
  2371. <OPTION VALUE="25" >25%
  2372. <OPTION VALUE="10" >10%
  2373. <!-- ID's are for localization -->
  2374. <OPTION VALUE=STR_ZOOM_PAGE_WIDTH id="idPageWidth">Page Width</OPTION>
  2375. <OPTION VALUE=STR_ZOOM_WHOLE_PAGE id="idWholePage">Whole Page</OPTION>
  2376. <OPTION VALUE=STR_ZOOM_TWO_PAGES id="idTwoPages" >Two Pages </OPTION>
  2377. </SELECT></TD>
  2378. <TD class="UISeparator" id="separatorFrameset" style="display:none"><IMG width=0 height=0></TD>
  2379. <TD class="UIPane" id="cellFrameset" style="display:none"> <SELECT id="selectFrameset" accesskey=f>
  2380. <OPTION VALUE=STR_FRAMESET_LAID_OUT id="idLaidOut">As laid out on screen</OPTION>
  2381. <OPTION VALUE=STR_FRAMESET_SELECTED id="idSelected">Only the selected frame</OPTION>
  2382. <OPTION VALUE=STR_FRAMESET_SEPARATE id="idSeparate">All frames individually</OPTION>
  2383. </SELECT></TD>
  2384. <TD class="UISeparator"><IMG width=0 height=0></TD>
  2385. <TD class="UIPane"> <BUTTON id="butHelp" title="Print Preview Help (Alt+H)" accesskey=h><U>H</U>elp</BUTTON></TD>
  2386. <TD class="UISeparator"><IMG width=0 height=0></TD>
  2387. <TD class="UIPane"> <BUTTON id="butClose" title="Close Print Preview (Alt+C)" accessKey=c><U>C</U>lose</BUTTON></TD>
  2388. </TR></TABLE>
  2389. </DIV>
  2390. </DIV>
  2391. <DIV id=OverflowContainer onclick="this.focus();" onfocus="butPrint.scrollIntoView();" tabindex=1 style="position:absolute; left:0; width:100%; overflow:auto; border:'thin threedhighlight inset'; background:threedshadow;">
  2392. <DIV id=MasterContainer tabindex=0 style="width:100%; position:absolute;">
  2393. <!-- Pages go here -->
  2394. </DIV>
  2395. #ifdef DEBUG
  2396. <!-- Div used to log template events for debugging only. No need to localize! -->
  2397. <DIV id=LogContainer style="display:none; position:absolute; background:C0FFC0; top:0px; left:0px; height:100%; width:100%; overflow-y:scroll; overflow-x:auto;"></DIV>
  2398. #endif
  2399. </DIV>
  2400. </BODY>
  2401. </HTML>