home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 January / 01_02.iso / software / netscape62win / browser.xpi / bin / chrome / comm.jar / content / communicator / viewZoomOverlay.js < prev    next >
Encoding:
JavaScript  |  2001-08-29  |  9.0 KB  |  298 lines

  1. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  
  3.  * The contents of this file are subject to the Mozilla Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/MPL/
  7.  *
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  *
  13.  * The Original Code is this file as it was released upon
  14.  * January 6, 2001.
  15.  *
  16.  * The Initial Developer of the Original Code is Peter Annema.
  17.  * Portions created by Peter Annema are Copyright (C) 2000
  18.  * Peter Annema. All Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *   Peter Annema <disttsc@bart.nl> (Original Author)
  22.  *   Jonas Sicking <sicking@bigfoot.com>
  23.  *
  24.  * Alternatively, the contents of this file may be used under the
  25.  * terms of the GNU General Public License Version 2 or later (the
  26.  * "GPL"), in which case the provisions of the GPL are applicable
  27.  * instead of those above.  If you wish to allow use of your
  28.  * version of this file only under the terms of the GPL and not to
  29.  * allow others to use your version of this file under the MPL,
  30.  * indicate your decision by deleting the provisions above and
  31.  * replace them with the notice and other provisions required by
  32.  * the GPL.  If you do not delete the provisions above, a recipient
  33.  * may use your version of this file under either the MPL or the
  34.  * GPL.
  35.  */
  36.  
  37. /** Document Zoom Management Code
  38.  *
  39.  * To use this, you'll need to have a <menu id="menu_textZoom"/>
  40.  * and a getMarkupDocumentViewer() function which returns a
  41.  * nsIMarkupDocumentViewer.
  42.  *
  43.  **/
  44.  
  45. function ZoomManager() {
  46.   this.bundle = document.getElementById("bundle_viewZoom");
  47.  
  48.   // factorAnchor starts on factorOther
  49.   this.factorOther = parseInt(this.bundle.getString("valueOther"));
  50.   this.factorAnchor = this.factorOther;
  51. }
  52.  
  53. ZoomManager.prototype = {
  54.   instance : null,
  55.  
  56.   getInstance : function() {
  57.     if (!ZoomManager.prototype.instance)
  58.       ZoomManager.prototype.instance = new ZoomManager();
  59.  
  60.     return ZoomManager.prototype.instance;
  61.   },
  62.  
  63.   MIN : 1,
  64.   MAX : 2000,
  65.  
  66.   bundle : null,
  67.  
  68.   zoomFactorsString : "", // cache
  69.   zoomFactors : null,
  70.  
  71.   factorOther : 300,
  72.   factorAnchor : 300,
  73.   steps : 0,
  74.  
  75.   get textZoom() {
  76.     var currentZoom = Math.round(getMarkupDocumentViewer().textZoom * 100);
  77.     if (this.indexOf(currentZoom) == -1) {
  78.       if (currentZoom != this.factorOther) {
  79.         this.factorOther = currentZoom;
  80.         this.factorAnchor = this.factorOther;
  81.       }
  82.     }
  83.     return currentZoom;
  84.   },
  85.  
  86.   set textZoom(aZoom) {
  87.     if (aZoom < this.MIN || aZoom > this.MAX)
  88.       throw Components.results.NS_ERROR_INVALID_ARG;
  89.  
  90.     getMarkupDocumentViewer().textZoom = aZoom / 100;
  91.   },
  92.  
  93.   enlarge : function() {
  94.     this.jump(1);
  95.   },
  96.  
  97.   reduce : function() {
  98.     this.jump(-1);
  99.   },
  100.  
  101.   reset : function() {
  102.     this.textZoom = 100;
  103.   },
  104.  
  105.   getZoomFactors : function() {
  106.     this.ensureZoomFactors();
  107.  
  108.     return this.zoomFactors;
  109.   },
  110.  
  111.   indexOf : function(aZoom) {
  112.     this.ensureZoomFactors();
  113.  
  114.     var index = -1;
  115.     if (this.isZoomInRange(aZoom)) {
  116.       index = this.zoomFactors.length - 1;
  117.       while (index >= 0 && this.zoomFactors[index] != aZoom)
  118.         --index;
  119.     }
  120.  
  121.     return index;
  122.   },
  123.  
  124.   /***** internal helper functions below here *****/
  125.  
  126.   ensureZoomFactors : function() {
  127.     var zoomFactorsString = this.bundle.getString("values");
  128.     if (this.zoomFactorsString != zoomFactorsString) {
  129.       this.zoomFactorsString = zoomFactorsString;
  130.       this.zoomFactors = zoomFactorsString.split(",");
  131.       for (var i = 0; i<this.zoomFactors.length; ++i)
  132.         this.zoomFactors[i] = parseInt(this.zoomFactors[i]);
  133.     }
  134.   },
  135.  
  136.   isLevelInRange : function(aLevel) {
  137.     return (aLevel >= 0 && aLevel < this.zoomFactors.length);
  138.   },
  139.  
  140.   isZoomInRange : function(aZoom) {
  141.     return (aZoom >= this.zoomFactors[0] && aZoom <= this.zoomFactors[this.zoomFactors.length - 1]);
  142.   },
  143.  
  144.   jump : function(aDirection) {
  145.     if (aDirection != -1 && aDirection != 1)
  146.       throw Components.results.NS_ERROR_INVALID_ARG;
  147.  
  148.     this.ensureZoomFactors();
  149.  
  150.     var currentZoom = this.textZoom;
  151.     var insertIndex = -1;
  152.     var stepFactor = parseFloat(this.bundle.getString("stepFactor"));
  153.  
  154.     // temporarily add factorOther to list
  155.     if (this.isZoomInRange(this.factorOther)) {
  156.       insertIndex = 0;
  157.       while (this.zoomFactors[insertIndex] < this.factorOther)
  158.         ++insertIndex;
  159.  
  160.       if (this.zoomFactors[insertIndex] != this.factorOther)
  161.         this.zoomFactors.splice(insertIndex, 0, this.factorOther);
  162.     }
  163.  
  164.     var factor;
  165.     var done = false;
  166.  
  167.     if (this.isZoomInRange(currentZoom)) {
  168.       var index = this.indexOf(currentZoom);
  169.       if (aDirection == -1 && index == 0 ||
  170.           aDirection ==  1 && index == this.zoomFactors.length - 1) {
  171.         this.steps = 0;
  172.         this.factorAnchor = this.zoomFactors[index];
  173.       } else {
  174.         factor = this.zoomFactors[index + aDirection];
  175.         done = true;
  176.       }
  177.     }
  178.  
  179.     if (!done) {
  180.       this.steps += aDirection;
  181.       factor = this.factorAnchor * Math.pow(stepFactor, this.steps);
  182.       if (factor < this.MIN || factor > this.MAX) {
  183.         this.steps -= aDirection;
  184.         factor = this.factorAnchor * Math.pow(stepFactor, this.steps);
  185.       }
  186.       factor = Math.round(factor);
  187.       if (this.isZoomInRange(factor))
  188.         factor = this.snap(factor);
  189.       else
  190.         this.factorOther = factor;
  191.     }
  192.  
  193.     if (insertIndex != -1)
  194.       this.zoomFactors.splice(insertIndex, 1);
  195.  
  196.     this.textZoom = factor;
  197.   },
  198.  
  199.   snap : function(aZoom) {
  200.     if (this.isZoomInRange(aZoom)) {
  201.       var level = 0;
  202.       while (this.zoomFactors[level + 1] < aZoom)
  203.         ++level;
  204.  
  205.       // if aZoom closer to [level + 1] than [level], snap to [level + 1]
  206.       if ((this.zoomFactors[level + 1] - aZoom) < (aZoom - this.zoomFactors[level]))
  207.         ++level;
  208.  
  209.       aZoom = this.zoomFactors[level];
  210.     }
  211.  
  212.     return aZoom;
  213.   }
  214. }
  215.  
  216. /***** init and helper functions for viewZoomOverlay.xul *****/
  217.  
  218. window.addEventListener("load", registerZoomManager, false);
  219.  
  220. function registerZoomManager()
  221. {
  222.   var textZoomMenu = document.getElementById("menu_textZoom");
  223.   if (textZoomMenu) {
  224.     var zoom = ZoomManager.prototype.getInstance();
  225.  
  226.     textZoomMenu.removeAttribute("hidden");
  227.  
  228.     var parentMenu = textZoomMenu.parentNode;
  229.     parentMenu.addEventListener("popupshowing", updateViewMenu, false);
  230.  
  231.     var insertBefore = document.getElementById("menu_textZoomInsertBefore");
  232.     var popup = insertBefore.parentNode;
  233.     var accessKeys = zoom.bundle.getString("accessKeys").split(",");
  234.     var zoomFactors = zoom.getZoomFactors();
  235.     for (var i = 0; i < zoomFactors.length; ++i) {
  236.       var menuItem = document.createElement("menuitem");
  237.       menuItem.setAttribute("type", "radio");
  238.       menuItem.setAttribute("name", "textZoom");
  239.  
  240.       var label;
  241.       if (zoomFactors[i] == 100)
  242.         label = zoom.bundle.getString("labelOriginal");
  243.       else
  244.         label = zoom.bundle.getString("label");
  245.  
  246.       menuItem.setAttribute("label", label.replace(/%zoom%/, zoomFactors[i]));
  247.       menuItem.setAttribute("accesskey", accessKeys[i]);
  248.       menuItem.setAttribute("oncommand", "ZoomManager.prototype.getInstance().textZoom = this.value;");
  249.       menuItem.setAttribute("value", zoomFactors[i]);
  250.       popup.insertBefore(menuItem, insertBefore);
  251.     }
  252.   }
  253. }
  254.  
  255. function updateViewMenu()
  256. {
  257.   var zoom = ZoomManager.prototype.getInstance();
  258.  
  259.   var textZoomMenu = document.getElementById("menu_textZoom");
  260.   var menuLabel = zoom.bundle.getString("menuLabel").replace(/%zoom%/, zoom.textZoom);
  261.   textZoomMenu.setAttribute("label", menuLabel);
  262. }
  263.  
  264. function updateTextZoomMenu()
  265. {
  266.   var zoom = ZoomManager.prototype.getInstance();
  267.  
  268.   var currentZoom = zoom.textZoom;
  269.  
  270.   var textZoomOther = document.getElementById("menu_textZoomOther");
  271.   var label = zoom.bundle.getString("labelOther");
  272.   textZoomOther.setAttribute("label", label.replace(/%zoom%/, zoom.factorOther));
  273.   textZoomOther.setAttribute("value", zoom.factorOther);
  274.  
  275.   var popup = document.getElementById("menu_textZoomPopup");
  276.   var item = popup.firstChild;
  277.   while (item) {
  278.     if (item.getAttribute("name") == "textZoom") {
  279.       if (item.getAttribute("value") == currentZoom)
  280.         item.setAttribute("checked","true");
  281.       else
  282.         item.removeAttribute("checked");
  283.     }
  284.     item = item.nextSibling;
  285.   }
  286. }
  287.  
  288. function setTextZoomOther()
  289. {
  290.   var zoom = ZoomManager.prototype.getInstance();
  291.  
  292.   // open dialog and ask for new value
  293.   var o = {value: zoom.factorOther, zoomMin: zoom.MIN, zoomMax: zoom.MAX};
  294.   window.openDialog("chrome://communicator/content/askViewZoom.xul", "AskViewZoom", "chrome,modal,titlebar", o);
  295.   if (o.zoomOK)
  296.     zoom.textZoom = o.value;
  297. }
  298.