Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

zrender

Package Overview
Dependencies
Maintainers
1
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zrender - npm Package Compare versions

Comparing version 3.1.1 to 3.1.2

lib/dom/HandlerProxy.js

104

lib/contain/text.js

@@ -9,2 +9,3 @@

var BoundingRect = require('../core/BoundingRect');
var retrieve = util.retrieve;

@@ -168,11 +169,14 @@ function getTextWidth(text, textFont) {

* @param {string} text
* @param {string} containerWidth
* @param {string} textFont
* @param {string} containerWidth
* @param {number} [ellipsis='...']
* @param {Object} [options]
* @param {number} [options.ellipsis='...']
* @param {number} [options.maxIterations=3]
* @param {number} [options.minCharacters=3]
* @param {number} [options.minChar=0] If truncate result are less
* then minChar, ellipsis will not show, which is
* better for user hint in some cases.
* @param {number} [options.placeholder=''] When all truncated, use the placeholder.
* @return {string}
*/
function textEllipsis(text, textFont, containerWidth, options) {
function truncateText(text, containerWidth, textFont, ellipsis, options) {
if (!containerWidth) {

@@ -182,58 +186,72 @@ return '';

options = util.defaults({
ellipsis: '...',
minCharacters: 3,
maxIterations: 3,
cnCharWidth: getTextWidth('国', textFont),
// FIXME
// 未考虑非等宽字体
ascCharWidth: getTextWidth('a', textFont)
}, options, true);
options = options || {};
containerWidth -= getTextWidth(options.ellipsis);
ellipsis = retrieve(ellipsis, '...');
var maxIterations = retrieve(options.maxIterations, 2);
var minChar = retrieve(options.minChar, 0);
// FIXME
// Other languages?
var cnCharWidth = getTextWidth('国', textFont);
// FIXME
// Consider proportional font?
var ascCharWidth = getTextWidth('a', textFont);
var placeholder = retrieve(options.placeholder, '');
var textLines = (text + '').split('\n');
// Example 1: minChar: 3, text: 'asdfzxcv', truncate result: 'asdf', but not: 'a...'.
// Example 2: minChar: 3, text: '维度', truncate result: '维', but not: '...'.
var contentWidth = containerWidth = Math.max(0, containerWidth - 1); // Reserve some gap.
for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) {
contentWidth -= ascCharWidth;
}
for (var i = 0, len = textLines.length; i < len; i++) {
textLines[i] = textLineTruncate(
textLines[i], textFont, containerWidth, options
);
var ellipsisWidth = getTextWidth(ellipsis);
if (ellipsisWidth > contentWidth) {
ellipsis = '';
ellipsisWidth = 0;
}
return textLines.join('\n');
}
contentWidth = containerWidth - ellipsisWidth;
function textLineTruncate(text, textFont, containerWidth, options) {
// FIXME
// 粗糙得写的,尚未考虑性能和各种语言、字体的效果。
for (var i = 0;; i++) {
var lineWidth = getTextWidth(text, textFont);
var textLines = (text + '').split('\n');
if (lineWidth < containerWidth || i >= options.maxIterations) {
text += options.ellipsis;
break;
for (var i = 0, len = textLines.length; i < len; i++) {
var textLine = textLines[i];
var lineWidth = getTextWidth(textLine, textFont);
if (lineWidth <= containerWidth) {
continue;
}
var subLength = i === 0
? estimateLength(text, containerWidth, options)
: Math.floor(text.length * containerWidth / lineWidth);
for (var j = 0;; j++) {
if (lineWidth <= contentWidth || j >= maxIterations) {
textLine += ellipsis;
break;
}
if (subLength < options.minCharacters) {
text = '';
break;
var subLength = j === 0
? estimateLength(textLine, contentWidth, ascCharWidth, cnCharWidth)
: lineWidth > 0
? Math.floor(textLine.length * contentWidth / lineWidth)
: 0;
textLine = textLine.substr(0, subLength);
lineWidth = getTextWidth(textLine, textFont);
}
text = text.substr(0, subLength);
if (textLine === '') {
textLine = placeholder;
}
textLines[i] = textLine;
}
return text;
return textLines.join('\n');
}
function estimateLength(text, containerWidth, options) {
function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) {
var width = 0;
var i = 0;
for (var len = text.length; i < len && width < containerWidth; i++) {
for (var len = text.length; i < len && width < contentWidth; i++) {
var charCode = text.charCodeAt(i);
width += (0 <= charCode && charCode <= 127)
? options.ascCharWidth : options.cnCharWidth;
width += (0 <= charCode && charCode <= 127) ? ascCharWidth : cnCharWidth;
}

@@ -251,7 +269,7 @@ return i;

ellipsis: textEllipsis,
truncateText: truncateText,
measureText: function (text, textFont) {
var ctx = util.getContext();
ctx.font = textFont;
ctx.font = textFont || '12px sans-serif';
return ctx.measureText(text);

@@ -258,0 +276,0 @@ }

@@ -47,3 +47,3 @@ /**

// var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
// var firefox = ua.match(/Firefox\/([\d.]+)/);
var firefox = ua.match(/Firefox\/([\d.]+)/);
// var safari = webkit && ua.match(/Mobile\//) && !chrome;

@@ -78,3 +78,3 @@ // var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;

// if (chrome) browser.chrome = true, browser.version = chrome[1];
// if (firefox) browser.firefox = true, browser.version = firefox[1];
if (firefox) browser.firefox = true, browser.version = firefox[1];
// if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;

@@ -81,0 +81,0 @@ // if (webview) browser.webview = true;

@@ -11,3 +11,2 @@ /**

var zrUtil = require('../core/util');
var roundRectHelper = require('./helper/roundRect');

@@ -102,9 +101,2 @@ var LRU = require('../core/LRU');

if (style.r) {
// Border radius clipping
// FIXME
ctx.beginPath();
roundRectHelper.buildPath(ctx, style);
ctx.clip();
}

@@ -111,0 +103,0 @@ if (style.sWidth && style.sHeight) {

@@ -177,3 +177,3 @@ /**

if (!style.hasFill()) {
w = Math.max(w, this.strokeContainThreshold);
w = Math.max(w, this.strokeContainThreshold || 4);
}

@@ -180,0 +180,0 @@ // Consider line width

@@ -51,5 +51,6 @@ /**

var textAlign = style.textAlign;
var font = style.textFont || style.font;
if (style.textVerticalAlign) {
var rect = textContain.getBoundingRect(
text, ctx.font, style.textAlign, 'top'
text, font, style.textAlign, 'top'
);

@@ -73,3 +74,3 @@ // Ignore textBaseline

ctx.font = style.textFont || style.font;
ctx.font = font;
ctx.textAlign = textAlign || 'left';

@@ -76,0 +77,0 @@ // Use canvas default left textAlign. Giving invalid value will cause state not change

@@ -11,31 +11,7 @@ 'use strict';

var env = require('./core/env');
var eventTool = require('./core/event');
var util = require('./core/util');
var Draggable = require('./mixin/Draggable');
var GestureMgr = require('./core/GestureMgr');
var Eventful = require('./mixin/Eventful');
var mouseHandlerNames = [
'click', 'dblclick', 'mousewheel', 'mouseout'
];
!usePointerEvent() && mouseHandlerNames.push(
'mouseup', 'mousedown', 'mousemove'
);
var touchHandlerNames = [
'touchstart', 'touchend', 'touchmove'
];
var pointerHandlerNames = [
'pointerdown', 'pointerup', 'pointermove'
];
var TOUCH_CLICK_DELAY = 300;
var addEventListener = eventTool.addEventListener;
var removeEventListener = eventTool.removeEventListener;
var normalizeEvent = eventTool.normalizeEvent;
function makeEventPacket(eveType, target, event) {

@@ -57,213 +33,10 @@ return {

var domHandlers = {
/**
* Mouse move handler
* @inner
* @param {Event} event
*/
mousemove: function (event) {
event = normalizeEvent(this.root, event);
function EmptyProxy () {}
EmptyProxy.prototype.dispose = function () {};
var x = event.zrX;
var y = event.zrY;
var hovered = this.findHover(x, y, null);
var lastHovered = this._hovered;
this._hovered = hovered;
this.root.style.cursor = hovered ? hovered.cursor : 'default';
// Mouse out on previous hovered element
if (lastHovered && hovered !== lastHovered && lastHovered.__zr) {
this._dispatchProxy(lastHovered, 'mouseout', event);
}
// Mouse moving on one element
this._dispatchProxy(hovered, 'mousemove', event);
// Mouse over on a new element
if (hovered && hovered !== lastHovered) {
this._dispatchProxy(hovered, 'mouseover', event);
}
},
/**
* Mouse out handler
* @inner
* @param {Event} event
*/
mouseout: function (event) {
event = normalizeEvent(this.root, event);
var element = event.toElement || event.relatedTarget;
if (element != this.root) {
while (element && element.nodeType != 9) {
// 忽略包含在root中的dom引起的mouseOut
if (element === this.root) {
return;
}
element = element.parentNode;
}
}
this._dispatchProxy(this._hovered, 'mouseout', event);
this.trigger('globalout', {
event: event
});
},
/**
* Touch开始响应函数
* @inner
* @param {Event} event
*/
touchstart: function (event) {
// Default mouse behaviour should not be disabled here.
// For example, page may needs to be slided.
// eventTool.stop(event);
event = normalizeEvent(this.root, event);
this._lastTouchMoment = new Date();
processGesture(this, event, 'start');
// 平板补充一次findHover
// this._mobileFindFixed(event);
// Trigger mousemove and mousedown
domHandlers.mousemove.call(this, event);
domHandlers.mousedown.call(this, event);
setTouchTimer(this);
},
/**
* Touch移动响应函数
* @inner
* @param {Event} event
*/
touchmove: function (event) {
// eventTool.stop(event);// 阻止浏览器默认事件,重要
event = normalizeEvent(this.root, event);
processGesture(this, event, 'change');
// Mouse move should always be triggered no matter whether
// there is gestrue event, because mouse move and pinch may
// be used at the same time.
domHandlers.mousemove.call(this, event);
setTouchTimer(this);
},
/**
* Touch结束响应函数
* @inner
* @param {Event} event
*/
touchend: function (event) {
// eventTool.stop(event);// 阻止浏览器默认事件,重要
event = normalizeEvent(this.root, event);
processGesture(this, event, 'end');
domHandlers.mouseup.call(this, event);
// click event should always be triggered no matter whether
// there is gestrue event. System click can not be prevented.
if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) {
// this._mobileFindFixed(event);
domHandlers.click.call(this, event);
}
setTouchTimer(this);
}
};
// Common handlers
util.each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick'], function (name) {
domHandlers[name] = function (event) {
event = normalizeEvent(this.root, event);
// Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
var hovered = this.findHover(event.zrX, event.zrY, null);
if (name === 'mousedown') {
this._downel = hovered;
// In case click triggered before mouseup
this._upel = hovered;
}
else if (name === 'mosueup') {
this._upel = hovered;
}
else if (name === 'click') {
if (this._downel !== this._upel) {
return;
}
}
this._dispatchProxy(hovered, name, event);
};
});
// Pointer event handlers
// util.each(['pointerdown', 'pointermove', 'pointerup'], function (name) {
// domHandlers[name] = function (event) {
// var mouseName = name.replace('pointer', 'mouse');
// domHandlers[mouseName].call(this, event);
// };
// });
function processGesture(zrHandler, event, stage) {
var gestureMgr = zrHandler._gestureMgr;
stage === 'start' && gestureMgr.clear();
var gestureInfo = gestureMgr.recognize(
event,
zrHandler.findHover(event.zrX, event.zrY, null),
zrHandler.root
);
stage === 'end' && gestureMgr.clear();
if (gestureInfo) {
// eventTool.stop(event);
var type = gestureInfo.type;
event.gestureEvent = type;
zrHandler._dispatchProxy(gestureInfo.target, type, gestureInfo.event);
}
}
var handlerNames = [
'click', 'dblclick', 'mousewheel', 'mouseout',
'mouseup', 'mousedown', 'mousemove'
];
/**
* 为控制类实例初始化dom 事件处理函数
*
* @inner
* @param {module:zrender/Handler} instance 控制类实例
*/
function initDomHandler(instance) {
var handlerNames = touchHandlerNames.concat(pointerHandlerNames);
for (var i = 0; i < handlerNames.length; i++) {
var name = handlerNames[i];
instance._handlers[name] = util.bind(domHandlers[name], instance);
}
for (var i = 0; i < mouseHandlerNames.length; i++) {
var name = mouseHandlerNames[i];
instance._handlers[name] = makeMouseHandler(domHandlers[name], instance);
}
function makeMouseHandler(fn, instance) {
return function () {
if (instance._touching) {
return;
}
return fn.apply(instance, arguments);
};
}
}
/**
* @alias module:zrender/Handler

@@ -276,10 +49,19 @@ * @constructor

*/
var Handler = function(root, storage, painter) {
var Handler = function(storage, painter, proxy) {
Eventful.call(this);
this.root = root;
this.storage = storage;
this.painter = painter;
proxy = proxy || new EmptyProxy();
/**
* Proxy of event. can be Dom, WebGLSurface, etc.
*/
this.proxy = proxy;
// Attach handler
proxy.handler = this;
/**
* @private

@@ -308,56 +90,48 @@ * @type {boolean}

/**
* @private
* @type {module:zrender/core/GestureMgr}
*/
this._gestureMgr = new GestureMgr();
/**
* @private
* @type {Array.<Function>}
*/
this._handlers = [];
Draggable.call(this);
/**
* @private
* @type {boolean}
*/
this._touching = false;
util.each(handlerNames, function (name) {
proxy.on && proxy.on(name, this[name], this);
}, this);
};
/**
* @private
* @type {number}
*/
this._touchTimer;
Handler.prototype = {
initDomHandler(this);
constructor: Handler,
if (usePointerEvent()) {
mountHandlers(pointerHandlerNames, this);
}
else if (useTouchEvent()) {
mountHandlers(touchHandlerNames, this);
mousemove: function (event) {
var x = event.zrX;
var y = event.zrY;
// Handler of 'mouseout' event is needed in touch mode, which will be mounted below.
// addEventListener(root, 'mouseout', this._mouseoutHandler);
}
var hovered = this.findHover(x, y, null);
var lastHovered = this._hovered;
var proxy = this.proxy;
// Considering some devices that both enable touch and mouse event (like MS Surface
// and lenovo X240, @see #2350), we make mouse event be always listened, otherwise
// mouse event can not be handle in those devices.
mountHandlers(mouseHandlerNames, this);
this._hovered = hovered;
Draggable.call(this);
proxy.setCursor && proxy.setCursor(hovered ? hovered.cursor : 'default');
function mountHandlers(handlerNames, instance) {
util.each(handlerNames, function (name) {
addEventListener(root, eventNameFix(name), instance._handlers[name]);
}, instance);
}
};
// Mouse out on previous hovered element
if (lastHovered && hovered !== lastHovered && lastHovered.__zr) {
this.dispatchToElement(lastHovered, 'mouseout', event);
}
Handler.prototype = {
// Mouse moving on one element
this.dispatchToElement(hovered, 'mousemove', event);
constructor: Handler,
// Mouse over on a new element
if (hovered && hovered !== lastHovered) {
this.dispatchToElement(hovered, 'mouseover', event);
}
},
mouseout: function (event) {
this.dispatchToElement(this._hovered, 'mouseout', event);
this.trigger('globalout', {
event: event
});
},
/**

@@ -376,3 +150,3 @@ * Resize

dispatch: function (eventName, eventArgs) {
var handler = this._handlers[eventName];
var handler = this[eventName];
handler && handler.call(this, eventArgs);

@@ -385,13 +159,7 @@ },

dispose: function () {
var root = this.root;
var handlerNames = mouseHandlerNames.concat(touchHandlerNames);
this.proxy.dispose();
for (var i = 0; i < handlerNames.length; i++) {
var name = handlerNames[i];
removeEventListener(root, eventNameFix(name), this._handlers[name]);
}
this.root =
this.storage =
this.proxy =
this.painter = null;

@@ -405,3 +173,4 @@ },

setCursorStyle: function (cursorStyle) {
this.root.style.cursor = cursorStyle || 'default';
var proxy = this.proxy;
proxy.setCursor && proxy.setCursor(cursorStyle);
},

@@ -417,3 +186,3 @@

*/
_dispatchProxy: function (targetEl, eventName, event) {
dispatchToElement: function (targetEl, eventName, event) {
var eventHandler = 'on' + eventName;

@@ -474,2 +243,26 @@ var eventPacket = makeEventPacket(eventName, targetEl, event);

// Common handlers
util.each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick'], function (name) {
Handler.prototype[name] = function (event) {
// Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
var hovered = this.findHover(event.zrX, event.zrY, null);
if (name === 'mousedown') {
this._downel = hovered;
// In case click triggered before mouseup
this._upel = hovered;
}
else if (name === 'mosueup') {
this._upel = hovered;
}
else if (name === 'click') {
if (this._downel !== this._upel) {
return;
}
}
this.dispatchToElement(hovered, name, event);
};
});
function isHover(displayable, x, y) {

@@ -491,41 +284,2 @@ if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) {

/**
* Prevent mouse event from being dispatched after Touch Events action
* @see <https://github.com/deltakosh/handjs/blob/master/src/hand.base.js>
* 1. Mobile browsers dispatch mouse events 300ms after touchend.
* 2. Chrome for Android dispatch mousedown for long-touch about 650ms
* Result: Blocking Mouse Events for 700ms.
*/
function setTouchTimer(instance) {
instance._touching = true;
clearTimeout(instance._touchTimer);
instance._touchTimer = setTimeout(function () {
instance._touching = false;
}, 700);
}
/**
* Althought MS Surface support screen touch, IE10/11 do not support
* touch event and MS Edge supported them but not by default (but chrome
* and firefox do). Thus we use Pointer event on MS browsers to handle touch.
*/
function usePointerEvent() {
// TODO
// pointermove event dont trigger when using finger.
// We may figger it out latter.
return false;
// return env.pointerEventsSupported
// In no-touch device we dont use pointer evnets but just
// use mouse event for avoiding problems.
// && window.navigator.maxTouchPoints;
}
function useTouchEvent() {
return env.touchEventsSupported;
}
function eventNameFix(name) {
return (name === 'mousewheel' && env.browser.firefox) ? 'DOMMouseScroll' : name;
}
util.mixin(Handler, Eventful);

@@ -532,0 +286,0 @@ util.mixin(Handler, Draggable);

@@ -29,3 +29,3 @@ // TODO Draggable for group

this._dispatchProxy(draggingTarget, 'dragstart', e.event);
this.dispatchToElement(draggingTarget, 'dragstart', e.event);
}

@@ -47,3 +47,3 @@ },

draggingTarget.drift(dx, dy, e);
this._dispatchProxy(draggingTarget, 'drag', e.event);
this.dispatchToElement(draggingTarget, 'drag', e.event);

@@ -56,6 +56,6 @@ var dropTarget = this.findHover(x, y, draggingTarget);

if (lastDropTarget && dropTarget !== lastDropTarget) {
this._dispatchProxy(lastDropTarget, 'dragleave', e.event);
this.dispatchToElement(lastDropTarget, 'dragleave', e.event);
}
if (dropTarget && dropTarget !== lastDropTarget) {
this._dispatchProxy(dropTarget, 'dragenter', e.event);
this.dispatchToElement(dropTarget, 'dragenter', e.event);
}

@@ -73,6 +73,6 @@ }

this._dispatchProxy(draggingTarget, 'dragend', e.event);
this.dispatchToElement(draggingTarget, 'dragend', e.event);
if (this._dropTarget) {
this._dispatchProxy(this._dropTarget, 'drop', e.event);
this.dispatchToElement(this._dropTarget, 'drop', e.event);
}

@@ -79,0 +79,0 @@

@@ -18,2 +18,3 @@ /*!

var Animation = require('./animation/Animation');
var HandlerProxy = require('./dom/HandlerProxy');

@@ -32,3 +33,3 @@ var useVML = !env.canvasSupported;

*/
zrender.version = '3.1.1';
zrender.version = '3.1.2';

@@ -127,6 +128,6 @@ /**

this.painter = painter;
if (!env.node) {
this.handler = new Handler(painter.getViewportRoot(), storage, painter);
}
var handerProxy = !env.node ? new HandlerProxy(painter.getViewportRoot()) : null;
this.handler = new Handler(storage, painter, handerProxy);
/**

@@ -293,3 +294,3 @@ * @type {module:zrender/animation/Animation}

this.painter.resize();
this.handler && this.handler.resize();
this.handler.resize();
},

@@ -347,3 +348,3 @@

setCursorStyle: function (cursorStyle) {
this.handler && this.handler.setCursorStyle(cursorStyle);
this.handler.setCursorStyle(cursorStyle);
},

@@ -359,3 +360,3 @@

on: function(eventName, eventHandler, context) {
this.handler && this.handler.on(eventName, eventHandler, context);
this.handler.on(eventName, eventHandler, context);
},

@@ -369,3 +370,3 @@

off: function(eventName, eventHandler) {
this.handler && this.handler.off(eventName, eventHandler);
this.handler.off(eventName, eventHandler);
},

@@ -380,3 +381,3 @@

trigger: function (eventName, event) {
this.handler && this.handler.trigger(eventName, event);
this.handler.trigger(eventName, event);
},

@@ -402,3 +403,3 @@

this.painter.dispose();
this.handler && this.handler.dispose();
this.handler.dispose();

@@ -405,0 +406,0 @@ this.animation =

{
"name": "zrender",
"version": "3.1.1",
"version": "3.1.2",
"description": "A lightweight canvas library.",

@@ -5,0 +5,0 @@ "keywords": [

@@ -9,2 +9,3 @@ define(function (require) {

var BoundingRect = require('../core/BoundingRect');
var retrieve = util.retrieve;

@@ -168,11 +169,14 @@ function getTextWidth(text, textFont) {

* @param {string} text
* @param {string} containerWidth
* @param {string} textFont
* @param {string} containerWidth
* @param {number} [ellipsis='...']
* @param {Object} [options]
* @param {number} [options.ellipsis='...']
* @param {number} [options.maxIterations=3]
* @param {number} [options.minCharacters=3]
* @param {number} [options.minChar=0] If truncate result are less
* then minChar, ellipsis will not show, which is
* better for user hint in some cases.
* @param {number} [options.placeholder=''] When all truncated, use the placeholder.
* @return {string}
*/
function textEllipsis(text, textFont, containerWidth, options) {
function truncateText(text, containerWidth, textFont, ellipsis, options) {
if (!containerWidth) {

@@ -182,58 +186,72 @@ return '';

options = util.defaults({
ellipsis: '...',
minCharacters: 3,
maxIterations: 3,
cnCharWidth: getTextWidth('国', textFont),
// FIXME
// 未考虑非等宽字体
ascCharWidth: getTextWidth('a', textFont)
}, options, true);
options = options || {};
containerWidth -= getTextWidth(options.ellipsis);
ellipsis = retrieve(ellipsis, '...');
var maxIterations = retrieve(options.maxIterations, 2);
var minChar = retrieve(options.minChar, 0);
// FIXME
// Other languages?
var cnCharWidth = getTextWidth('国', textFont);
// FIXME
// Consider proportional font?
var ascCharWidth = getTextWidth('a', textFont);
var placeholder = retrieve(options.placeholder, '');
var textLines = (text + '').split('\n');
// Example 1: minChar: 3, text: 'asdfzxcv', truncate result: 'asdf', but not: 'a...'.
// Example 2: minChar: 3, text: '维度', truncate result: '维', but not: '...'.
var contentWidth = containerWidth = Math.max(0, containerWidth - 1); // Reserve some gap.
for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) {
contentWidth -= ascCharWidth;
}
for (var i = 0, len = textLines.length; i < len; i++) {
textLines[i] = textLineTruncate(
textLines[i], textFont, containerWidth, options
);
var ellipsisWidth = getTextWidth(ellipsis);
if (ellipsisWidth > contentWidth) {
ellipsis = '';
ellipsisWidth = 0;
}
return textLines.join('\n');
}
contentWidth = containerWidth - ellipsisWidth;
function textLineTruncate(text, textFont, containerWidth, options) {
// FIXME
// 粗糙得写的,尚未考虑性能和各种语言、字体的效果。
for (var i = 0;; i++) {
var lineWidth = getTextWidth(text, textFont);
var textLines = (text + '').split('\n');
if (lineWidth < containerWidth || i >= options.maxIterations) {
text += options.ellipsis;
break;
for (var i = 0, len = textLines.length; i < len; i++) {
var textLine = textLines[i];
var lineWidth = getTextWidth(textLine, textFont);
if (lineWidth <= containerWidth) {
continue;
}
var subLength = i === 0
? estimateLength(text, containerWidth, options)
: Math.floor(text.length * containerWidth / lineWidth);
for (var j = 0;; j++) {
if (lineWidth <= contentWidth || j >= maxIterations) {
textLine += ellipsis;
break;
}
if (subLength < options.minCharacters) {
text = '';
break;
var subLength = j === 0
? estimateLength(textLine, contentWidth, ascCharWidth, cnCharWidth)
: lineWidth > 0
? Math.floor(textLine.length * contentWidth / lineWidth)
: 0;
textLine = textLine.substr(0, subLength);
lineWidth = getTextWidth(textLine, textFont);
}
text = text.substr(0, subLength);
if (textLine === '') {
textLine = placeholder;
}
textLines[i] = textLine;
}
return text;
return textLines.join('\n');
}
function estimateLength(text, containerWidth, options) {
function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) {
var width = 0;
var i = 0;
for (var len = text.length; i < len && width < containerWidth; i++) {
for (var len = text.length; i < len && width < contentWidth; i++) {
var charCode = text.charCodeAt(i);
width += (0 <= charCode && charCode <= 127)
? options.ascCharWidth : options.cnCharWidth;
width += (0 <= charCode && charCode <= 127) ? ascCharWidth : cnCharWidth;
}

@@ -251,7 +269,7 @@ return i;

ellipsis: textEllipsis,
truncateText: truncateText,
measureText: function (text, textFont) {
var ctx = util.getContext();
ctx.font = textFont;
ctx.font = textFont || '12px sans-serif';
return ctx.measureText(text);

@@ -258,0 +276,0 @@ }

@@ -47,3 +47,3 @@ /**

// var chrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
// var firefox = ua.match(/Firefox\/([\d.]+)/);
var firefox = ua.match(/Firefox\/([\d.]+)/);
// var safari = webkit && ua.match(/Mobile\//) && !chrome;

@@ -78,3 +78,3 @@ // var webview = ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/) && !chrome;

// if (chrome) browser.chrome = true, browser.version = chrome[1];
// if (firefox) browser.firefox = true, browser.version = firefox[1];
if (firefox) browser.firefox = true, browser.version = firefox[1];
// if (safari && (ua.match(/Safari/) || !!os.ios)) browser.safari = true;

@@ -81,0 +81,0 @@ // if (webview) browser.webview = true;

@@ -11,3 +11,2 @@ /**

var zrUtil = require('../core/util');
var roundRectHelper = require('./helper/roundRect');

@@ -102,9 +101,2 @@ var LRU = require('../core/LRU');

if (style.r) {
// Border radius clipping
// FIXME
ctx.beginPath();
roundRectHelper.buildPath(ctx, style);
ctx.clip();
}

@@ -111,0 +103,0 @@ if (style.sWidth && style.sHeight) {

@@ -177,3 +177,3 @@ /**

if (!style.hasFill()) {
w = Math.max(w, this.strokeContainThreshold);
w = Math.max(w, this.strokeContainThreshold || 4);
}

@@ -180,0 +180,0 @@ // Consider line width

@@ -51,5 +51,6 @@ /**

var textAlign = style.textAlign;
var font = style.textFont || style.font;
if (style.textVerticalAlign) {
var rect = textContain.getBoundingRect(
text, ctx.font, style.textAlign, 'top'
text, font, style.textAlign, 'top'
);

@@ -73,3 +74,3 @@ // Ignore textBaseline

ctx.font = style.textFont || style.font;
ctx.font = font;
ctx.textAlign = textAlign || 'left';

@@ -76,0 +77,0 @@ // Use canvas default left textAlign. Giving invalid value will cause state not change

@@ -12,31 +12,7 @@ /**

var env = require('./core/env');
var eventTool = require('./core/event');
var util = require('./core/util');
var Draggable = require('./mixin/Draggable');
var GestureMgr = require('./core/GestureMgr');
var Eventful = require('./mixin/Eventful');
var mouseHandlerNames = [
'click', 'dblclick', 'mousewheel', 'mouseout'
];
!usePointerEvent() && mouseHandlerNames.push(
'mouseup', 'mousedown', 'mousemove'
);
var touchHandlerNames = [
'touchstart', 'touchend', 'touchmove'
];
var pointerHandlerNames = [
'pointerdown', 'pointerup', 'pointermove'
];
var TOUCH_CLICK_DELAY = 300;
var addEventListener = eventTool.addEventListener;
var removeEventListener = eventTool.removeEventListener;
var normalizeEvent = eventTool.normalizeEvent;
function makeEventPacket(eveType, target, event) {

@@ -58,213 +34,10 @@ return {

var domHandlers = {
/**
* Mouse move handler
* @inner
* @param {Event} event
*/
mousemove: function (event) {
event = normalizeEvent(this.root, event);
function EmptyProxy () {}
EmptyProxy.prototype.dispose = function () {};
var x = event.zrX;
var y = event.zrY;
var hovered = this.findHover(x, y, null);
var lastHovered = this._hovered;
this._hovered = hovered;
this.root.style.cursor = hovered ? hovered.cursor : 'default';
// Mouse out on previous hovered element
if (lastHovered && hovered !== lastHovered && lastHovered.__zr) {
this._dispatchProxy(lastHovered, 'mouseout', event);
}
// Mouse moving on one element
this._dispatchProxy(hovered, 'mousemove', event);
// Mouse over on a new element
if (hovered && hovered !== lastHovered) {
this._dispatchProxy(hovered, 'mouseover', event);
}
},
/**
* Mouse out handler
* @inner
* @param {Event} event
*/
mouseout: function (event) {
event = normalizeEvent(this.root, event);
var element = event.toElement || event.relatedTarget;
if (element != this.root) {
while (element && element.nodeType != 9) {
// 忽略包含在root中的dom引起的mouseOut
if (element === this.root) {
return;
}
element = element.parentNode;
}
}
this._dispatchProxy(this._hovered, 'mouseout', event);
this.trigger('globalout', {
event: event
});
},
/**
* Touch开始响应函数
* @inner
* @param {Event} event
*/
touchstart: function (event) {
// Default mouse behaviour should not be disabled here.
// For example, page may needs to be slided.
// eventTool.stop(event);
event = normalizeEvent(this.root, event);
this._lastTouchMoment = new Date();
processGesture(this, event, 'start');
// 平板补充一次findHover
// this._mobileFindFixed(event);
// Trigger mousemove and mousedown
domHandlers.mousemove.call(this, event);
domHandlers.mousedown.call(this, event);
setTouchTimer(this);
},
/**
* Touch移动响应函数
* @inner
* @param {Event} event
*/
touchmove: function (event) {
// eventTool.stop(event);// 阻止浏览器默认事件,重要
event = normalizeEvent(this.root, event);
processGesture(this, event, 'change');
// Mouse move should always be triggered no matter whether
// there is gestrue event, because mouse move and pinch may
// be used at the same time.
domHandlers.mousemove.call(this, event);
setTouchTimer(this);
},
/**
* Touch结束响应函数
* @inner
* @param {Event} event
*/
touchend: function (event) {
// eventTool.stop(event);// 阻止浏览器默认事件,重要
event = normalizeEvent(this.root, event);
processGesture(this, event, 'end');
domHandlers.mouseup.call(this, event);
// click event should always be triggered no matter whether
// there is gestrue event. System click can not be prevented.
if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) {
// this._mobileFindFixed(event);
domHandlers.click.call(this, event);
}
setTouchTimer(this);
}
};
// Common handlers
util.each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick'], function (name) {
domHandlers[name] = function (event) {
event = normalizeEvent(this.root, event);
// Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
var hovered = this.findHover(event.zrX, event.zrY, null);
if (name === 'mousedown') {
this._downel = hovered;
// In case click triggered before mouseup
this._upel = hovered;
}
else if (name === 'mosueup') {
this._upel = hovered;
}
else if (name === 'click') {
if (this._downel !== this._upel) {
return;
}
}
this._dispatchProxy(hovered, name, event);
};
});
// Pointer event handlers
// util.each(['pointerdown', 'pointermove', 'pointerup'], function (name) {
// domHandlers[name] = function (event) {
// var mouseName = name.replace('pointer', 'mouse');
// domHandlers[mouseName].call(this, event);
// };
// });
function processGesture(zrHandler, event, stage) {
var gestureMgr = zrHandler._gestureMgr;
stage === 'start' && gestureMgr.clear();
var gestureInfo = gestureMgr.recognize(
event,
zrHandler.findHover(event.zrX, event.zrY, null),
zrHandler.root
);
stage === 'end' && gestureMgr.clear();
if (gestureInfo) {
// eventTool.stop(event);
var type = gestureInfo.type;
event.gestureEvent = type;
zrHandler._dispatchProxy(gestureInfo.target, type, gestureInfo.event);
}
}
var handlerNames = [
'click', 'dblclick', 'mousewheel', 'mouseout',
'mouseup', 'mousedown', 'mousemove'
];
/**
* 为控制类实例初始化dom 事件处理函数
*
* @inner
* @param {module:zrender/Handler} instance 控制类实例
*/
function initDomHandler(instance) {
var handlerNames = touchHandlerNames.concat(pointerHandlerNames);
for (var i = 0; i < handlerNames.length; i++) {
var name = handlerNames[i];
instance._handlers[name] = util.bind(domHandlers[name], instance);
}
for (var i = 0; i < mouseHandlerNames.length; i++) {
var name = mouseHandlerNames[i];
instance._handlers[name] = makeMouseHandler(domHandlers[name], instance);
}
function makeMouseHandler(fn, instance) {
return function () {
if (instance._touching) {
return;
}
return fn.apply(instance, arguments);
};
}
}
/**
* @alias module:zrender/Handler

@@ -277,10 +50,19 @@ * @constructor

*/
var Handler = function(root, storage, painter) {
var Handler = function(storage, painter, proxy) {
Eventful.call(this);
this.root = root;
this.storage = storage;
this.painter = painter;
proxy = proxy || new EmptyProxy();
/**
* Proxy of event. can be Dom, WebGLSurface, etc.
*/
this.proxy = proxy;
// Attach handler
proxy.handler = this;
/**
* @private

@@ -309,56 +91,48 @@ * @type {boolean}

/**
* @private
* @type {module:zrender/core/GestureMgr}
*/
this._gestureMgr = new GestureMgr();
/**
* @private
* @type {Array.<Function>}
*/
this._handlers = [];
Draggable.call(this);
/**
* @private
* @type {boolean}
*/
this._touching = false;
util.each(handlerNames, function (name) {
proxy.on && proxy.on(name, this[name], this);
}, this);
};
/**
* @private
* @type {number}
*/
this._touchTimer;
Handler.prototype = {
initDomHandler(this);
constructor: Handler,
if (usePointerEvent()) {
mountHandlers(pointerHandlerNames, this);
}
else if (useTouchEvent()) {
mountHandlers(touchHandlerNames, this);
mousemove: function (event) {
var x = event.zrX;
var y = event.zrY;
// Handler of 'mouseout' event is needed in touch mode, which will be mounted below.
// addEventListener(root, 'mouseout', this._mouseoutHandler);
}
var hovered = this.findHover(x, y, null);
var lastHovered = this._hovered;
var proxy = this.proxy;
// Considering some devices that both enable touch and mouse event (like MS Surface
// and lenovo X240, @see #2350), we make mouse event be always listened, otherwise
// mouse event can not be handle in those devices.
mountHandlers(mouseHandlerNames, this);
this._hovered = hovered;
Draggable.call(this);
proxy.setCursor && proxy.setCursor(hovered ? hovered.cursor : 'default');
function mountHandlers(handlerNames, instance) {
util.each(handlerNames, function (name) {
addEventListener(root, eventNameFix(name), instance._handlers[name]);
}, instance);
}
};
// Mouse out on previous hovered element
if (lastHovered && hovered !== lastHovered && lastHovered.__zr) {
this.dispatchToElement(lastHovered, 'mouseout', event);
}
Handler.prototype = {
// Mouse moving on one element
this.dispatchToElement(hovered, 'mousemove', event);
constructor: Handler,
// Mouse over on a new element
if (hovered && hovered !== lastHovered) {
this.dispatchToElement(hovered, 'mouseover', event);
}
},
mouseout: function (event) {
this.dispatchToElement(this._hovered, 'mouseout', event);
this.trigger('globalout', {
event: event
});
},
/**

@@ -377,3 +151,3 @@ * Resize

dispatch: function (eventName, eventArgs) {
var handler = this._handlers[eventName];
var handler = this[eventName];
handler && handler.call(this, eventArgs);

@@ -386,13 +160,7 @@ },

dispose: function () {
var root = this.root;
var handlerNames = mouseHandlerNames.concat(touchHandlerNames);
this.proxy.dispose();
for (var i = 0; i < handlerNames.length; i++) {
var name = handlerNames[i];
removeEventListener(root, eventNameFix(name), this._handlers[name]);
}
this.root =
this.storage =
this.proxy =
this.painter = null;

@@ -406,3 +174,4 @@ },

setCursorStyle: function (cursorStyle) {
this.root.style.cursor = cursorStyle || 'default';
var proxy = this.proxy;
proxy.setCursor && proxy.setCursor(cursorStyle);
},

@@ -418,3 +187,3 @@

*/
_dispatchProxy: function (targetEl, eventName, event) {
dispatchToElement: function (targetEl, eventName, event) {
var eventHandler = 'on' + eventName;

@@ -475,2 +244,26 @@ var eventPacket = makeEventPacket(eventName, targetEl, event);

// Common handlers
util.each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick'], function (name) {
Handler.prototype[name] = function (event) {
// Find hover again to avoid click event is dispatched manually. Or click is triggered without mouseover
var hovered = this.findHover(event.zrX, event.zrY, null);
if (name === 'mousedown') {
this._downel = hovered;
// In case click triggered before mouseup
this._upel = hovered;
}
else if (name === 'mosueup') {
this._upel = hovered;
}
else if (name === 'click') {
if (this._downel !== this._upel) {
return;
}
}
this.dispatchToElement(hovered, name, event);
};
});
function isHover(displayable, x, y) {

@@ -492,41 +285,2 @@ if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) {

/**
* Prevent mouse event from being dispatched after Touch Events action
* @see <https://github.com/deltakosh/handjs/blob/master/src/hand.base.js>
* 1. Mobile browsers dispatch mouse events 300ms after touchend.
* 2. Chrome for Android dispatch mousedown for long-touch about 650ms
* Result: Blocking Mouse Events for 700ms.
*/
function setTouchTimer(instance) {
instance._touching = true;
clearTimeout(instance._touchTimer);
instance._touchTimer = setTimeout(function () {
instance._touching = false;
}, 700);
}
/**
* Althought MS Surface support screen touch, IE10/11 do not support
* touch event and MS Edge supported them but not by default (but chrome
* and firefox do). Thus we use Pointer event on MS browsers to handle touch.
*/
function usePointerEvent() {
// TODO
// pointermove event dont trigger when using finger.
// We may figger it out latter.
return false;
// return env.pointerEventsSupported
// In no-touch device we dont use pointer evnets but just
// use mouse event for avoiding problems.
// && window.navigator.maxTouchPoints;
}
function useTouchEvent() {
return env.touchEventsSupported;
}
function eventNameFix(name) {
return (name === 'mousewheel' && env.browser.firefox) ? 'DOMMouseScroll' : name;
}
util.mixin(Handler, Eventful);

@@ -533,0 +287,0 @@ util.mixin(Handler, Draggable);

@@ -29,3 +29,3 @@ // TODO Draggable for group

this._dispatchProxy(draggingTarget, 'dragstart', e.event);
this.dispatchToElement(draggingTarget, 'dragstart', e.event);
}

@@ -47,3 +47,3 @@ },

draggingTarget.drift(dx, dy, e);
this._dispatchProxy(draggingTarget, 'drag', e.event);
this.dispatchToElement(draggingTarget, 'drag', e.event);

@@ -56,6 +56,6 @@ var dropTarget = this.findHover(x, y, draggingTarget);

if (lastDropTarget && dropTarget !== lastDropTarget) {
this._dispatchProxy(lastDropTarget, 'dragleave', e.event);
this.dispatchToElement(lastDropTarget, 'dragleave', e.event);
}
if (dropTarget && dropTarget !== lastDropTarget) {
this._dispatchProxy(dropTarget, 'dragenter', e.event);
this.dispatchToElement(dropTarget, 'dragenter', e.event);
}

@@ -73,6 +73,6 @@ }

this._dispatchProxy(draggingTarget, 'dragend', e.event);
this.dispatchToElement(draggingTarget, 'dragend', e.event);
if (this._dropTarget) {
this._dispatchProxy(this._dropTarget, 'drop', e.event);
this.dispatchToElement(this._dropTarget, 'drop', e.event);
}

@@ -79,0 +79,0 @@

@@ -18,2 +18,3 @@ /*!

var Animation = require('./animation/Animation');
var HandlerProxy = require('./dom/HandlerProxy');

@@ -32,3 +33,3 @@ var useVML = !env.canvasSupported;

*/
zrender.version = '3.1.1';
zrender.version = '3.1.2';

@@ -127,6 +128,6 @@ /**

this.painter = painter;
if (!env.node) {
this.handler = new Handler(painter.getViewportRoot(), storage, painter);
}
var handerProxy = !env.node ? new HandlerProxy(painter.getViewportRoot()) : null;
this.handler = new Handler(storage, painter, handerProxy);
/**

@@ -293,3 +294,3 @@ * @type {module:zrender/animation/Animation}

this.painter.resize();
this.handler && this.handler.resize();
this.handler.resize();
},

@@ -347,3 +348,3 @@

setCursorStyle: function (cursorStyle) {
this.handler && this.handler.setCursorStyle(cursorStyle);
this.handler.setCursorStyle(cursorStyle);
},

@@ -359,3 +360,3 @@

on: function(eventName, eventHandler, context) {
this.handler && this.handler.on(eventName, eventHandler, context);
this.handler.on(eventName, eventHandler, context);
},

@@ -369,3 +370,3 @@

off: function(eventName, eventHandler) {
this.handler && this.handler.off(eventName, eventHandler);
this.handler.off(eventName, eventHandler);
},

@@ -380,3 +381,3 @@

trigger: function (eventName, event) {
this.handler && this.handler.trigger(eventName, event);
this.handler.trigger(eventName, event);
},

@@ -402,3 +403,3 @@

this.painter.dispose();
this.handler && this.handler.dispose();
this.handler.dispose();

@@ -405,0 +406,0 @@ this.animation =

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc