Path: blob/trunk/third_party/closure/goog/dom/browserrange/browserrange.js
2868 views
// Copyright 2007 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Definition of the browser range namespace and interface, as16* well as several useful utility functions.17*18* DO NOT USE THIS FILE DIRECTLY. Use goog.dom.Range instead.19*20* @author [email protected] (Robby Walker)21*/222324goog.provide('goog.dom.browserrange');25goog.provide('goog.dom.browserrange.Error');2627goog.require('goog.dom');28goog.require('goog.dom.BrowserFeature');29goog.require('goog.dom.NodeType');30goog.require('goog.dom.browserrange.GeckoRange');31goog.require('goog.dom.browserrange.IeRange');32goog.require('goog.dom.browserrange.OperaRange');33goog.require('goog.dom.browserrange.W3cRange');34goog.require('goog.dom.browserrange.WebKitRange');35goog.require('goog.userAgent');363738/**39* Common error constants.40* @enum {string}41*/42goog.dom.browserrange.Error = {43NOT_IMPLEMENTED: 'Not Implemented'44};454647// NOTE(robbyw): While it would be nice to eliminate the duplicate switches48// below, doing so uncovers bugs in the JsCompiler in which49// necessary code is stripped out.505152/**53* Static method that returns the proper type of browser range.54* @param {Range|TextRange} range A browser range object.55* @return {!goog.dom.browserrange.AbstractRange} A wrapper object.56*/57goog.dom.browserrange.createRange = function(range) {58if (goog.dom.BrowserFeature.LEGACY_IE_RANGES) {59return new goog.dom.browserrange.IeRange(60/** @type {TextRange} */ (range),61goog.dom.getOwnerDocument(range.parentElement()));62} else if (goog.userAgent.WEBKIT) {63return new goog.dom.browserrange.WebKitRange(64/** @type {Range} */ (range));65} else if (goog.userAgent.GECKO) {66return new goog.dom.browserrange.GeckoRange(67/** @type {Range} */ (range));68} else if (goog.userAgent.OPERA) {69return new goog.dom.browserrange.OperaRange(70/** @type {Range} */ (range));71} else {72// Default other browsers, including Opera, to W3c ranges.73return new goog.dom.browserrange.W3cRange(74/** @type {Range} */ (range));75}76};777879/**80* Static method that returns the proper type of browser range.81* @param {Node} node The node to select.82* @return {!goog.dom.browserrange.AbstractRange} A wrapper object.83*/84goog.dom.browserrange.createRangeFromNodeContents = function(node) {85if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {86return goog.dom.browserrange.IeRange.createFromNodeContents(node);87} else if (goog.userAgent.WEBKIT) {88return goog.dom.browserrange.WebKitRange.createFromNodeContents(node);89} else if (goog.userAgent.GECKO) {90return goog.dom.browserrange.GeckoRange.createFromNodeContents(node);91} else if (goog.userAgent.OPERA) {92return goog.dom.browserrange.OperaRange.createFromNodeContents(node);93} else {94// Default other browsers to W3c ranges.95return goog.dom.browserrange.W3cRange.createFromNodeContents(node);96}97};9899100/**101* Static method that returns the proper type of browser range.102* @param {Node} startNode The node to start with.103* @param {number} startOffset The offset within the node to start. This is104* either the index into the childNodes array for element startNodes or105* the index into the character array for text startNodes.106* @param {Node} endNode The node to end with.107* @param {number} endOffset The offset within the node to end. This is108* either the index into the childNodes array for element endNodes or109* the index into the character array for text endNodes.110* @return {!goog.dom.browserrange.AbstractRange} A wrapper object.111*/112goog.dom.browserrange.createRangeFromNodes = function(113startNode, startOffset, endNode, endOffset) {114if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {115return goog.dom.browserrange.IeRange.createFromNodes(116startNode, startOffset, endNode, endOffset);117} else if (goog.userAgent.WEBKIT) {118return goog.dom.browserrange.WebKitRange.createFromNodes(119startNode, startOffset, endNode, endOffset);120} else if (goog.userAgent.GECKO) {121return goog.dom.browserrange.GeckoRange.createFromNodes(122startNode, startOffset, endNode, endOffset);123} else if (goog.userAgent.OPERA) {124return goog.dom.browserrange.OperaRange.createFromNodes(125startNode, startOffset, endNode, endOffset);126} else {127// Default other browsers to W3c ranges.128return goog.dom.browserrange.W3cRange.createFromNodes(129startNode, startOffset, endNode, endOffset);130}131};132133134/**135* Tests whether the given node can contain a range end point.136* @param {Node} node The node to check.137* @return {boolean} Whether the given node can contain a range end point.138*/139goog.dom.browserrange.canContainRangeEndpoint = function(node) {140// NOTE(user, bloom): This is not complete, as divs with style -141// 'display:inline-block' or 'position:absolute' can also not contain range142// endpoints. A more complete check is to see if that element can be partially143// selected (can be container) or not.144return goog.dom.canHaveChildren(node) ||145node.nodeType == goog.dom.NodeType.TEXT;146};147148149