"use strict"; import {MyDocItem} from "../model/MyDocItem.js"; import {MyMapItem} from "../model/MyMapItem.js"; export class MyUtils { //todo 判断是哪一种浏览器类型。以及是否是手机 //todo 初始化屏幕宽高比 MyBrowser = null constructor() { /** * 提供浏览器检测的模块 * @unfile * @module UE.browser */ window.browser = ((function () { var agent = navigator.userAgent.toLowerCase(), opera = window.opera, browser = { /** * @property {boolean} ie 检测当前浏览器是否为IE * @example * ```javascript * if ( UE.browser.ie ) { * console.log( '当前浏览器是IE' ); * } * ``` */ ie: /(msie\s|trident.*rv:)([\w.]+)/i.test(agent), /** * @property {boolean} opera 检测当前浏览器是否为Opera * @example * ```javascript * if ( UE.browser.opera ) { * console.log( '当前浏览器是Opera' ); * } * ``` */ opera: !!opera && opera.version, /** * @property {boolean} webkit 检测当前浏览器是否是webkit内核的浏览器 * @example * ```javascript * if ( UE.browser.webkit ) { * console.log( '当前浏览器是webkit内核浏览器' ); * } * ``` */ webkit: agent.indexOf(" applewebkit/") > -1, /** * @property {boolean} mac 检测当前浏览器是否是运行在mac平台下 * @example * ```javascript * if ( UE.browser.mac ) { * console.log( '当前浏览器运行在mac平台下' ); * } * ``` */ mac: agent.indexOf("macintosh") > -1, /** * @property {boolean} quirks 检测当前浏览器是否处于“怪异模式”下 * @example * ```javascript * if ( UE.browser.quirks ) { * console.log( '当前浏览器运行处于“怪异模式”' ); * } * ``` */ quirks: document.compatMode == "BackCompat" } /** * @property {boolean} gecko 检测当前浏览器内核是否是gecko内核 * @example * ```javascript * if ( UE.browser.gecko ) { * console.log( '当前浏览器内核是gecko内核' ); * } * ``` */ browser.gecko = navigator.product == "Gecko" && !browser.webkit && !browser.opera && !browser.ie var version = 0 // Internet Explorer 6.0+ if (browser.ie) { var v1 = agent.match(/(?:msie\s([\w.]+))/) var v2 = agent.match(/(?:trident.*rv:([\w.]+))/) if (v1 && v2 && v1[1] && v2[1]) { version = Math.max(v1[1] * 1, v2[1] * 1) } else if (v1 && v1[1]) { version = v1[1] * 1 } else if (v2 && v2[1]) { version = v2[1] * 1 } else { version = 0 } browser.ie11Compat = document.documentMode == 11 /** * @property { boolean } ie9Compat 检测浏览器模式是否为 IE9 兼容模式 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie9Compat ) { * console.log( '当前浏览器运行在IE9兼容模式下' ); * } * ``` */ browser.ie9Compat = document.documentMode == 9 /** * @property { boolean } ie8 检测浏览器是否是IE8浏览器 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie8 ) { * console.log( '当前浏览器是IE8浏览器' ); * } * ``` */ browser.ie8 = !!document.documentMode /** * @property { boolean } ie8Compat 检测浏览器模式是否为 IE8 兼容模式 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie8Compat ) { * console.log( '当前浏览器运行在IE8兼容模式下' ); * } * ``` */ browser.ie8Compat = document.documentMode == 8 /** * @property { boolean } ie7Compat 检测浏览器模式是否为 IE7 兼容模式 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie7Compat ) { * console.log( '当前浏览器运行在IE7兼容模式下' ); * } * ``` */ browser.ie7Compat = (version == 7 && !document.documentMode) || document.documentMode == 7 /** * @property { boolean } ie6Compat 检测浏览器模式是否为 IE6 模式 或者怪异模式 * @warning 如果浏览器不是IE, 则该值为undefined * @example * ```javascript * if ( UE.browser.ie6Compat ) { * console.log( '当前浏览器运行在IE6模式或者怪异模式下' ); * } * ``` */ browser.ie6Compat = version < 7 || browser.quirks browser.ie9above = version > 8 browser.ie9below = version < 9 browser.ie11above = version > 10 browser.ie11below = version < 11 } // Gecko. if (browser.gecko) { var geckoRelease = agent.match(/rv:([\d\.]+)/) if (geckoRelease) { geckoRelease = geckoRelease[1].split(".") version = geckoRelease[0] * 10000 + (geckoRelease[1] || 0) * 100 + (geckoRelease[2] || 0) * 1 } } /** * @property { Number } chrome 检测当前浏览器是否为Chrome, 如果是,则返回Chrome的大版本号 * @warning 如果浏览器不是chrome, 则该值为undefined * @example * ```javascript * if ( UE.browser.chrome ) { * console.log( '当前浏览器是Chrome' ); * } * ``` */ if (/chrome\/(\d+\.\d)/i.test(agent)) { browser.chrome = +RegExp["\x241"] } /** * @property { Number } safari 检测当前浏览器是否为Safari, 如果是,则返回Safari的大版本号 * @warning 如果浏览器不是safari, 则该值为undefined * @example * ```javascript * if ( UE.browser.safari ) { * console.log( '当前浏览器是Safari' ); * } * ``` */ if ( /(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent) ) { browser.safari = +(RegExp["\x241"] || RegExp["\x242"]) } // Opera 9.50+ if (browser.opera) version = parseFloat(opera.version()) // WebKit 522+ (Safari 3+) if (browser.webkit) version = parseFloat(agent.match(/ applewebkit\/(\d+)/)[1]) /** * @property { Number } version 检测当前浏览器版本号 * @remind * * @example * ```javascript * console.log( '当前浏览器版本号是: ' + UE.browser.version ); * ``` */ browser.version = version /** * @property { boolean } isCompatible 检测当前浏览器是否能够与UEditor良好兼容 * @example * ```javascript * if ( UE.browser.isCompatible ) { * console.log( '浏览器与UEditor能够良好兼容' ); * } * ``` */ browser.isCompatible = !browser.mobile && ((browser.ie && version >= 6) || (browser.gecko && version >= 10801) || (browser.opera && version >= 9.5) || (browser.air && version >= 1) || (browser.webkit && version >= 522) || false) return browser })()) //快捷方式 window.ie = window.browser.ie; window.webkit = window.browser.webkit; window.gecko = window.browser.gecko; window.opera = window.browser.opera; //log console.log("browser : ", window.browser, "\nie: ", window.ie, "\nwindow.webkit: ", window.webkit, "\nwindow.gecko: ", window.gecko, "\nwindow.opera: ", window.opera) let testDiv = document.getElementById("testDevice") testDiv.innerText = testDiv.innerText + "\n ie: " + window.ie + "\n window.webkit: " + window.webkit + "\n window.gecko: " + window.gecko + "\n window.opera: " + window.opera } /** * 刷新跟节点 front-size * @constructor */ RefreshRootFrontSize() { let curDoc = document.documentElement;//当前文档的 root 元素 let curClientW = curDoc.clientWidth; if (!curClientW) { return } let designWidth = window.myEdit.ctx.designWith; //set 1rem = viewWidth/10 (支持响应式) let nowFrontSize = ((curClientW / designWidth) / 10) + 'px'; curDoc.style.fontSize = nowFrontSize; console.log("curClientW :", curClientW, "designWidth: ", designWidth, "-> ", nowFrontSize); let testDiv = document.getElementById("testDevice") testDiv.innerText = testDiv.innerText + "\n curClientW :" + curClientW + " \n designWidth: " + designWidth + "\n -> " + nowFrontSize } RefreshBodyFrontSize() { let dpr = window.devicePixelRatio || 1;//当前设置下 物理像素和虚拟像素的比值 let defaultFrontSize = window.myEdit.ctx.bodyFrontSize; if (!dpr) { //devicePixelRatio这个属性是可以获取到设备的dpr let devicePixelRatio = win.devicePixelRatio; //判断dpr是否为整数 let isRegularDpr = devicePixelRatio.toString().match(/^[1-9]\d*$/g) if (isRegularDpr) { // 对于是整数的dpr,对dpr进行操作 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) { dpr = 2; } else { dpr = 1; } } else { // 其他设备下,仍旧使用1倍的方案 dpr = 1; } } if (document.documentElement.clientWidth <= 720) { document.body.style.fontSize = defaultFrontSize + 'px'; } else { document.body.style.fontSize = defaultFrontSize * dpr + 'px'; } console.log("body-frontSize: ", document.body.style.fontSize); } /** * * @returns 生产uuid */ Uuid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' .replace(/[xy]/g, function (c) { const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8) return v.toString(16) }).split("-")[0] } /** * 阻止默认事件 * @constructor */ ProhibitDefaultEvent(event) { event.preventDefault() event.returnValue = false } /** * 获取 触发事件的元素 * @param event * @constructor */ GetEventTarget(event) { return event.target } ParseEvent(e) { return e || window.event //标准化事件处理 } GetKeyCode(event) { return event.keyCode || event.which || event.charCode } /** * 当前选区。 兼容不同浏览器 * @returns {Selection|*} */ GetSelection() { return window.getSelection() || document.selection } /** * 是否是数字 * @param value * @returns {boolean} */ IsNum(value) { return !isNaN(parseFloat(value)) && isFinite(value) } /** * 在节点node后面插入新节点newNode * @method InsertAfter * @param { Node } node 目标节点 * @param { Node } newNode 新插入的节点, 该节点将置于目标节点之后 * @return { Node } 新插入的节点 */ InsertAfter(node, newNode) { return node.nextSibling ? node.parentNode.insertBefore(newNode, node.nextSibling) : node.parentNode.appendChild(newNode) } /** * 新增一个元素 * @param newParagraph */ AddNewParagraph(newParagraph) { //docRoot window.myEdit.ctx.MyRoot.appendChild(newParagraph); //mapRoot let myP = new MyDocItem(newParagraph); let curOrder = myP.parseOrder(); let uuid = myP.parseUuid(); window.myEdit.ctx.MyDocMap.set(curOrder, new MyMapItem(uuid)) //收起选区到一个点,光标落在一个可编辑元素上 window.myEdit.utils.GetSelection().setPosition(newParagraph, 0); } /** * 同步某一行数据到对应的 map节点 * @param docP * @constructor */ SyncMapItemChildrenStyle(docP) { //子元素为空不处理 let items = docP.childNodes; if (items.length <= 0) { return } //构造参数 let curMyP = new MyDocItem(docP); let mapItem = window.myEdit.ctx.getMapItem(curMyP.parseOrder()); //清空重置 // console.log(mapItem); mapItem.getStyle().setChildrenStyleMapNull(); //遍历 for (let i = 0; i < items.length; i++) { let curItem = items[i]; let tmpClassList = curItem.classList; if (tmpClassList != null && tmpClassList.length > 0) { mapItem.getStyle().setChildrenStyle(i, tmpClassList); } } // console.log("sync docP : ", docP, " children: ", docP.children, " childrenMap: ", mapItem.getStyle().getChildrenStyleMap()) } /** * A4纸 */ GetDPI() { let tempDiv = document.createElement("div"); tempDiv.style.width = "1in"; tempDiv.style.visibility = "hidden"; document.body.appendChild(tempDiv); let dpi = tempDiv.offsetWidth; document.body.removeChild(tempDiv); return dpi; } MmToPixel(mm, dpi) { // 1 inch = 25.4 mm let inches = mm / 25.4; let pixels = inches * dpi; return Math.round(pixels); } A4SizeInPixels() { let dpi = window.myEdit.utils.GetDPI(); let width_mm = 210; // A4纸宽度,单位:毫米 let height_mm = 297; // A4纸高度,单位:毫米 let width_px = window.myEdit.utils.MmToPixel(width_mm, dpi); let height_px = window.myEdit.utils.MmToPixel(height_mm, dpi); return {width: width_px, height: height_px}; } }