diff --git a/dist/paper-full.js b/dist/paper-full.js index b5148171..1f11c8bd 100644 --- a/dist/paper-full.js +++ b/dist/paper-full.js @@ -9,7 +9,7 @@ * * All rights reserved. * - * Date: Mon Apr 7 11:24:38 2014 +0200 + * Date: Wed May 7 17:35:17 2014 +0100 * *** * @@ -194,6 +194,10 @@ var Base = new function() { return each(this, iter, bind); }, + set: function(props) { + return set(this, props); + }, + clone: function() { return new this.constructor(this); }, @@ -261,8 +265,8 @@ Base.inject({ return Base.serialize(this); }, - _set: function(props, exclude) { - if (props && Base.isPlainObject(props)) { + _set: function(props, exclude, dontCheck) { + if (props && (dontCheck || Base.isPlainObject(props))) { var orig = props._filtering || props; for (var key in orig) { if (key in this && orig.hasOwnProperty(key) @@ -402,8 +406,9 @@ Base.inject({ return !!this.getNamed(list, name); }, - isPlainValue: function(obj) { - return this.isPlainObject(obj) || Array.isArray(obj); + isPlainValue: function(obj, asString) { + return this.isPlainObject(obj) || Array.isArray(obj) + || asString && typeof obj === 'string'; }, serialize: function(obj, options, compact, dictionary) { @@ -462,8 +467,7 @@ Base.inject({ }, deserialize: function(json, create, _data) { - var res = json, - isRoot = !_data; + var res = json; _data = _data || {}; if (Array.isArray(json)) { var type = json[0], @@ -481,7 +485,7 @@ Base.inject({ } else if (type) { var args = res; if (create) { - res = create(type, args, isRoot); + res = create(type, args); } else { res = Base.create(type.prototype); type.apply(res, args); @@ -505,13 +509,13 @@ Base.inject({ importJSON: function(json, target) { return Base.deserialize( typeof json === 'string' ? JSON.parse(json) : json, - function(type, args, isRoot) { + function(type, args) { var obj = target && target.constructor === type ? target : Base.create(type.prototype), isTarget = obj === target; - if (!isRoot && args.length === 1 && obj instanceof Item - && (!(obj instanceof Layer) || isTarget)) { + if (args.length === 1 && obj instanceof Item + && (isTarget || !(obj instanceof Layer))) { var arg = args[0]; if (Base.isPlainObject(arg)) arg.insert = false; @@ -691,11 +695,11 @@ var PaperScope = Base.extend({ initialize: function PaperScope(script) { paper = this; - this.settings = { + this.settings = new Base({ applyMatrix: true, handleSize: 4, hitTolerance: 0 - }; + }); this.project = null; this.projects = []; this.tools = []; @@ -725,8 +729,8 @@ var PaperScope = Base.extend({ return this; }, - execute: function(code) { - paper.PaperScript.execute(code, this); + execute: function(code, url, options) { + paper.PaperScript.execute(code, this, url, options); View.updateFocus(); }, @@ -2480,7 +2484,7 @@ var Project = PaperScopeItem.extend({ var point = Point.read(arguments), options = HitResult.getOptions(Base.read(arguments)); for (var i = this.layers.length - 1; i >= 0; i--) { - var res = this.layers[i].hitTest(point, options); + var res = this.layers[i]._hitTest(point, options); if (res) return res; } return null; @@ -2507,45 +2511,22 @@ var Project = PaperScopeItem.extend({ var param = new Base({ offset: new Point(0, 0), pixelRatio: pixelRatio, - trackTransforms: true, - transforms: [matrix] + viewMatrix: matrix.isIdentity() ? null : matrix, + matrices: [new Matrix()], + updateMatrix: true }); - for (var i = 0, l = this.layers.length; i < l; i++) - this.layers[i].draw(ctx, param); + for (var i = 0, layers = this.layers, l = layers.length; i < l; i++) + layers[i].draw(ctx, param); ctx.restore(); if (this._selectedItemCount > 0) { ctx.save(); ctx.strokeWidth = 1; - for (var id in this._selectedItems) { - var item = this._selectedItems[id], - globalMatrix = item._globalMatrix, - size = this._scope.settings.handleSize, - half = size / 2; - if (item._updateVersion === this._updateVersion - && (item._drawSelected || item._boundsSelected) - && globalMatrix) { - var color = item.getSelectedColor() - || item.getLayer().getSelectedColor(); - ctx.strokeStyle = ctx.fillStyle = color - ? color.toCanvasStyle(ctx) : '#009dec'; - if (item._drawSelected) - item._drawSelected(ctx, globalMatrix); - if (item._boundsSelected) { - var coords = globalMatrix._transformCorners( - item.getInternalBounds()); - ctx.beginPath(); - for (var i = 0; i < 8; i++) - ctx[i === 0 ? 'moveTo' : 'lineTo']( - coords[i], coords[++i]); - ctx.closePath(); - ctx.stroke(); - for (var i = 0; i < 8; i++) - ctx.fillRect(coords[i] - half, coords[++i] - half, - size, size); - } - } - } + var items = this._selectedItems, + size = this._scope.settings.handleSize, + updateVersion = this._updateVersion; + for (var id in items) + items[id]._drawSelection(ctx, matrix, size, updateVersion); ctx.restore(); } } @@ -2624,6 +2605,7 @@ var Item = Base.extend(Callback, { _selectChildren: false, _serializeFields: { name: null, + applyMatrix: null, matrix: new Matrix(), pivot: null, locked: false, @@ -2633,7 +2615,6 @@ var Item = Base.extend(Callback, { guide: false, selected: false, clipMask: false, - applyMatrix: null, data: {} }, @@ -2641,7 +2622,8 @@ var Item = Base.extend(Callback, { }, _initialize: function(props, point) { - var internal = props && props.internal === true, + var hasProps = props && Base.isPlainObject(props), + internal = hasProps && props.internal === true, matrix = this._matrix = new Matrix(), project = paper.project; if (!internal) @@ -2652,15 +2634,17 @@ var Item = Base.extend(Callback, { matrix._owner = this; this._style = new Style(project._currentStyle, this, project); if (!this._project) { - if (internal || props && props.insert === false) { + if (internal || hasProps && props.insert === false) { this._setProject(project); + } else if (hasProps && props.parent) { + this.setParent(props.parent); } else { (project.activeLayer || new Layer()).addChild(this); } } - return props && props !== Item.NO_INSERT - ? this._set(props, { insert: true }) - : true; + if (hasProps && props !== Item.NO_INSERT) + this._set(props, { insert: true, parent: true }, true); + return hasProps; }, _events: new function() { @@ -2785,7 +2769,7 @@ var Item = Base.extend(Callback, { set: function(props) { if (props) - this._set(props, { insert: true }); + this._set(props); return this; }, @@ -2828,18 +2812,6 @@ var Item = Base.extend(Callback, { setStyle: function(style) { this.getStyle().set(style); - }, - - hasFill: function() { - return this.getStyle().hasFill(); - }, - - hasStroke: function() { - return this.getStyle().hasStroke(); - }, - - hasShadow: function() { - return this.getStyle().hasShadow(); } }, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'], function(name) { @@ -2870,8 +2842,9 @@ var Item = Base.extend(Callback, { isSelected: function() { if (this._selectChildren) { - for (var i = 0, l = this._children.length; i < l; i++) - if (this._children[i].isSelected()) + var children = this._children; + for (var i = 0, l = children.length; i < l; i++) + if (children[i].isSelected()) return true; } return this._selected; @@ -2879,8 +2852,9 @@ var Item = Base.extend(Callback, { setSelected: function(selected, noChildren) { if (!noChildren && this._selectChildren) { - for (var i = 0, l = this._children.length; i < l; i++) - this._children[i].setSelected(selected); + var children = this._children; + for (var i = 0, l = children.length; i < l; i++) + children[i].setSelected(selected); } if ((selected = !!selected) ^ this._selected) { this._selected = selected; @@ -2892,9 +2866,10 @@ var Item = Base.extend(Callback, { _selected: false, isFullySelected: function() { - if (this._children && this._selected) { - for (var i = 0, l = this._children.length; i < l; i++) - if (!this._children[i].isFullySelected()) + var children = this._children; + if (children && this._selected) { + for (var i = 0, l = children.length; i < l; i++) + if (!children[i].isFullySelected()) return false; return true; } @@ -2902,9 +2877,10 @@ var Item = Base.extend(Callback, { }, setFullySelected: function(selected) { - if (this._children) { - for (var i = 0, l = this._children.length; i < l; i++) - this._children[i].setFullySelected(selected); + var children = this._children; + if (children) { + for (var i = 0, l = children.length; i < l; i++) + children[i].setFullySelected(selected); } this.setSelected(selected, true); }, @@ -2958,7 +2934,7 @@ var Item = Base.extend(Callback, { var pivot = this._pivot; if (pivot) { var ctor = _dontLink ? Point : LinkedPoint; - pivot = new ctor(pivot.x, pivot.y, this, 'setAnchor'); + pivot = new ctor(pivot.x, pivot.y, this, 'setPivot'); } return pivot; }, @@ -2983,7 +2959,7 @@ var Item = Base.extend(Callback, { name = !internalGetter && (typeof boundsGetter === 'string' ? boundsGetter : boundsGetter && boundsGetter[getter]) || getter, - bounds = this._getCachedBounds(name, _matrix, null, + bounds = this._getCachedBounds(name, _matrix, this, internalGetter); return key === 'bounds' ? new LinkedRectangle(bounds.x, bounds.y, bounds.width, @@ -3038,7 +3014,7 @@ var Item = Base.extend(Callback, { var _matrix = internalGetter ? null : this._matrix.orNullIfIdentity(), cache = (!matrix || matrix.equals(_matrix)) && getter; var cacheParent = this._parent || this._parentSymbol; - if (cacheItem && cacheParent) { + if (cacheParent) { var id = cacheItem._id, ref = cacheParent._boundsCache = cacheParent._boundsCache || { ids: {}, @@ -3057,7 +3033,7 @@ var Item = Base.extend(Callback, { ? matrix.clone().concatenate(_matrix) : matrix; var bounds = this._getBounds(internalGetter || getter, matrix, - cache ? this : cacheItem); + cacheItem); if (cache) { if (!this._bounds) this._bounds = {}; @@ -3073,11 +3049,13 @@ var Item = Base.extend(Callback, { for (var i = 0, list = item._boundsCache.list, l = list.length; i < l; i++) { var child = list[i]; - child._bounds = child._position = undefined; - if (child !== item && child._boundsCache) - Item._clearBoundsCache(child); + if (child !== item) { + child._bounds = child._position = undefined; + if (child._boundsCache) + Item._clearBoundsCache(child); + } } - item._boundsCache = undefined; + item._bounds = item._position = item._boundsCache = undefined; } } } @@ -3133,20 +3111,19 @@ var Item = Base.extend(Callback, { } }, - getGlobalMatrix: function(_internal) { + getGlobalMatrix: function(_dontClone) { var matrix = this._globalMatrix, - updateVersion = this._project._updateVersion, - viewMatrix = this.getView()._matrix; + updateVersion = this._project._updateVersion; if (matrix && matrix._updateVersion !== updateVersion) matrix = null; if (!matrix) { matrix = this._globalMatrix = this._matrix.clone(); - matrix.preConcatenate(this._parent - ? this._parent.getGlobalMatrix(true) - : viewMatrix); + var parent = this._parent; + if (parent) + matrix.preConcatenate(parent.getGlobalMatrix(true)); matrix._updateVersion = updateVersion; } - return _internal ? matrix : viewMatrix.inverted().concatenate(matrix); + return _dontClone ? matrix : matrix.clone(); }, getApplyMatrix: function() { @@ -3237,10 +3214,6 @@ var Item = Base.extend(Callback, { return this._index; }, - isInserted: function() { - return this._parent ? this._parent.isInserted() : false; - }, - equals: function(item) { return item === this || item && this._class === item._class && this._style.equals(item._style) @@ -3301,7 +3274,7 @@ var Item = Base.extend(Callback, { matrix = new Matrix().scale(scale).translate(topLeft.negate()); ctx.save(); matrix.applyToContext(ctx); - this.draw(ctx, new Base({ transforms: [matrix] })); + this.draw(ctx, new Base({ matrices: [matrix] })); ctx.restore(); var raster = new Raster(Item.NO_INSERT); raster.setCanvas(canvas); @@ -3327,9 +3300,13 @@ var Item = Base.extend(Callback, { return point.isInside(this.getInternalBounds()); }, - hitTest: function(point, options) { - point = Point.read(arguments); - options = HitResult.getOptions(Base.read(arguments)); + hitTest: function() { + return this._hitTest( + Point.read(arguments), + HitResult.getOptions(Base.read(arguments))); + }, + + _hitTest: function(point, options) { if (this._locked || !this._visible || this._guide && !options.guides || this.isEmpty()) return null; @@ -3339,8 +3316,7 @@ var Item = Base.extend(Callback, { view = this.getView(), totalMatrix = options._totalMatrix = parentTotalMatrix ? parentTotalMatrix.clone().concatenate(matrix) - : this.getGlobalMatrix().clone().preConcatenate( - view._matrix), + : this.getGlobalMatrix().preConcatenate(view._matrix), tolerancePadding = options._tolerancePadding = new Size( Path._getPenPadding(1, totalMatrix.inverted()) ).multiply( @@ -3351,12 +3327,10 @@ var Item = Base.extend(Callback, { if (!this._children && !this.getInternalRoughBounds() .expand(tolerancePadding.multiply(2))._containsPoint(point)) return null; - var type, - checkSelf = !(options.guides && !this._guide + var checkSelf = !(options.guides && !this._guide || options.selected && !this._selected - || (type = options.type) && (typeof type === 'string' - ? type !== Base.hyphenate(this._class) - : !(this instanceof type))), + || options.type && options.type !== Base.hyphenate(this._class) + || options.class && !(this instanceof options.class)), that = this, res; @@ -3385,10 +3359,10 @@ var Item = Base.extend(Callback, { if (children) { var opts = this._getChildHitTestOptions(options); for (var i = children.length - 1; i >= 0 && !res; i--) - res = children[i].hitTest(point, opts); + res = children[i]._hitTest(point, opts); } if (!res && checkSelf) - res = this._hitTest(point, options); + res = this._hitTestSelf(point, options); if (res && res.point) res.point = matrix.transform(res.point); options._totalMatrix = parentTotalMatrix; @@ -3399,11 +3373,11 @@ var Item = Base.extend(Callback, { return options; }, - _hitTest: function(point, options) { + _hitTestSelf: function(point, options) { if (options.fill && this.hasFill() && this._contains(point)) return new HitResult('fill', this); - } -}, { + }, + matches: function(match) { function matchObject(obj1, obj2) { for (var i in obj1) { @@ -3534,7 +3508,7 @@ var Item = Base.extend(Callback, { return null; var index = item._index + (above ? 1 : 0); if (item._parent === this._parent && index > this._index) - index--; + index--; return item._parent.insertChild(index, this, _preserve); }, @@ -3543,8 +3517,8 @@ var Item = Base.extend(Callback, { }, insertBelow: function(item, _preserve) { - return this._insert(false, item, _preserve); - }, + return this._insert(false, item, _preserve); + }, sendToBack: function() { return this._parent.insertChild(0, this); @@ -3644,7 +3618,7 @@ var Item = Base.extend(Callback, { }, isEmpty: function() { - return !this._children || this._children.length == 0; + return !this._children || this._children.length === 0; }, isEditable: function() { @@ -3657,6 +3631,18 @@ var Item = Base.extend(Callback, { return true; }, + hasFill: function() { + return this.getStyle().hasFill(); + }, + + hasStroke: function() { + return this.getStyle().hasStroke(); + }, + + hasShadow: function() { + return this.getStyle().hasShadow(); + }, + _getOrder: function(item) { function getList(item) { var list = []; @@ -3679,6 +3665,10 @@ var Item = Base.extend(Callback, { return this._children && this._children.length > 0; }, + isInserted: function() { + return this._parent ? this._parent.isInserted() : false; + }, + isAbove: function(item) { return this._getOrder(item) === -1; }, @@ -3756,7 +3746,7 @@ var Item = Base.extend(Callback, { fillColor = style.getFillColor(true), strokeColor = style.getStrokeColor(true); if (pivot) - pivot.transform(_matrix); + _matrix._transformPoint(pivot, pivot, true); if (fillColor) fillColor.transform(_matrix); if (strokeColor) @@ -3794,13 +3784,13 @@ var Item = Base.extend(Callback, { }, globalToLocal: function() { - var matrix = this.getGlobalMatrix(); - return matrix && matrix._inverseTransform(Point.read(arguments)); + return this.getGlobalMatrix(true)._inverseTransform( + Point.read(arguments)); }, localToGlobal: function() { - var matrix = this.getGlobalMatrix(); - return matrix && matrix._transformPoint(Point.read(arguments)); + return this.getGlobalMatrix(true)._transformPoint( + Point.read(arguments)); }, fitBounds: function(rectangle, fill) { @@ -3866,19 +3856,25 @@ var Item = Base.extend(Callback, { }, draw: function(ctx, param) { + var updateVersion = this._updateVersion = this._project._updateVersion; if (!this._visible || this._opacity === 0) return; - var updateVersion = this._updateVersion = this._project._updateVersion; - var trackTransforms = param.trackTransforms, - transforms = param.transforms, + var matrices = param.matrices, + parentMatrix = matrices[matrices.length - 1], + viewMatrix = param.viewMatrix, matrix = this._matrix, - parentMatrix = transforms[transforms.length - 1], globalMatrix = parentMatrix.clone().concatenate(matrix); if (!globalMatrix.isInvertible()) return; - if (trackTransforms) { - transforms.push(this._globalMatrix = globalMatrix); + + function getViewMatrix(matrix) { + return viewMatrix ? viewMatrix.clone().concatenate(matrix) : matrix; + } + + matrices.push(globalMatrix); + if (param.updateMatrix) { globalMatrix._updateVersion = updateVersion; + this._globalMatrix = globalMatrix; } var blendMode = this._blendMode, @@ -3891,7 +3887,7 @@ var Item = Base.extend(Callback, { && this._canComposite(), mainCtx, itemOffset, prevOffset; if (!direct) { - var bounds = this.getStrokeBounds(parentMatrix); + var bounds = this.getStrokeBounds(getViewMatrix(parentMatrix)); if (!bounds.width || !bounds.height) return; prevOffset = param.offset; @@ -3909,13 +3905,12 @@ var Item = Base.extend(Callback, { } else { ctx.translate(-itemOffset.x, -itemOffset.y); } - (direct ? matrix : globalMatrix).applyToContext(ctx); + (direct ? matrix : getViewMatrix(globalMatrix)).applyToContext(ctx); if (!direct && param.clipItem) param.clipItem.draw(ctx, param.extend({ clip: true })); this._draw(ctx, param); ctx.restore(); - if (trackTransforms) - transforms.pop(); + matrices.pop(); if (param.clip && !param.dontFinish) ctx.clip(); if (!direct) { @@ -3926,6 +3921,44 @@ var Item = Base.extend(Callback, { } }, + _isUpdated: function(updateVersion) { + var parent = this._parent; + if (parent instanceof CompoundPath) + return parent._isUpdated(updateVersion); + var updated = this._updateVersion === updateVersion; + if (!updated && parent && parent._visible + && parent._isUpdated(updateVersion)) { + this._updateVersion = updateVersion; + updated = true; + } + return updated; + }, + + _drawSelection: function(ctx, matrix, size, updateVersion) { + if ((this._drawSelected || this._boundsSelected) + && this._isUpdated(updateVersion)) { + var color = this.getSelectedColor(true) + || this.getLayer().getSelectedColor(true), + mx = matrix.clone().concatenate(this.getGlobalMatrix(true)); + ctx.strokeStyle = ctx.fillStyle = color + ? color.toCanvasStyle(ctx) : '#009dec'; + if (this._drawSelected) + this._drawSelected(ctx, mx); + if (this._boundsSelected) { + var half = size / 2; + coords = mx._transformCorners(this.getInternalBounds()); + ctx.beginPath(); + for (var i = 0; i < 8; i++) + ctx[i === 0 ? 'moveTo' : 'lineTo'](coords[i], coords[++i]); + ctx.closePath(); + ctx.stroke(); + for (var i = 0; i < 8; i++) + ctx.fillRect(coords[i] - half, coords[++i] - half, + size, size); + } + } + }, + _canComposite: function() { return false; } @@ -4317,7 +4350,7 @@ new function() { } }, - _hitTest: function _hitTest(point, options) { + _hitTestSelf: function _hitTestSelf(point, options) { var hit = false; if (this.hasStroke()) { var type = this._type, @@ -4345,7 +4378,7 @@ new function() { } return hit ? new HitResult('stroke', this) - : _hitTest.base.apply(this, arguments); + : _hitTestSelf.base.apply(this, arguments); } }; }, { @@ -4464,7 +4497,7 @@ var Raster = Item.extend({ }, isEmpty: function() { - return this._size.width == 0 && this._size.height == 0; + return this._size.width === 0 && this._size.height === 0; }, getPpi: function() { @@ -4485,7 +4518,7 @@ var Raster = Item.extend({ setImage: function(image) { if (this._canvas) CanvasProvider.release(this._canvas); - if (image.getContext) { + if (image && image.getContext) { this._image = null; this._canvas = image; } else { @@ -4493,8 +4526,8 @@ var Raster = Item.extend({ this._canvas = null; } this._size = new Size( - image.naturalWidth || image.width, - image.naturalHeight || image.height); + image ? image.naturalWidth || image.width : 0, + image ? image.naturalHeight || image.height : 0); this._context = null; this._changed(9 | 513); }, @@ -4563,9 +4596,11 @@ var Raster = Item.extend({ getElement: function() { return this._canvas || this._image; - }, + } +}, { + beans: false, - getSubCanvas: function(rect) { + getSubCanvas: function() { var rect = Rectangle.read(arguments), ctx = CanvasProvider.getContext(rect.getSize()); ctx.drawImage(this.getCanvas(), rect.x, rect.y, @@ -4573,7 +4608,7 @@ var Raster = Item.extend({ return ctx.canvas; }, - getSubRaster: function(rect) { + getSubRaster: function() { var rect = Rectangle.read(arguments), raster = new Raster(Item.NO_INSERT); raster.setCanvas(this.getSubCanvas(rect)); @@ -4624,7 +4659,7 @@ var Raster = Item.extend({ .translate(-bounds.x, -bounds.y); matrix.applyToContext(ctx); if (path) - path.draw(ctx, new Base({ clip: true, transforms: [matrix] })); + path.draw(ctx, new Base({ clip: true, matrices: [matrix] })); this._matrix.applyToContext(ctx); ctx.drawImage(this.getElement(), -this._size.width / 2, -this._size.height / 2); @@ -4646,7 +4681,7 @@ var Raster = Item.extend({ return total ? Color.read(channels) : null; }, - getPixel: function(point) { + getPixel: function() { var point = Point.read(arguments); var data = this.getContext().getImageData(point.x, point.y, 1, 1).data; return new Color('rgb', [data[0] / 255, data[1] / 255, data[2] / 255], @@ -4673,7 +4708,7 @@ var Raster = Item.extend({ return this.getContext().createImageData(size.width, size.height); }, - getImageData: function(rect) { + getImageData: function() { var rect = Rectangle.read(arguments); if (rect.isEmpty()) rect = new Rectangle(this._size); @@ -4691,7 +4726,7 @@ var Raster = Item.extend({ return matrix ? matrix._transformBounds(rect) : rect; }, - _hitTest: function(point) { + _hitTestSelf: function(point) { if (this._contains(point)) { var that = this; return new HitResult('pixel', that, { @@ -4763,8 +4798,8 @@ var PlacedSymbol = Item.extend({ cacheItem); }, - _hitTest: function(point, options) { - var res = this._symbol._definition.hitTest(point, options); + _hitTestSelf: function(point, options) { + var res = this._symbol._definition._hitTest(point, options); if (res) res.item = this; return res; @@ -4790,7 +4825,7 @@ var HitResult = Base.extend({ statics: { getOptions: function(options) { - return options && options._merged ? options : new Base({ + return new Base({ type: null, tolerance: paper.settings.hitTolerance, fill: !options, @@ -4801,8 +4836,7 @@ var HitResult = Base.extend({ center: false, bounds: false, guides: false, - selected: false, - _merged: true + selected: false }, options); } } @@ -4896,9 +4930,12 @@ var Segment = Base.extend({ return this._handleIn.isZero() && this._handleOut.isZero(); }, - setLinear: function() { - this._handleIn.set(0, 0); - this._handleOut.set(0, 0); + setLinear: function(linear) { + if (linear) { + this._handleIn.set(0, 0); + this._handleOut.set(0, 0); + } else { + } }, isColinear: function(segment) { @@ -5642,12 +5679,14 @@ statics: { }; }, { + beans: false, + getParameterAt: function(offset, start) { return Curve.getParameterAt(this.getValues(), offset, start !== undefined ? start : offset < 0 ? 1 : 0); }, - getParameterOf: function(point) { + getParameterOf: function() { var point = Point.read(arguments); return Curve.getParameterOf(this.getValues(), point.x, point.y); }, @@ -5658,13 +5697,13 @@ statics: { return new CurveLocation(this, offset); }, - getLocationOf: function(point) { + getLocationOf: function() { var point = Point.read(arguments), t = this.getParameterOf(point); return t != null ? new CurveLocation(this, t) : null; }, - getNearestLocation: function(point) { + getNearestLocation: function() { var point = Point.read(arguments), values = this.getValues(), count = 100, @@ -5696,9 +5735,8 @@ statics: { point.getDistance(pt)); }, - getNearestPoint: function(point) { - var point = Point.read(arguments); - return this.getNearestLocation(point).getPoint(); + getNearestPoint: function() { + return this.getNearestLocation.apply(this, arguments).getPoint(); } }), @@ -6679,6 +6717,24 @@ var Path = PathItem.extend({ clear: '#removeSegments', + getLength: function() { + if (this._length == null) { + var curves = this.getCurves(); + this._length = 0; + for (var i = 0, l = curves.length; i < l; i++) + this._length += curves[i].getLength(); + } + return this._length; + }, + + getArea: function() { + var curves = this.getCurves(); + var area = 0; + for (var i = 0, l = curves.length; i < l; i++) + area += curves[i].getArea(); + return area; + }, + isFullySelected: function() { var length = this._segments.length; return this._selected && length > 0 && this._selectedSegmentState @@ -6802,6 +6858,7 @@ var Path = PathItem.extend({ this._curves = null; if (this._clockwise !== undefined) this._clockwise = !this._clockwise; + this._changed(8); }, join: function(path) { @@ -6841,106 +6898,6 @@ var Path = PathItem.extend({ } }, - getLength: function() { - if (this._length == null) { - var curves = this.getCurves(); - this._length = 0; - for (var i = 0, l = curves.length; i < l; i++) - this._length += curves[i].getLength(); - } - return this._length; - }, - - getArea: function() { - var curves = this.getCurves(); - var area = 0; - for (var i = 0, l = curves.length; i < l; i++) - area += curves[i].getArea(); - return area; - }, - - _getOffset: function(location) { - var index = location && location.getIndex(); - if (index != null) { - var curves = this.getCurves(), - offset = 0; - for (var i = 0; i < index; i++) - offset += curves[i].getLength(); - var curve = curves[index], - parameter = location.getParameter(); - if (parameter > 0) - offset += curve.getPartLength(0, parameter); - return offset; - } - return null; - }, - - getLocationOf: function(point) { - var point = Point.read(arguments), - curves = this.getCurves(); - for (var i = 0, l = curves.length; i < l; i++) { - var loc = curves[i].getLocationOf(point); - if (loc) - return loc; - } - return null; - }, - - getLocationAt: function(offset, isParameter) { - var curves = this.getCurves(), - length = 0; - if (isParameter) { - var index = ~~offset; - return curves[index].getLocationAt(offset - index, true); - } - for (var i = 0, l = curves.length; i < l; i++) { - var start = length, - curve = curves[i]; - length += curve.getLength(); - if (length > offset) { - return curve.getLocationAt(offset - start); - } - } - if (offset <= this.getLength()) - return new CurveLocation(curves[curves.length - 1], 1); - return null; - }, - - getPointAt: function(offset, isParameter) { - var loc = this.getLocationAt(offset, isParameter); - return loc && loc.getPoint(); - }, - - getTangentAt: function(offset, isParameter) { - var loc = this.getLocationAt(offset, isParameter); - return loc && loc.getTangent(); - }, - - getNormalAt: function(offset, isParameter) { - var loc = this.getLocationAt(offset, isParameter); - return loc && loc.getNormal(); - }, - - getNearestLocation: function(point) { - var point = Point.read(arguments), - curves = this.getCurves(), - minDist = Infinity, - minLoc = null; - for (var i = 0, l = curves.length; i < l; i++) { - var loc = curves[i].getNearestLocation(point); - if (loc._distance < minDist) { - minDist = loc._distance; - minLoc = loc; - } - } - return minLoc; - }, - - getNearestPoint: function(point) { - var point = Point.read(arguments); - return this.getNearestLocation(point).getPoint(); - }, - toShape: function(insert) { if (!this._closed) return null; @@ -7008,7 +6965,7 @@ var Path = PathItem.extend({ return null; }, - _hitTest: function(point, options) { + _hitTestSelf: function(point, options) { var that = this, style = this.getStyle(), segments = this._segments, @@ -7018,11 +6975,14 @@ var Path = PathItem.extend({ strokePadding = tolerancePadding, join, cap, miterLimit, area, loc, res, - hasStroke = options.stroke && style.hasStroke(), - hasFill = options.fill && style.hasFill(), - radius = hasStroke ? style.getStrokeWidth() / 2 - : hasFill ? 0 : null; - if (radius != null) { + hitStroke = options.stroke && style.hasStroke(), + hitFill = options.fill && style.hasFill(), + hitCurves = options.curves, + radius = hitStroke + ? style.getStrokeWidth() / 2 + : hitFill && options.tolerance > 0 || hitCurves + ? 0 : null; + if (radius !== null) { if (radius > 0) { join = style.getStrokeJoin(); cap = style.getStrokeCap(); @@ -7094,7 +7054,7 @@ var Path = PathItem.extend({ if (res = checkSegmentPoints(segments[i])) return res; } - if (radius != null) { + if (radius !== null) { loc = this.getNearestLocation(point); if (loc) { var parameter = loc.getParameter(); @@ -7116,16 +7076,100 @@ var Path = PathItem.extend({ } } } - return !loc && hasFill && this._contains(point) || loc && !hasStroke - ? new HitResult('fill', this) - : loc - ? new HitResult('stroke', this, { - location: loc, - point: loc.getPoint() - }) - : null; + return !loc && hitFill && this._contains(point) + || loc && !hitStroke && !hitCurves + ? new HitResult('fill', this) + : loc + ? new HitResult(hitStroke ? 'stroke' : 'curve', this, { + location: loc, + point: loc.getPoint() + }) + : null; } +}, { + beans: false, + + _getOffset: function(location) { + var index = location && location.getIndex(); + if (index != null) { + var curves = this.getCurves(), + offset = 0; + for (var i = 0; i < index; i++) + offset += curves[i].getLength(); + var curve = curves[index], + parameter = location.getParameter(); + if (parameter > 0) + offset += curve.getPartLength(0, parameter); + return offset; + } + return null; + }, + + getLocationOf: function() { + var point = Point.read(arguments), + curves = this.getCurves(); + for (var i = 0, l = curves.length; i < l; i++) { + var loc = curves[i].getLocationOf(point); + if (loc) + return loc; + } + return null; + }, + + getLocationAt: function(offset, isParameter) { + var curves = this.getCurves(), + length = 0; + if (isParameter) { + var index = ~~offset; + return curves[index].getLocationAt(offset - index, true); + } + for (var i = 0, l = curves.length; i < l; i++) { + var start = length, + curve = curves[i]; + length += curve.getLength(); + if (length > offset) { + return curve.getLocationAt(offset - start); + } + } + if (offset <= this.getLength()) + return new CurveLocation(curves[curves.length - 1], 1); + return null; + }, + + getPointAt: function(offset, isParameter) { + var loc = this.getLocationAt(offset, isParameter); + return loc && loc.getPoint(); + }, + + getTangentAt: function(offset, isParameter) { + var loc = this.getLocationAt(offset, isParameter); + return loc && loc.getTangent(); + }, + + getNormalAt: function(offset, isParameter) { + var loc = this.getLocationAt(offset, isParameter); + return loc && loc.getNormal(); + }, + + getNearestLocation: function() { + var point = Point.read(arguments), + curves = this.getCurves(), + minDist = Infinity, + minLoc = null; + for (var i = 0, l = curves.length; i < l; i++) { + var loc = curves[i].getNearestLocation(point); + if (loc._distance < minDist) { + minDist = loc._distance; + minLoc = loc; + } + } + return minLoc; + }, + + getNearestPoint: function() { + return this.getNearestLocation.apply(this, arguments).getPoint(); + } }, new function() { function drawHandles(ctx, segments, matrix, size) { @@ -7681,7 +7725,7 @@ statics: { function addJoin(segment, join) { var handleIn = segment._handleIn, - handleOut = segment._handleOut + handleOut = segment._handleOut; if (join === 'round' || !handleIn.isZero() && !handleOut.isZero() && handleIn.isColinear(handleOut)) { addRound(segment); @@ -7768,7 +7812,7 @@ statics: { addPoint(point.add(normal)); } if (cap === 'square') - point = point.add(normal.rotate(loc.getParameter() == 0 ? -90 : 90)); + point = point.add(normal.rotate(loc.getParameter() === 0 ? -90 : 90)); addPoint(point.add(normal)); addPoint(point.subtract(normal)); }, @@ -7784,7 +7828,7 @@ statics: { var segment = segments[i]; segment._transformCoordinates(matrix, coords, false); for (var j = 0; j < 6; j += 2) { - var padding = j == 0 ? joinPadding : strokePadding, + var padding = j === 0 ? joinPadding : strokePadding, paddingX = padding ? padding[0] : 0, paddingY = padding ? padding[1] : 0, x = coords[j], @@ -8046,7 +8090,7 @@ var CompoundPath = PathItem.extend({ } }, { _getChildHitTestOptions: function(options) { - return options.type === 'path' + return options.class === Path || options.type === 'path' ? options : new Base(options, { fill: false }); }, @@ -8210,7 +8254,9 @@ PathItem.inject(new function() { _path1.remove(); if (_path2) _path2.remove(); - return result.reduce(); + result = result.reduce(); + result.setStyle(path1._style); + return result; } function splitPath(intersections) { @@ -8977,7 +9023,6 @@ var PointText = TextItem.extend({ }); var Color = Base.extend(new function() { - var types = { gray: ['gray'], rgb: ['red', 'green', 'blue'], @@ -9362,7 +9407,7 @@ var Color = Base.extend(new function() { }, equals: function(color) { - var col = Base.isPlainValue(color) + var col = Base.isPlainValue(color, true) ? Color.read(arguments) : color; return col === this || col && this._class === col._class @@ -9712,7 +9757,7 @@ var Style = Base.extend(new function() { justification: 9 }; - var item = {}, + var item = { beans: true }, fields = { _defaults: defaults, _textDefaults: new Base(defaults, { @@ -9785,8 +9830,8 @@ var Style = Base.extend(new function() { return value; }; - item[get] = function() { - return this._style[get](); + item[get] = function(_dontMerge) { + return this._style[get](_dontMerge); }; item[set] = function(value) { @@ -10401,8 +10446,8 @@ var View = Base.extend(Callback, { return this.getBounds().getCenter(); }, - setCenter: function(center) { - center = Point.read(arguments); + setCenter: function() { + var center = Point.read(arguments); this.scrollBy(center.subtract(this.getCenter())); }, @@ -10707,7 +10752,7 @@ var CanvasView = View.extend({ return; var project = this._project, hit = project.hitTest(point, { - tolerance: this._scope.settings.hitTolerance, + tolerance: 0, fill: true, stroke: true }), @@ -12083,7 +12128,7 @@ new function() { if (attrs.opacity === 1) delete attrs.opacity; - if (item._visibility != null && !item._visibility) + if (!item._visible) attrs.visibility = 'hidden'; return setAttributes(node, attrs); @@ -12130,9 +12175,12 @@ new function() { function exportSVG(item, options) { var exporter = exporters[item._class], node = exporter && exporter(item, options); - if (node && item._data) { + if (node) { + var onExport = options.onExport; + if (onExport) + node = onExport(item, node, options) || node; var data = JSON.stringify(item._data); - if (data !== '{}') + if (data && data !== '{}') node.setAttribute('data-paper-data', data); } return node && applyStyle(item, node); @@ -12475,6 +12523,10 @@ new function() { item.setVisible(value === 'visible'); }, + display: function(item, value) { + item.setVisible(value !== null); + }, + 'stop-color': function(item, value) { if (item.setColor) item.setColor(value); @@ -12603,6 +12655,9 @@ new function() { if (item) { if (!(item instanceof Group)) item = applyAttributes(item, node, isRoot); + var onImport = options.onImport; + if (onImport) + item = onImport(node, item, options) || item; if (options.expandShapes && item instanceof Shape) { item.remove(); item = item.toPath(); @@ -12634,6 +12689,19 @@ Base.exports.PaperScript = (function() { scope = this; !function(e,r){return"object"==typeof exports&&"object"==typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):(r(e.acorn||(e.acorn={})),void 0)}(this,function(e){"use strict";function r(e){fr=e||{};for(var r in hr)Object.prototype.hasOwnProperty.call(fr,r)||(fr[r]=hr[r]);mr=fr.sourceFile||null}function t(e,r){var t=vr(pr,e);r+=" ("+t.line+":"+t.column+")";var n=new SyntaxError(r);throw n.pos=e,n.loc=t,n.raisedAt=br,n}function n(e){function r(e){if(1==e.length)return t+="return str === "+JSON.stringify(e[0])+";";t+="switch(str){";for(var r=0;r3){n.sort(function(e,r){return r.length-e.length}),t+="switch(str.length){";for(var a=0;abr&&10!==t&&13!==t&&8232!==t&&8329!==t;)++br,t=pr.charCodeAt(br);fr.onComment&&fr.onComment(!1,pr.slice(e+2,br),e,br,r,fr.locations&&new a)}function u(){for(;dr>br;){var e=pr.charCodeAt(br);if(32===e)++br;else if(13===e){++br;var r=pr.charCodeAt(br);10===r&&++br,fr.locations&&(++Ar,Sr=br)}else if(10===e)++br,++Ar,Sr=br;else if(14>e&&e>8)++br;else if(47===e){var r=pr.charCodeAt(br+1);if(42===r)s();else{if(47!==r)break;c()}}else if(160===e)++br;else{if(!(e>=5760&&Jt.test(String.fromCharCode(e))))break;++br}}}function l(){var e=pr.charCodeAt(br+1);return e>=48&&57>=e?E(!0):(++br,i(xt))}function f(){var e=pr.charCodeAt(br+1);return Er?(++br,k()):61===e?x(Et,2):x(wt,1)}function p(){var e=pr.charCodeAt(br+1);return 61===e?x(Et,2):x(Ft,1)}function d(e){var r=pr.charCodeAt(br+1);return r===e?x(124===e?Lt:Ut,2):61===r?x(Et,2):x(124===e?Rt:Vt,1)}function m(){var e=pr.charCodeAt(br+1);return 61===e?x(Et,2):x(Tt,1)}function h(e){var r=pr.charCodeAt(br+1);return r===e?x(St,2):61===r?x(Et,2):x(At,1)}function v(e){var r=pr.charCodeAt(br+1),t=1;return r===e?(t=62===e&&62===pr.charCodeAt(br+2)?3:2,61===pr.charCodeAt(br+t)?x(Et,t+1):x(jt,t)):(61===r&&(t=61===pr.charCodeAt(br+2)?3:2),x(Ot,t))}function b(e){var r=pr.charCodeAt(br+1);return 61===r?x(qt,61===pr.charCodeAt(br+2)?3:2):x(61===e?Ct:It,1)}function y(e){switch(e){case 46:return l();case 40:return++br,i(ht);case 41:return++br,i(vt);case 59:return++br,i(yt);case 44:return++br,i(bt);case 91:return++br,i(ft);case 93:return++br,i(pt);case 123:return++br,i(dt);case 125:return++br,i(mt);case 58:return++br,i(gt);case 63:return++br,i(kt);case 48:var r=pr.charCodeAt(br+1);if(120===r||88===r)return C();case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return E(!1);case 34:case 39:return A(e);case 47:return f(e);case 37:case 42:return p();case 124:case 38:return d(e);case 94:return m();case 43:case 45:return h(e);case 60:case 62:return v(e);case 61:case 33:return b(e);case 126:return x(It,1)}return!1}function g(e){if(e?br=yr+1:yr=br,fr.locations&&(xr=new a),e)return k();if(br>=dr)return i(Br);var r=pr.charCodeAt(br);if(Qt(r)||92===r)return L();var n=y(r);if(n===!1){var o=String.fromCharCode(r);if("\\"===o||$t.test(o))return L();t(br,"Unexpected character '"+o+"'")}return n}function x(e,r){var t=pr.slice(br,br+r);br+=r,i(e,t)}function k(){for(var e,r,n="",a=br;;){br>=dr&&t(a,"Unterminated regular expression");var o=pr.charAt(br);if(Gt.test(o)&&t(a,"Unterminated regular expression"),e)e=!1;else{if("["===o)r=!0;else if("]"===o&&r)r=!1;else if("/"===o&&!r)break;e="\\"===o}++br}var n=pr.slice(a,br);++br;var s=I();return s&&!/^[gmsiy]*$/.test(s)&&t(a,"Invalid regexp flag"),i(jr,new RegExp(n,s))}function w(e,r){for(var t=br,n=0,a=0,o=null==r?1/0:r;o>a;++a){var i,s=pr.charCodeAt(br);if(i=s>=97?s-97+10:s>=65?s-65+10:s>=48&&57>=s?s-48:1/0,i>=e)break;++br,n=n*e+i}return br===t||null!=r&&br-t!==r?null:n}function C(){br+=2;var e=w(16);return null==e&&t(yr+2,"Expected hexadecimal number"),Qt(pr.charCodeAt(br))&&t(br,"Identifier directly after number"),i(Or,e)}function E(e){var r=br,n=!1,a=48===pr.charCodeAt(br);e||null!==w(10)||t(r,"Invalid number"),46===pr.charCodeAt(br)&&(++br,w(10),n=!0);var o=pr.charCodeAt(br);(69===o||101===o)&&(o=pr.charCodeAt(++br),(43===o||45===o)&&++br,null===w(10)&&t(r,"Invalid number"),n=!0),Qt(pr.charCodeAt(br))&&t(br,"Identifier directly after number");var s,c=pr.slice(r,br);return n?s=parseFloat(c):a&&1!==c.length?/[89]/.test(c)||Vr?t(r,"Invalid number"):s=parseInt(c,8):s=parseInt(c,10),i(Or,s)}function A(e){br++;for(var r="";;){br>=dr&&t(yr,"Unterminated string constant");var n=pr.charCodeAt(br);if(n===e)return++br,i(Fr,r);if(92===n){n=pr.charCodeAt(++br);var a=/^[0-7]+/.exec(pr.slice(br,br+3));for(a&&(a=a[0]);a&&parseInt(a,8)>255;)a=a.slice(0,a.length-1);if("0"===a&&(a=null),++br,a)Vr&&t(br-2,"Octal literal in strict mode"),r+=String.fromCharCode(parseInt(a,8)),br+=a.length-1;else switch(n){case 110:r+="\n";break;case 114:r+="\r";break;case 120:r+=String.fromCharCode(S(2));break;case 117:r+=String.fromCharCode(S(4));break;case 85:r+=String.fromCharCode(S(8));break;case 116:r+=" ";break;case 98:r+="\b";break;case 118:r+=" ";break;case 102:r+="\f";break;case 48:r+="\0";break;case 13:10===pr.charCodeAt(br)&&++br;case 10:fr.locations&&(Sr=br,++Ar);break;default:r+=String.fromCharCode(n)}}else(13===n||10===n||8232===n||8329===n)&&t(yr,"Unterminated string constant"),r+=String.fromCharCode(n),++br}}function S(e){var r=w(16,e);return null===r&&t(yr,"Bad character escape sequence"),r}function I(){Bt=!1;for(var e,r=!0,n=br;;){var a=pr.charCodeAt(br);if(Yt(a))Bt&&(e+=pr.charAt(br)),++br;else{if(92!==a)break;Bt||(e=pr.slice(n,br)),Bt=!0,117!=pr.charCodeAt(++br)&&t(br,"Expecting Unicode escape sequence \\uXXXX"),++br;var o=S(4),i=String.fromCharCode(o);i||t(br-1,"Invalid Unicode escape"),(r?Qt(o):Yt(o))||t(br-4,"Invalid Unicode escape"),e+=i}r=!1}return Bt?e:pr.slice(n,br)}function L(){var e=I(),r=Dr;return Bt||(Wt(e)?r=lt[e]:(fr.forbidReserved&&(3===fr.ecmaVersion?Mt:zt)(e)||Vr&&Xt(e))&&t(yr,"The keyword '"+e+"' is reserved")),i(r,e)}function U(){Ir=yr,Lr=gr,Ur=kr,g()}function R(e){for(Vr=e,br=Lr;Sr>br;)Sr=pr.lastIndexOf("\n",Sr-2)+1,--Ar;u(),g()}function T(){this.type=null,this.start=yr,this.end=null}function V(){this.start=xr,this.end=null,null!==mr&&(this.source=mr)}function q(){var e=new T;return fr.locations&&(e.loc=new V),fr.ranges&&(e.range=[yr,0]),e}function O(e){var r=new T;return r.start=e.start,fr.locations&&(r.loc=new V,r.loc.start=e.loc.start),fr.ranges&&(r.range=[e.range[0],0]),r}function j(e,r){return e.type=r,e.end=Lr,fr.locations&&(e.loc.end=Ur),fr.ranges&&(e.range[1]=Lr),e}function F(e){return fr.ecmaVersion>=5&&"ExpressionStatement"===e.type&&"Literal"===e.expression.type&&"use strict"===e.expression.value}function D(e){return wr===e?(U(),!0):void 0}function B(){return!fr.strictSemicolons&&(wr===Br||wr===mt||Gt.test(pr.slice(Lr,yr)))}function M(){D(yt)||B()||X()}function z(e){wr===e?U():X()}function X(){t(yr,"Unexpected token")}function N(e){"Identifier"!==e.type&&"MemberExpression"!==e.type&&t(e.start,"Assigning to rvalue"),Vr&&"Identifier"===e.type&&Nt(e.name)&&t(e.start,"Assigning to "+e.name+" in strict mode")}function W(e){Ir=Lr=br,fr.locations&&(Ur=new a),Rr=Vr=null,Tr=[],g();var r=e||q(),t=!0;for(e||(r.body=[]);wr!==Br;){var n=J();r.body.push(n),t&&F(n)&&R(!0),t=!1}return j(r,"Program")}function J(){wr===wt&&g(!0);var e=wr,r=q();switch(e){case Mr:case Nr:U();var n=e===Mr;D(yt)||B()?r.label=null:wr!==Dr?X():(r.label=lr(),M());for(var a=0;ar){var a=O(e);a.left=e,a.operator=Cr,U(),a.right=er(rr(),n,t);var a=j(a,/&&|\|\|/.test(a.operator)?"LogicalExpression":"BinaryExpression");return er(a,r,t)}return e}function rr(){if(wr.prefix){var e=q(),r=wr.isUpdate;return e.operator=Cr,e.prefix=!0,U(),e.argument=rr(),r?N(e.argument):Vr&&"delete"===e.operator&&"Identifier"===e.argument.type&&t(e.start,"Deleting local variable in strict mode"),j(e,r?"UpdateExpression":"UnaryExpression")}for(var n=tr();wr.postfix&&!B();){var e=O(n);e.operator=Cr,e.prefix=!1,e.argument=n,N(n),U(),n=j(e,"UpdateExpression")}return n}function tr(){return nr(ar())}function nr(e,r){if(D(xt)){var t=O(e);return t.object=e,t.property=lr(!0),t.computed=!1,nr(j(t,"MemberExpression"),r)}if(D(ft)){var t=O(e);return t.object=e,t.property=K(),t.computed=!0,z(pt),nr(j(t,"MemberExpression"),r)}if(!r&&D(ht)){var t=O(e);return t.callee=e,t.arguments=ur(vt,!1),nr(j(t,"CallExpression"),r)}return e}function ar(){switch(wr){case ot:var e=q();return U(),j(e,"ThisExpression");case Dr:return lr();case Or:case Fr:case jr:var e=q();return e.value=Cr,e.raw=pr.slice(yr,gr),U(),j(e,"Literal");case it:case st:case ct:var e=q();return e.value=wr.atomValue,e.raw=wr.keyword,U(),j(e,"Literal");case ht:var r=xr,t=yr;U();var n=K();return n.start=t,n.end=gr,fr.locations&&(n.loc.start=r,n.loc.end=kr),fr.ranges&&(n.range=[t,gr]),z(vt),n;case ft:var e=q();return U(),e.elements=ur(pt,!0,!0),j(e,"ArrayExpression");case dt:return ir();case Gr:var e=q();return U(),cr(e,!1);case at:return or();default:X()}}function or(){var e=q();return U(),e.callee=nr(ar(),!0),e.arguments=D(ht)?ur(vt,!1):qr,j(e,"NewExpression")}function ir(){var e=q(),r=!0,n=!1;for(e.properties=[],U();!D(mt);){if(r)r=!1;else if(z(bt),fr.allowTrailingCommas&&D(mt))break;var a,o={key:sr()},i=!1;if(D(gt)?(o.value=K(!0),a=o.kind="init"):fr.ecmaVersion>=5&&"Identifier"===o.key.type&&("get"===o.key.name||"set"===o.key.name)?(i=n=!0,a=o.kind=o.key.name,o.key=sr(),wr!==ht&&X(),o.value=cr(q(),!1)):X(),"Identifier"===o.key.type&&(Vr||n))for(var s=0;si?e.id:e.params[i];if((Xt(s.name)||Nt(s.name))&&t(s.start,"Defining '"+s.name+"' in strict mode"),i>=0)for(var c=0;i>c;++c)s.name===e.params[c].name&&t(s.start,"Argument name clash in strict mode")}return j(e,r?"FunctionDeclaration":"FunctionExpression")}function ur(e,r,t){for(var n=[],a=!0;!D(e);){if(a)a=!1;else if(z(bt),r&&fr.allowTrailingCommas&&D(e))break;t&&wr===bt?n.push(null):n.push(K(!0))}return n}function lr(e){var r=q();return r.name=wr===Dr?Cr:e&&!fr.forbidReserved&&wr.keyword||X(),U(),j(r,"Identifier")}e.version="0.3.2";var fr,pr,dr,mr;e.parse=function(e,t){return pr=String(e),dr=pr.length,r(t),o(),W(fr.program)};var hr=e.defaultOptions={ecmaVersion:5,strictSemicolons:!1,allowTrailingCommas:!0,forbidReserved:!1,locations:!1,onComment:null,ranges:!1,program:null,sourceFile:null},vr=e.getLineInfo=function(e,r){for(var t=1,n=0;;){Kt.lastIndex=n;var a=Kt.exec(e);if(!(a&&a.indexe?36===e:91>e?!0:97>e?95===e:123>e?!0:e>=170&&$t.test(String.fromCharCode(e))},Yt=e.isIdentifierChar=function(e){return 48>e?36===e:58>e?!0:65>e?!1:91>e?!0:97>e?95===e:123>e?!0:e>=170&&_t.test(String.fromCharCode(e))},Zt={kind:"loop"},en={kind:"switch"}}); + var ua = navigator.userAgent, + match = ua.match(/(opera|chrome|safari|firefox|msie|trident)\/?\s*([.\d]+)(?:.*rv\:([.\d]+))?/i) || [], + name = match[1].toLowerCase(), + version = match[2]; + if (name === 'trident') { + version = match[3]; + name = 'msie'; + } else if (match = ua.match(/version\/([.\d]+)/i)) { + version = match[1]; + } + var browser = { name: name, version: parseFloat(version) }; + browser[name] = true; + var binaryOperators = { '+': '__add', '-': '__subtract', @@ -12687,7 +12755,15 @@ Base.exports.PaperScript = (function() { } } - function compile(code) { + function parse(code, options) { + return scope.acorn.parse(code, options); + } + + function compile(code, url, options) { + if (!code) + return ''; + options = options || {}; + url = url || ''; var insertions = []; @@ -12724,7 +12800,7 @@ Base.exports.PaperScript = (function() { if (!node) return; for (var key in node) { - if (key === 'range') + if (key === 'range' || key === 'loc') continue; var value = node[key]; if (Array.isArray(value)) { @@ -12734,7 +12810,7 @@ Base.exports.PaperScript = (function() { walkAST(value, node); } } - switch (node && node.type) { + switch (node.type) { case 'UnaryExpression': if (node.operator in unaryOperators && node.argument.type !== 'Literal') { @@ -12779,11 +12855,45 @@ Base.exports.PaperScript = (function() { break; } } - walkAST(scope.acorn.parse(code, { ranges: true })); + var sourceMap = null, + version = browser.version, + lineBreaks = /\r\n|\n|\r/mg; + if (browser.chrome && version >= 30 + || browser.safari && version >= 7 + || browser.firefox && version >= 23) { + var offset = 0; + if (url === window.location.href) { + var html = document.getElementsByTagName('html')[0].innerHTML; + offset = html.substr(0, html.indexOf(code) + 1).match( + lineBreaks).length + 1; + } + var mappings = ['AAAA']; + mappings.length = code.match(lineBreaks).length + 1 + offset; + sourceMap = { + version: 3, + file: url, + names:[], + mappings: mappings.join(';AACA'), + sourceRoot: '', + sources: [url] + }; + var source = options.source || !url && code; + if (source) + sourceMap.sourcesContent = [source]; + } + walkAST(parse(code, { ranges: true })); + + if (sourceMap) { + code = new Array(offset + 1).join('\n') + code + + "\n//# sourceMappingURL=data:application/json;base64," + + (btoa(unescape(encodeURIComponent( + JSON.stringify(sourceMap))))) + + "\n//# sourceURL=" + (url || 'paperscript'); + } return code; } - function execute(code, scope) { + function execute(code, scope, url, options) { paper = scope; var view = scope.getView(), tool = /\s+on(?:Key|Mouse)(?:Up|Down|Move|Drag)\b/.test(code) @@ -12794,7 +12904,7 @@ Base.exports.PaperScript = (function() { params = [], args = [], func; - code = compile(code); + code = compile(code, url, options); function expose(scope, hidden) { for (var key in scope) { if ((hidden || !/^_/.test(key)) && new RegExp( @@ -12804,7 +12914,7 @@ Base.exports.PaperScript = (function() { } } } - expose({ _$_: _$_, $_: $_, view: view, tool: tool }, true); + expose({ _$_: _$_, $_: $_, paper: scope, view: view, tool: tool }, true); expose(scope); handlers = Base.each(handlers, function(key) { if (new RegExp('\\s+' + key + '\\b').test(code)) { @@ -12814,11 +12924,10 @@ Base.exports.PaperScript = (function() { }, []).join(', '); if (handlers) code += '\nreturn { ' + handlers + ' };'; - var firefox = window.InstallTrigger; - if (firefox || window.chrome) { + if (browser.chrome || browser.firefox) { var script = document.createElement('script'), head = document.head; - if (firefox) + if (browser.firefox) code = '\n' + code; script.appendChild(document.createTextNode( 'paper._execute = function(' + params + ') {' + code + '\n}' @@ -12859,10 +12968,10 @@ Base.exports.PaperScript = (function() { src = script.src; if (src) { Http.request('get', src, function(code) { - execute(code, scope); + execute(code, scope, src); }); } else { - execute(script.innerHTML, scope); + execute(script.innerHTML, scope, script.baseURI); } script.setAttribute('data-paper-ignore', true); } @@ -12879,7 +12988,7 @@ Base.exports.PaperScript = (function() { compile: compile, execute: execute, load: load, - lineNumberBase: 0 + parse: parse }; }).call(this);