"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
*
* - IE系列返回值为5,6,7,8,9,10等
* - gecko系列会返回10900,158900等
* - webkit系列会返回其build号 (如 522等)
*
* @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};
}
}