From 8408d26cb8fdad49adcffbe7924f9064df59ff35 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Tue, 16 Dec 2014 10:58:52 -0800 Subject: [PATCH 1/2] index: rearrange require calls --- index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 2ec6b29..c3a4cda 100644 --- a/index.js +++ b/index.js @@ -2,15 +2,16 @@ * Module dependencies. */ +var css = require('css'); var bind = require('bind'); -var Emitter = require('emitter'); -var events = require('events'); var query = require('query'); var domify = require('domify'); +var events = require('events'); +var offset = require('offset'); +var Emitter = require('emitter'); var classes = require('classes'); -var css = require('css'); + var html = domify(require('./template.html')); -var offset = require('offset'); /** * Expose `Tip`. From b8b4361e0acd494460ea667ec4ec83453dad4808 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Tue, 16 Dec 2014 14:46:41 -0800 Subject: [PATCH 2/2] use "bounding-client-rect" module This gives a slight performance boost, since before we would potentially be calling `getBoundingClientRect()` twice. Now the TextRectangle is being re-used, and works with more types of Nodes. So now `component/tip` should be compatible with regular DOM Elements, TextNode instances and Ranges. --- component.json | 2 +- index.js | 62 +++++++++++++++++++++++--------------------------- package.json | 7 +++--- 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/component.json b/component.json index cfe6764..d0a21e9 100644 --- a/component.json +++ b/component.json @@ -17,7 +17,7 @@ "component/domify": "1.3.0", "component/classes": "1.2.1", "component/css": "0.0.6", - "timoxley/offset": "1.0.3" + "webmodules/bounding-client-rect": "1.0.1" }, "development": { "component/aurora-tip": "*", diff --git a/index.js b/index.js index c3a4cda..694f1ad 100644 --- a/index.js +++ b/index.js @@ -7,9 +7,9 @@ var bind = require('bind'); var query = require('query'); var domify = require('domify'); var events = require('events'); -var offset = require('offset'); var Emitter = require('emitter'); var classes = require('classes'); +var getBoundingClientRect = require('bounding-client-rect'); var html = domify(require('./template.html')); @@ -304,18 +304,18 @@ Tip.prototype.replaceClass = function(name){ Tip.prototype.offset = function(pos){ var pad = 15; - var tipDims = dimensions(this.el); - if (!tipDims) throw new Error('could not determine dimensions of Tip element'); - var ew = tipDims.width; - var eh = tipDims.height; + var tipRect = getBoundingClientRect(this.el); + if (!tipRect) throw new Error('could not get bounding client rect of Tip element'); + var ew = tipRect.width; + var eh = tipRect.height; - var to = offset(this.target); - if (!to) throw new Error('could not determine page offset of `target`'); + var targetRect = getBoundingClientRect(this.target); + if (!targetRect) throw new Error('could not get bounding client rect of `target`'); + var tw = targetRect.width; + var th = targetRect.height; - var dims = dimensions(this.target); - if (!dims) throw new Error('could not determine dimensions of `target`'); - var tw = dims.width; - var th = dims.height; + var to = offset(targetRect, document); + if (!to) throw new Error('could not determine page offset of `target`'); switch (pos) { case 'top': @@ -425,29 +425,25 @@ Tip.prototype.remove = function(){ }; /** - * Returns an Object with `width` and `height` values which represent the - * dimensions of the given `node` which could be a DOM Element, Range, etc. - * - * TODO: extract this into a standalone module + * Extracted from `timoxley/offset`, but directly using a + * TextRectangle instead of getting another version. * - * @private + * @param {TextRectangle} box - result from a `getBoundingClientRect()` call + * @param {Document} doc - Document instance to use + * @return {Object} an object with `top` and `left` Number properties + * @api private */ -function dimensions(node) { - var dims; - var ow = node.offsetWidth; - var oh = node.offsetHeight; - - // use `offsetWidth` and `offsetHeight` by default if available - if (ow != null && oh != null) { - dims = { width: ow, height: oh }; - } - - // fallback to `getBoundingClientRect()` if available - if ((!dims || (!dims.width && !dims.height)) && - 'function' == typeof node.getBoundingClientRect) { - dims = node.getBoundingClientRect(); - } - - return dims; +function offset (box, doc) { + var body = doc.body || doc.getElementsByTagName('body')[0]; + var docEl = doc.documentElement || body.parentNode; + var clientTop = docEl.clientTop || body.clientTop || 0; + var clientLeft = docEl.clientLeft || body.clientLeft || 0; + var scrollTop = window.pageYOffset || docEl.scrollTop; + var scrollLeft = window.pageXOffset || docEl.scrollLeft; + + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; } diff --git a/package.json b/package.json index 0474e81..9bd0cb7 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "ui" ], "dependencies": { + "bounding-client-rect": "1.0.1", "component-bind": "*", "component-classes": "1.2.1", "component-css": "0.0.6", @@ -17,8 +18,7 @@ "component-events": "1.0.9", "component-query": "0.0.3", "domify": "1.3.0", - "html-browserify": "0.0.4", - "document-offset": "1.0.3" + "html-browserify": "0.0.4" }, "browser": { "bind": "component-bind", @@ -26,8 +26,7 @@ "css": "component-css", "emitter": "component-emitter", "events": "component-events", - "query": "component-query", - "offset": "document-offset" + "query": "component-query" }, "browserify": { "transform": "html-browserify"