document.getAnonymousElementByAttribute(this, "anonid", "cstack"); document.getAnonymousElementByAttribute(this, "anonid", "ccanvas"); return document.getAnonymousElementByAttribute(this, "anonid", "display-list"); null = 0) zoomDelta *= -1; this._zoomLevel = this._clampZoomLevel(this._zoomLevel + zoomDelta); this._browserToCanvas(); ]]> /** * Retrieve the content element for a given point (relative to the top * left corner of the browser window). */ var cdoc = this.browser.contentDocument; // Return the document width/height for XUL documents (which is // essentially the same as the viewport width/height). if (cdoc instanceof XULDocument) return [cdoc.width, cdoc.height]; // These might not exist yet depending on page load state var body = cdoc.body || {}; var html = cdoc.documentElement || {}; var w = Math.max(body.scrollWidth, html.scrollWidth); var h = Math.max(body.scrollHeight, html.scrollHeight); if (isNaN(w) || isNaN(h)) throw "Can't get content width/height"; return [w, h]; 0 /** * Given a set of page coordinates, constrain them such that they * fit within the rect defined by [0,0] and [x,y], where x and y are * the maximum values that can be used for the canvas' .top and .left * such that it is still within the scrollable area of the page, taking * into account the current zoomLevel. */ OVERPAN_LIMIT) this._fireOverpan = OVERPAN_RIGHT; } else { var newPageX = Math.min(this.dragData.pageX + aX, offscreenWidth); newPageX = Math.max(newPageX, 0); aX = newPageX - this.dragData.pageX; // Check for an overpan if (origX < -OVERPAN_LIMIT && aX <= 0 && newPageX == 0) this._fireOverpan = OVERPAN_LEFT; else if (origX > OVERPAN_LIMIT && aX >= 0 && (offscreenWidth - newPageX) == 0) this._fireOverpan = OVERPAN_RIGHT; } var offscreenHeight = contentAreaHeight - canvasH; if (offscreenHeight <= 0) { // Content is shorter than viewport, no need to pan vertically aY = 0; // Check for an overpan if (origY < -OVERPAN_LIMIT) this._fireOverpan = OVERPAN_TOP; else if (origY > OVERPAN_LIMIT) this._fireOverpan = OVERPAN_BOTTOM; } else { // min of 0, max of contentAreaHeight - canvasHeight var newPageY = Math.min(this.dragData.pageY + aY, offscreenHeight); newPageY = Math.max(newPageY, 0); aY = newPageY - this.dragData.pageY; // Check for an overpan if (origY < -OVERPAN_LIMIT && aY <= 0 && newPageY == 0) this._fireOverpan = OVERPAN_TOP; else if (origY > OVERPAN_LIMIT && aY >= 0 && (offscreenHeight - newPageY) == 0) this._fireOverpan = OVERPAN_BOTTOM; } return [aX, aY]; ]]> 0) { this.dragData.velocityX = -dx / dt; this.dragData.velocityY = -dy / dt; this.dragData.originalX = this.dragData.dragX; this.dragData.originalY = this.dragData.dragY; var [canvasWidth, canvasHeight] = this._effectiveCanvasDimensions; var [contentAreaWidth, contentAreaHeight] = this._contentAreaDimensions; let destX = Math.min(this.dragData.pageX - this.dragData.dragX + this.dragData.velocityX * 800, contentAreaWidth - canvasWidth); let destY = Math.min(this.dragData.pageY - this.dragData.dragY + this.dragData.velocityY * 800, contentAreaHeight - canvasHeight); destX = Math.max(destX, 0); destY = Math.max(destY, 0); this.dragData.destinationX = -destX + this.dragData.pageX; this.dragData.destinationY = -destY + this.dragData.pageY; this.dragData.kineticId = window.setInterval(this._doKinetic, dt / (this.PAN_EVENTS_TO_TRACK - 1), this, dt / (this.PAN_EVENTS_TO_TRACK - 1)); } else { this._endPan(); } } else { this._endPan() } ]]> nextX && nextX > self.dragData.destinationX) || (self.dragData.originalX < nextX && nextX < self.dragData.destinationX)) self.dragData.dragX = nextX; else self.dragData.dragX = self.dragData.destinationX; if((self.dragData.originalY > nextY && nextY > self.dragData.destinationY) || (self.dragData.originalY < nextY && nextY < self.dragData.destinationY)) self.dragData.dragY = nextY; else self.dragData.dragY = self.dragData.destinationY; self._updateCanvasPosition(); let actualDx = startX - self.dragData.dragX; let actualDy = startY - self.dragData.dragY if ((actualDx / (self.dragData.destinationX - self.dragData.originalX) < 0 && actualDy / (self.dragData.destinationY - self.dragData.originalY) < 0) || ( Math.abs(actualDx) < 4 && Math.abs(actualDy) < 4)) { self._endKinetic(); } ]]> 0) { var event = document.createEvent("UIEvents"); event.initUIEvent("overpan", true, false, window, this._fireOverpan); this.dispatchEvent(event); } this._fireOverpan = 0; ]]> 10 || Math.abs(this.deckbrowser.dragData.sY - aEvent.screenY) > 10)) { clearTimeout(this.deckbrowser._dragStartTimeout); this.deckbrowser._dragStartTimer(); } else { return false; } } var dx = this.deckbrowser.dragData.sX - aEvent.screenX; var dy = this.deckbrowser.dragData.sY - aEvent.screenY; // Filter out noise in big panning operations which are // almost certainly intended to be on-axis horizontal or // vertical pans. if (Math.abs(dx) > 40 || Math.abs(dy) > 40) { if (Math.abs(dx/dy) < 0.3) // dx is a lot less than dy, probably a vertical drag dx = 0; else if (Math.abs(dy/dx) < 0.3) // probably a horizontal drag dy = 0; } let now = Date.now(); if (this.deckbrowser.dragData.dragging) { this.deckbrowser._panEventTrackerIndex = (this.deckbrowser._panEventTrackerIndex + 1) % this.deckbrowser.PAN_EVENTS_TO_TRACK; var pt = new Object(); pt.x = aEvent.screenX; pt.y = aEvent.screenY; pt.t = now; this.deckbrowser._panEventTracker[this.deckbrowser._panEventTrackerIndex] = pt; } this.deckbrowser._moveCanvas(dx, dy); if (now - this.deckbrowser.dragData.lastMouseEvent < 75) { // FIXME: make this a constant //dump("dropping event\n"); return false; } this.deckbrowser.dragData.lastMouseEvent = now; aEvent.preventDefault(); return true; }, DOMMouseScroll: function seh_DOMMouseScroll(aEvent) { this.deckbrowser.zoom(aEvent.detail); }, dblclick: function seh_dblclick(aEvent) { var target = aEvent.originalTarget; var dragData = this.deckbrowser.dragData; if (this.deckbrowser._zoomed) { // reset zoom, pan state this.deckbrowser._zoomLevel = this._oldZoomLevel; [dragData.pageX, dragData.pageY] = [dragData.oldPageX, dragData.oldPageY]; this.deckbrowser._browserToCanvas(); this.deckbrowser._zoomed = false; } else { var element = this.deckbrowser.elementFromPoint(aEvent.clientX, aEvent.clientY); if (!element) { Components.utils.reportError("elementFromPoint returned null\n"); return; } // Find the nearest non-inline ancestor while (element.parentNode) { var display = window.getComputedStyle(element, "").getPropertyValue("display"); var zoomable = /table/.test(display) || /block/.test(display); if (zoomable) break; element = element.parentNode; } // Remember pageX/pageY [dragData.oldPageX, dragData.oldPageY] = [dragData.pageX, dragData.pageY]; this._oldZoomLevel = this.deckbrowser._zoomLevel; this.deckbrowser.zoomToElement(element); this.deckbrowser._zoomed = true; } } }); ]]>