Path: blob/trunk/third_party/closure/goog/editor/browserfeature.js
2868 views
// Copyright 2005 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 Trogedit constants for browser features and quirks that should16* be used by the rich text editor.17*/1819goog.provide('goog.editor.BrowserFeature');2021goog.require('goog.editor.defines');22goog.require('goog.labs.userAgent.browser');23goog.require('goog.userAgent');24goog.require('goog.userAgent.product');25goog.require('goog.userAgent.product.isVersion');262728/**29* Maps browser quirks to boolean values, detailing what the current30* browser supports.31* @const32*/33goog.editor.BrowserFeature = {34// Whether this browser uses the IE TextRange object.35HAS_IE_RANGES: goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9),3637// Whether this browser uses the W3C standard Range object.38// Assumes IE higher versions will be compliance with W3C standard.39HAS_W3C_RANGES: goog.userAgent.GECKO || goog.userAgent.WEBKIT ||40goog.userAgent.OPERA || goog.userAgent.EDGE ||41(goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(9)),4243// Has the contentEditable attribute, which makes nodes editable.44//45// NOTE(nicksantos): FF3 has contentEditable, but there are 3 major reasons46// why we don't use it:47// 1) In FF3, we listen for key events on the document, and we'd have to48// filter them properly. See TR_Browser.USE_DOCUMENT_FOR_KEY_EVENTS.49// 2) In FF3, we listen for focus/blur events on the document, which50// simply doesn't make sense in contentEditable. focus/blur51// on contentEditable elements still has some quirks, which we're52// talking to Firefox-team about.53// 3) We currently use Mutation events in FF3 to detect changes,54// and these are dispatched on the document only.55// If we ever hope to support FF3/contentEditable, all 3 of these issues56// will need answers. Most just involve refactoring at our end.57HAS_CONTENT_EDITABLE: goog.userAgent.IE || goog.userAgent.WEBKIT ||58goog.userAgent.OPERA || goog.userAgent.EDGE ||59(goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3 &&60goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9')),6162// Whether to use mutation event types to detect changes63// in the field contents.64USE_MUTATION_EVENTS: goog.userAgent.GECKO,6566// Whether the browser has a functional DOMSubtreeModified event.67// TODO(user): Enable for all FF3 once we're confident this event fires68// reliably. Currently it's only enabled if using contentEditable in FF as69// we have no other choice in that case but to use this event.70HAS_DOM_SUBTREE_MODIFIED_EVENT: goog.userAgent.WEBKIT ||71(goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3 &&72goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9')),7374// Whether nodes can be copied from one document to another75HAS_DOCUMENT_INDEPENDENT_NODES: goog.userAgent.GECKO,7677// Whether the cursor goes before or inside the first block element on78// focus, e.g., <body><p>foo</p></body>. FF will put the cursor before the79// paragraph on focus, which is wrong.80PUTS_CURSOR_BEFORE_FIRST_BLOCK_ELEMENT_ON_FOCUS: goog.userAgent.GECKO,8182// Whether the selection of one frame is cleared when another frame83// is focused.84CLEARS_SELECTION_WHEN_FOCUS_LEAVES:85goog.userAgent.IE || goog.userAgent.WEBKIT || goog.userAgent.OPERA,8687// Whether "unselectable" is supported as an element style.88HAS_UNSELECTABLE_STYLE: goog.userAgent.GECKO || goog.userAgent.WEBKIT,8990// Whether this browser's "FormatBlock" command does not suck.91FORMAT_BLOCK_WORKS_FOR_BLOCKQUOTES:92goog.userAgent.GECKO || goog.userAgent.WEBKIT || goog.userAgent.OPERA,9394// Whether this browser's "FormatBlock" command may create multiple95// blockquotes.96CREATES_MULTIPLE_BLOCKQUOTES:97(goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('534.16')) ||98goog.userAgent.OPERA,99100// Whether this browser's "FormatBlock" command will wrap blockquotes101// inside of divs, instead of replacing divs with blockquotes.102WRAPS_BLOCKQUOTE_IN_DIVS: goog.userAgent.OPERA,103104// Whether the readystatechange event is more reliable than load.105PREFERS_READY_STATE_CHANGE_EVENT: goog.userAgent.IE,106107// Whether hitting the tab key will fire a keypress event.108// see http://www.quirksmode.org/js/keys.html109// TODO(user): This is fixed in IE8 and higher.110TAB_FIRES_KEYPRESS: !goog.userAgent.IE,111112// Has a standards mode quirk where width=100% doesn't do the right thing,113// but width=99% does.114// TODO(user|user): This should be fixable by less hacky means115NEEDS_99_WIDTH_IN_STANDARDS_MODE: goog.userAgent.IE,116117// Whether keyboard events only reliably fire on the document.118// On Gecko without contentEditable, keyboard events only fire reliably on the119// document element. With contentEditable, the field itself is focusable,120// which means that it will fire key events. This does not apply if121// application is using ContentEditableField or otherwise overriding Field122// not to use an iframe.123USE_DOCUMENT_FOR_KEY_EVENTS: goog.userAgent.GECKO &&124!goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3,125126// Whether this browser shows non-standard attributes in innerHTML.127SHOWS_CUSTOM_ATTRS_IN_INNER_HTML: goog.userAgent.IE,128129// Whether this browser shrinks empty nodes away to nothing.130// (If so, we need to insert some space characters into nodes that131// shouldn't be collapsed)132COLLAPSES_EMPTY_NODES:133goog.userAgent.GECKO || goog.userAgent.WEBKIT || goog.userAgent.OPERA,134135// Whether we must convert <strong> and <em> tags to <b>, <i>.136CONVERT_TO_B_AND_I_TAGS: goog.userAgent.GECKO || goog.userAgent.OPERA,137138// Whether this browser likes to tab through images in contentEditable mode,139// and we like to disable this feature.140TABS_THROUGH_IMAGES: goog.userAgent.IE,141142// Whether this browser unescapes urls when you extract it from the href tag.143UNESCAPES_URLS_WITHOUT_ASKING:144goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('7.0'),145146// Whether this browser supports execCommand("styleWithCSS") to toggle between147// inserting html tags or inline styling for things like bold, italic, etc.148HAS_STYLE_WITH_CSS:149goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.8') ||150goog.userAgent.WEBKIT || goog.userAgent.OPERA,151152// Whether clicking on an editable link will take you to that site.153FOLLOWS_EDITABLE_LINKS: goog.userAgent.WEBKIT ||154goog.userAgent.IE && goog.userAgent.isVersionOrHigher('9'),155156// Whether this browser has document.activeElement available.157HAS_ACTIVE_ELEMENT: goog.userAgent.IE || goog.userAgent.EDGE ||158goog.userAgent.OPERA ||159goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9'),160161// Whether this browser supports the setCapture method on DOM elements.162HAS_SET_CAPTURE: goog.userAgent.IE,163164// Whether this browser can't set background color when the selection165// is collapsed.166EATS_EMPTY_BACKGROUND_COLOR: goog.userAgent.GECKO ||167goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('527'),168169// Whether this browser supports the "focusin" or "DOMFocusIn" event170// consistently.171// NOTE(nicksantos): FF supports DOMFocusIn, but doesn't seem to do so172// consistently.173SUPPORTS_FOCUSIN: goog.userAgent.IE || goog.userAgent.OPERA,174175// Whether clicking on an image will cause the selection to move to the image.176// Note: Gecko moves the selection, but it won't always go to the image.177// For example, if the image is wrapped in a div, and you click on the img,178// anchorNode = focusNode = div, anchorOffset = 0, focusOffset = 1, so this179// is another way of "selecting" the image, but there are too many special180// cases like this so we will do the work manually.181SELECTS_IMAGES_ON_CLICK: goog.userAgent.IE || goog.userAgent.OPERA,182183// Whether this browser moves <style> tags into new <head> elements.184MOVES_STYLE_TO_HEAD: goog.userAgent.WEBKIT,185186// Whether this browser collapses the selection in a contenteditable when the187// mouse is pressed in a non-editable portion of the same frame, even if188// Event.preventDefault is called. This field is deprecated and unused -- only189// old versions of Opera have this bug.190COLLAPSES_SELECTION_ONMOUSEDOWN: false,191192// Whether the user can actually create a selection in this browser with the193// caret in the MIDDLE of the selection by double-clicking.194CARET_INSIDE_SELECTION: goog.userAgent.OPERA,195196// Whether the browser focuses <body contenteditable> automatically when197// the user clicks on <html>. This field is deprecated and unused -- only old198// versions of Opera don't have this behavior.199FOCUSES_EDITABLE_BODY_ON_HTML_CLICK: true,200201// Whether to use keydown for key listening (uses keypress otherwise). Taken202// from goog.events.KeyHandler.203USES_KEYDOWN: goog.userAgent.IE || goog.userAgent.EDGE ||204goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525'),205206// Whether this browser converts spaces to non-breaking spaces when calling207// execCommand's RemoveFormat.208// See: https://bugs.webkit.org/show_bug.cgi?id=14062209ADDS_NBSPS_IN_REMOVE_FORMAT:210goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('531'),211212// Whether the browser will get stuck inside a link. That is, if your cursor213// is after a link and you type, does your text go inside the link tag.214// Bug: http://bugs.webkit.org/show_bug.cgi?id=17697215GETS_STUCK_IN_LINKS:216goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('528'),217218// Whether the browser corrupts empty text nodes in Node#normalize,219// removing them from the Document instead of merging them.220NORMALIZE_CORRUPTS_EMPTY_TEXT_NODES:221goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9') ||222goog.userAgent.IE || goog.userAgent.EDGE || goog.userAgent.OPERA ||223goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('531'),224225// Whether the browser corrupts all text nodes in Node#normalize,226// removing them from the Document instead of merging them.227NORMALIZE_CORRUPTS_ALL_TEXT_NODES: goog.userAgent.IE,228229// Browsers where executing subscript then superscript (or vv) will cause both230// to be applied in a nested fashion instead of the first being overwritten by231// the second.232NESTS_SUBSCRIPT_SUPERSCRIPT: goog.userAgent.IE || goog.userAgent.EDGE ||233goog.userAgent.GECKO || goog.userAgent.OPERA,234235// Whether this browser can place a cursor in an empty element natively.236CAN_SELECT_EMPTY_ELEMENT: !goog.userAgent.IE && !goog.userAgent.WEBKIT,237238FORGETS_FORMATTING_WHEN_LISTIFYING: goog.userAgent.GECKO ||239goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('526'),240241LEAVES_P_WHEN_REMOVING_LISTS: goog.userAgent.IE || goog.userAgent.OPERA,242243CAN_LISTIFY_BR: !goog.userAgent.IE && !goog.userAgent.OPERA,244245// See bug 1286408. When somewhere inside your selection there is an element246// with a style attribute that sets the font size, if you change the font247// size, the browser creates a font tag, but the font size in the style attr248// overrides the font tag. Only webkit removes that font size from the style249// attr.250DOESNT_OVERRIDE_FONT_SIZE_IN_STYLE_ATTR:251!goog.userAgent.WEBKIT && !goog.userAgent.EDGE,252253// Implements this spec about dragging files from the filesystem to the254// browser: http://www.whatwg/org/specs/web-apps/current-work/#dnd255SUPPORTS_HTML5_FILE_DRAGGING: (goog.userAgent.product.CHROME &&256goog.userAgent.product.isVersion('4')) ||257(goog.userAgent.product.SAFARI &&258goog.userAgent.isVersionOrHigher('533')) ||259(goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('2.0')) ||260(goog.userAgent.IE && goog.userAgent.isVersionOrHigher('10')) ||261// TODO(user): Remove when b/27923889 is fixed.262(goog.userAgent.OPERA &&263goog.labs.userAgent.browser.isVersionOrHigher('15')) ||264goog.userAgent.EDGE,265266// Version of Opera that supports the opera-defaultBlock execCommand to change267// the default block inserted when [return] is pressed. Note that this only is268// used if the caret is not already in a block that can be repeated.269// TODO(user): Link to public documentation of this feature if Opera puts270// something up about it.271SUPPORTS_OPERA_DEFAULTBLOCK_COMMAND:272goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher('11.10'),273274SUPPORTS_FILE_PASTING:275goog.userAgent.product.CHROME && goog.userAgent.product.isVersion('12')276};277278279