%PDF- %PDF-
Direktori : /home/riacommer/public_html/admin/vendor/wysihtml5/src/ |
Current File : /home/riacommer/public_html/admin/vendor/wysihtml5/src/browser.js |
/** * Detect browser support for specific features */ wysihtml5.browser = (function() { var userAgent = navigator.userAgent, testElement = document.createElement("div"), // Browser sniffing is unfortunately needed since some behaviors are impossible to feature detect isIE = userAgent.indexOf("MSIE") !== -1 && userAgent.indexOf("Opera") === -1, isGecko = userAgent.indexOf("Gecko") !== -1 && userAgent.indexOf("KHTML") === -1, isWebKit = userAgent.indexOf("AppleWebKit/") !== -1, isChrome = userAgent.indexOf("Chrome/") !== -1, isOpera = userAgent.indexOf("Opera/") !== -1; function iosVersion(userAgent) { return ((/ipad|iphone|ipod/.test(userAgent) && userAgent.match(/ os (\d+).+? like mac os x/)) || [, 0])[1]; } return { // Static variable needed, publicly accessible, to be able override it in unit tests USER_AGENT: userAgent, /** * Exclude browsers that are not capable of displaying and handling * contentEditable as desired: * - iPhone, iPad (tested iOS 4.2.2) and Android (tested 2.2) refuse to make contentEditables focusable * - IE < 8 create invalid markup and crash randomly from time to time * * @return {Boolean} */ supported: function() { var userAgent = this.USER_AGENT.toLowerCase(), // Essential for making html elements editable hasContentEditableSupport = "contentEditable" in testElement, // Following methods are needed in order to interact with the contentEditable area hasEditingApiSupport = document.execCommand && document.queryCommandSupported && document.queryCommandState, // document selector apis are only supported by IE 8+, Safari 4+, Chrome and Firefox 3.5+ hasQuerySelectorSupport = document.querySelector && document.querySelectorAll, // contentEditable is unusable in mobile browsers (tested iOS 4.2.2, Android 2.2, Opera Mobile, WebOS 3.05) isIncompatibleMobileBrowser = (this.isIos() && iosVersion(userAgent) < 5) || userAgent.indexOf("opera mobi") !== -1 || userAgent.indexOf("hpwos/") !== -1; return hasContentEditableSupport && hasEditingApiSupport && hasQuerySelectorSupport && !isIncompatibleMobileBrowser; }, isTouchDevice: function() { return this.supportsEvent("touchmove"); }, isIos: function() { var userAgent = this.USER_AGENT.toLowerCase(); return userAgent.indexOf("webkit") !== -1 && userAgent.indexOf("mobile") !== -1; }, /** * Whether the browser supports sandboxed iframes * Currently only IE 6+ offers such feature <iframe security="restricted"> * * http://msdn.microsoft.com/en-us/library/ms534622(v=vs.85).aspx * http://blogs.msdn.com/b/ie/archive/2008/01/18/using-frames-more-securely.aspx * * HTML5 sandboxed iframes are still buggy and their DOM is not reachable from the outside (except when using postMessage) */ supportsSandboxedIframes: function() { return isIE; }, /** * IE6+7 throw a mixed content warning when the src of an iframe * is empty/unset or about:blank * window.querySelector is implemented as of IE8 */ throwsMixedContentWarningWhenIframeSrcIsEmpty: function() { return !("querySelector" in document); }, /** * Whether the caret is correctly displayed in contentEditable elements * Firefox sometimes shows a huge caret in the beginning after focusing */ displaysCaretInEmptyContentEditableCorrectly: function() { return !isGecko; }, /** * Opera and IE are the only browsers who offer the css value * in the original unit, thx to the currentStyle object * All other browsers provide the computed style in px via window.getComputedStyle */ hasCurrentStyleProperty: function() { return "currentStyle" in testElement; }, /** * Whether the browser inserts a <br> when pressing enter in a contentEditable element */ insertsLineBreaksOnReturn: function() { return isGecko; }, supportsPlaceholderAttributeOn: function(element) { return "placeholder" in element; }, supportsEvent: function(eventName) { return "on" + eventName in testElement || (function() { testElement.setAttribute("on" + eventName, "return;"); return typeof(testElement["on" + eventName]) === "function"; })(); }, /** * Opera doesn't correctly fire focus/blur events when clicking in- and outside of iframe */ supportsEventsInIframeCorrectly: function() { return !isOpera; }, /** * Chrome & Safari only fire the ondrop/ondragend/... events when the ondragover event is cancelled * with event.preventDefault * Firefox 3.6 fires those events anyway, but the mozilla doc says that the dragover/dragenter event needs * to be cancelled */ firesOnDropOnlyWhenOnDragOverIsCancelled: function() { return isWebKit || isGecko; }, /** * Whether the browser supports the event.dataTransfer property in a proper way */ supportsDataTransfer: function() { try { // Firefox doesn't support dataTransfer in a safe way, it doesn't strip script code in the html payload (like Chrome does) return isWebKit && (window.Clipboard || window.DataTransfer).prototype.getData; } catch(e) { return false; } }, /** * Everything below IE9 doesn't know how to treat HTML5 tags * * @param {Object} context The document object on which to check HTML5 support * * @example * wysihtml5.browser.supportsHTML5Tags(document); */ supportsHTML5Tags: function(context) { var element = context.createElement("div"), html5 = "<article>foo</article>"; element.innerHTML = html5; return element.innerHTML.toLowerCase() === html5; }, /** * Checks whether a document supports a certain queryCommand * In particular, Opera needs a reference to a document that has a contentEditable in it's dom tree * in oder to report correct results * * @param {Object} doc Document object on which to check for a query command * @param {String} command The query command to check for * @return {Boolean} * * @example * wysihtml5.browser.supportsCommand(document, "bold"); */ supportsCommand: (function() { // Following commands are supported but contain bugs in some browsers var buggyCommands = { // formatBlock fails with some tags (eg. <blockquote>) "formatBlock": isIE, // When inserting unordered or ordered lists in Firefox, Chrome or Safari, the current selection or line gets // converted into a list (<ul><li>...</li></ul>, <ol><li>...</li></ol>) // IE and Opera act a bit different here as they convert the entire content of the current block element into a list "insertUnorderedList": isIE || isOpera || isWebKit, "insertOrderedList": isIE || isOpera || isWebKit }; // Firefox throws errors for queryCommandSupported, so we have to build up our own object of supported commands var supported = { "insertHTML": isGecko }; return function(doc, command) { var isBuggy = buggyCommands[command]; if (!isBuggy) { // Firefox throws errors when invoking queryCommandSupported or queryCommandEnabled try { return doc.queryCommandSupported(command); } catch(e1) {} try { return doc.queryCommandEnabled(command); } catch(e2) { return !!supported[command]; } } return false; }; })(), /** * IE: URLs starting with: * www., http://, https://, ftp://, gopher://, mailto:, new:, snews:, telnet:, wasis:, file://, * nntp://, newsrc:, ldap://, ldaps://, outlook:, mic:// and url: * will automatically be auto-linked when either the user inserts them via copy&paste or presses the * space bar when the caret is directly after such an url. * This behavior cannot easily be avoided in IE < 9 since the logic is hardcoded in the mshtml.dll * (related blog post on msdn * http://blogs.msdn.com/b/ieinternals/archive/2009/09/17/prevent-automatic-hyperlinking-in-contenteditable-html.aspx). */ doesAutoLinkingInContentEditable: function() { return isIE; }, /** * As stated above, IE auto links urls typed into contentEditable elements * Since IE9 it's possible to prevent this behavior */ canDisableAutoLinking: function() { return this.supportsCommand(document, "AutoUrlDetect"); }, /** * IE leaves an empty paragraph in the contentEditable element after clearing it * Chrome/Safari sometimes an empty <div> */ clearsContentEditableCorrectly: function() { return isGecko || isOpera || isWebKit; }, /** * IE gives wrong results for getAttribute */ supportsGetAttributeCorrectly: function() { var td = document.createElement("td"); return td.getAttribute("rowspan") != "1"; }, /** * When clicking on images in IE, Opera and Firefox, they are selected, which makes it easy to interact with them. * Chrome and Safari both don't support this */ canSelectImagesInContentEditable: function() { return isGecko || isIE || isOpera; }, /** * When the caret is in an empty list (<ul><li>|</li></ul>) which is the first child in an contentEditable container * pressing backspace doesn't remove the entire list as done in other browsers */ clearsListsInContentEditableCorrectly: function() { return isGecko || isIE || isWebKit; }, /** * All browsers except Safari and Chrome automatically scroll the range/caret position into view */ autoScrollsToCaret: function() { return !isWebKit; }, /** * Check whether the browser automatically closes tags that don't need to be opened */ autoClosesUnclosedTags: function() { var clonedTestElement = testElement.cloneNode(false), returnValue, innerHTML; clonedTestElement.innerHTML = "<p><div></div>"; innerHTML = clonedTestElement.innerHTML.toLowerCase(); returnValue = innerHTML === "<p></p><div></div>" || innerHTML === "<p><div></div></p>"; // Cache result by overwriting current function this.autoClosesUnclosedTags = function() { return returnValue; }; return returnValue; }, /** * Whether the browser supports the native document.getElementsByClassName which returns live NodeLists */ supportsNativeGetElementsByClassName: function() { return String(document.getElementsByClassName).indexOf("[native code]") !== -1; }, /** * As of now (19.04.2011) only supported by Firefox 4 and Chrome * See https://developer.mozilla.org/en/DOM/Selection/modify */ supportsSelectionModify: function() { return "getSelection" in window && "modify" in window.getSelection(); }, /** * Whether the browser supports the classList object for fast className manipulation * See https://developer.mozilla.org/en/DOM/element.classList */ supportsClassList: function() { return "classList" in testElement; }, /** * Opera needs a white space after a <br> in order to position the caret correctly */ needsSpaceAfterLineBreak: function() { return isOpera; }, /** * Whether the browser supports the speech api on the given element * See http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/ * * @example * var input = document.createElement("input"); * if (wysihtml5.browser.supportsSpeechApiOn(input)) { * // ... * } */ supportsSpeechApiOn: function(input) { var chromeVersion = userAgent.match(/Chrome\/(\d+)/) || [, 0]; return chromeVersion[1] >= 11 && ("onwebkitspeechchange" in input || "speech" in input); }, /** * IE9 crashes when setting a getter via Object.defineProperty on XMLHttpRequest or XDomainRequest * See https://connect.microsoft.com/ie/feedback/details/650112 * or try the POC http://tifftiff.de/ie9_crash/ */ crashesWhenDefineProperty: function(property) { return isIE && (property === "XMLHttpRequest" || property === "XDomainRequest"); }, /** * IE is the only browser who fires the "focus" event not immediately when .focus() is called on an element */ doesAsyncFocus: function() { return isIE; }, /** * In IE it's impssible for the user and for the selection library to set the caret after an <img> when it's the lastChild in the document */ hasProblemsSettingCaretAfterImg: function() { return isIE; }, hasUndoInContextMenu: function() { return isGecko || isChrome || isOpera; } }; })();