diff --git a/.gitignore b/.gitignore index b1f31aab..57a51e92 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -node_modules .DS_Store +/node_modules/ +/npm-debug.log before_commit diff --git a/.jshintrc b/.jshintrc index bc589f4d..c05b47de 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,49 +1,41 @@ { "globals": { + "ActiveXObject": true, + "Cufon": true, "define": true, + "Event": true, "exports": true, "fabric": true, - "Cufon": true, - "Event": true, - "G_vmlCanvasManager": true, - "ActiveXObject": true + "G_vmlCanvasManager": true }, - "node": true, - "es5": false, "browser": true, - - "boss": false, - "curly": false, - "debug": false, - "devel": false, "eqeqeq": true, "eqnull": true, "evil": true, "expr": true, "forin": false, "immed": true, + "lastsemic": true, "laxbreak": true, "loopfunc": true, "multistr": true, "newcap": true, "noarg": true, + "node": true, "noempty": false, - "nonew": false, "nomen": false, + "nonew": false, "onevar": false, "plusplus": false, - "regexp": false, - "undef": true, - "sub": true, "strict": false, - "white": false, + "sub": true, + "undef": true, "unused": true, - "lastsemic": true, - // "maxparams": 4 // "maxcomplexity": 7 - // "maxlen": 100 "maxdepth": 4, + // "maxlen": 100 + // "maxparams": 4 "maxstatements": 30 } diff --git a/README.md b/README.md index 743fb12e..1d2b22cf 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ [![Code Climate](https://codeclimate.com/repos/526a0ed089af7e6cf2001389/badges/d1c922dd1511ffa8a72f/gpa.png)](https://codeclimate.com/repos/526a0ed089af7e6cf2001389/feed) [![Coverage Status](https://coveralls.io/repos/kangax/fabric.js/badge.png?branch=master)](https://coveralls.io/r/kangax/fabric.js?branch=master) -[![Dependency Status](https://gemnasium.com/kangax/fabric.js.png)](https://gemnasium.com/kangax/fabric.js) +[![Dependency Status](https://david-dm.org/kangax/fabric.js.png?theme=shields.io)](https://david-dm.org/kangax/fabric.js) +[![devDependency Status](https://david-dm.org/kangax/fabric.js/dev-status.png?theme=shields.io)](https://david-dm.org/kangax/fabric.js#info=devDependencies) **Fabric.js** is a framework that makes it easy to work with HTML5 canvas element. It is an **interactive object model** on top of canvas element. It is also an **SVG-to-canvas parser**. @@ -160,29 +161,29 @@ For example: #### Adding red rectangle to canvas ```html - - - - - - + + + + + + - - + - - + canvas.add(rect); + + + ``` ### Helping Fabric @@ -231,4 +232,3 @@ SOFTWARE. [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/kangax/fabric.js/trend.png)](https://bitdeli.com/free "Bitdeli Badge") - diff --git a/lib/excanvas-diff.patch b/lib/excanvas-diff.patch index 2b7d64cc..37ad3c8b 100644 --- a/lib/excanvas-diff.patch +++ b/lib/excanvas-diff.patch @@ -6,7 +6,7 @@ Index: excanvas.js o2.arcScaleX_ = o1.arcScaleX_; o2.arcScaleY_ = o1.arcScaleY_; o2.lineScale_ = o1.lineScale_; -+ o2.rotation_ = o1.rotation_; // used for images ++ o2.rotation_ = o1.rotation_; // used for images } var colorData = { @@ -14,7 +14,7 @@ Index: excanvas.js this.arcScaleX_ = 1; this.arcScaleY_ = 1; this.lineScale_ = 1; -+ this.rotation_ = 0; ++ this.rotation_ = 0; } var contextPrototype = CanvasRenderingContext2D_.prototype; @@ -26,10 +26,10 @@ Index: excanvas.js + contextPrototype.drawImage = function(image) { var dx, dy, dw, dh, sx, sy, sw, sh; - -+ ++ + // to fix new Image() we check the existance of runtimeStyle + var rts = image.runtimeStyle.width; -+ ++ // to find the original width we overide the width and height - var oldRuntimeWidth = image.runtimeStyle.width; - var oldRuntimeHeight = image.runtimeStyle.height; @@ -38,25 +38,25 @@ Index: excanvas.js + if(rts) { + var oldRuntimeWidth = image.runtimeStyle.width; + var oldRuntimeHeight = image.runtimeStyle.height; -+ ++ + image.runtimeStyle.width = 'auto'; -+ image.runtimeStyle.height = 'auto'; ++ image.runtimeStyle.height = 'auto'; + } // get the original size var w = image.width; var h = image.height; - -+ ++ // and remove overides - image.runtimeStyle.width = oldRuntimeWidth; - image.runtimeStyle.height = oldRuntimeHeight; - + if(rts) { + image.runtimeStyle.width = oldRuntimeWidth; -+ image.runtimeStyle.height = oldRuntimeHeight; ++ image.runtimeStyle.height = oldRuntimeHeight; + } -+ ++ if (arguments.length == 3) { dx = arguments[1]; dy = arguments[2]; @@ -64,9 +64,9 @@ Index: excanvas.js var W = 10; var H = 10; -+ ++ + var scaleX = scaleY = 1; -+ ++ + // FIX: divs give better quality then vml image and also fixes transparent PNG's + vmlStr.push('
'); + } -+ -+ ++ ++ + // Apply scales to width and height + vmlStr.push('
'); -+ -+ // Close the crop div if necessary ++ ++ // Close the crop div if necessary + if (sx || sy) vmlStr.push('
'); -+ ++ + vmlStr.push('
'); -+ ++ + this.element_.insertAdjacentHTML('beforeEnd', vmlStr.join('')); }; @@ -176,8 +176,8 @@ Index: excanvas.js var c = mc(aRot); var s = ms(aRot); -+ this.rotation_ += aRot; -+ ++ this.rotation_ += aRot; ++ var m1 = [ [c, s, 0], [-s, c, 0], @@ -188,7 +188,7 @@ Index: excanvas.js - this.textMeasureEl_.style.font = this.font; + // FIX: Apply current font style to textMeasureEl to get correct size + var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_), -+ fontStyleString = buildStyle(fontStyle); ++ fontStyleString = buildStyle(fontStyle); + this.textMeasureEl_.style.font = fontStyleString; + // Don't use innerHTML or innerText because they allow markup/whitespace. diff --git a/lib/excanvas.js b/lib/excanvas.js index a6dceecb..b95043cf 100644 --- a/lib/excanvas.js +++ b/lib/excanvas.js @@ -253,7 +253,7 @@ if (!document.createElement('canvas').getContext) { o2.arcScaleX_ = o1.arcScaleX_; o2.arcScaleY_ = o1.arcScaleY_; o2.lineScale_ = o1.lineScale_; - o2.rotation_ = o1.rotation_; // used for images + o2.rotation_ = o1.rotation_; // used for images } var colorData = { @@ -604,7 +604,7 @@ if (!document.createElement('canvas').getContext) { this.arcScaleX_ = 1; this.arcScaleY_ = 1; this.lineScale_ = 1; - this.rotation_ = 0; + this.rotation_ = 0; } var contextPrototype = CanvasRenderingContext2D_.prototype; @@ -771,29 +771,29 @@ if (!document.createElement('canvas').getContext) { contextPrototype.drawImage = function(image) { var dx, dy, dw, dh, sx, sy, sw, sh; - + // to fix new Image() we check the existance of runtimeStyle var rts = image.runtimeStyle.width; - + // to find the original width we overide the width and height if(rts) { var oldRuntimeWidth = image.runtimeStyle.width; var oldRuntimeHeight = image.runtimeStyle.height; - + image.runtimeStyle.width = 'auto'; - image.runtimeStyle.height = 'auto'; + image.runtimeStyle.height = 'auto'; } // get the original size var w = image.width; var h = image.height; - + // and remove overides if(rts) { image.runtimeStyle.width = oldRuntimeWidth; - image.runtimeStyle.height = oldRuntimeHeight; + image.runtimeStyle.height = oldRuntimeHeight; } - + if (arguments.length == 3) { dx = arguments[1]; dy = arguments[2]; @@ -830,9 +830,9 @@ if (!document.createElement('canvas').getContext) { var W = 10; var H = 10; - + var scaleX = scaleY = 1; - + // FIX: divs give better quality then vml image and also fixes transparent PNG's vmlStr.push('
'); } - - + + // Apply scales to width and height vmlStr.push('
'); - - // Close the crop div if necessary + + // Close the crop div if necessary if (sx || sy) vmlStr.push('
'); - + vmlStr.push('
'); - + this.element_.insertAdjacentHTML('beforeEnd', vmlStr.join('')); }; @@ -1198,8 +1198,8 @@ if (!document.createElement('canvas').getContext) { var c = mc(aRot); var s = ms(aRot); - this.rotation_ += aRot; - + this.rotation_ += aRot; + var m1 = [ [c, s, 0], [-s, c, 0], @@ -1355,7 +1355,7 @@ if (!document.createElement('canvas').getContext) { this.textMeasureEl_.innerHTML = ''; // FIX: Apply current font style to textMeasureEl to get correct size var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_), - fontStyleString = buildStyle(fontStyle); + fontStyleString = buildStyle(fontStyle); this.textMeasureEl_.style.font = fontStyleString; // Don't use innerHTML or innerText because they allow markup/whitespace. diff --git a/lib/json2.js b/lib/json2.js index a43520a6..deb88ec9 100644 --- a/lib/json2.js +++ b/lib/json2.js @@ -1,6 +1,6 @@ /* json2.js - 2011-10-19 + 2014-02-04 Public Domain. @@ -159,8 +159,7 @@ // Create a JSON object only if one does not already exist. We create the // methods in a closure to avoid creating global variables. -var JSON; -if (!JSON) { +if (typeof JSON !== 'object') { JSON = {}; } @@ -174,8 +173,7 @@ if (!JSON) { if (typeof Date.prototype.toJSON !== 'function') { - /** @ignore */ - Date.prototype.toJSON = function (key) { + Date.prototype.toJSON = function () { return isFinite(this.valueOf()) ? this.getUTCFullYear() + '-' + @@ -189,25 +187,16 @@ if (!JSON) { String.prototype.toJSON = Number.prototype.toJSON = - /** @ignore */ - Boolean.prototype.toJSON = function (key) { + Boolean.prototype.toJSON = function () { return this.valueOf(); }; } - var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + var cx, + escapable, gap, indent, - meta = { // table of character substitutions - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '"' : '\\"', - '\\': '\\\\' - }, + meta, rep; @@ -359,7 +348,16 @@ if (!JSON) { // If the JSON object does not yet have a stringify method, give it one. if (typeof JSON.stringify !== 'function') { - /** @ignore */ + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }; JSON.stringify = function (value, replacer, space) { // The stringify method takes a value and an optional replacer, and an optional @@ -407,7 +405,7 @@ if (!JSON) { // If the JSON object does not yet have a parse method, give it one. if (typeof JSON.parse !== 'function') { - /** @ignore */ + cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; JSON.parse = function (text, reviver) { // The parse method takes a text and an optional reviver function, and returns @@ -488,4 +486,4 @@ if (!JSON) { throw new SyntaxError('JSON.parse'); }; } -}()); \ No newline at end of file +}()); diff --git a/lib/screenshot.png b/lib/screenshot.png index 27c2b3b7..1135d4cd 100644 Binary files a/lib/screenshot.png and b/lib/screenshot.png differ diff --git a/package.json b/package.json index 41862e7a..1e3ff676 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,29 @@ "homepage": "http://fabricjs.com/", "version": "1.4.4", "author": "Juriy Zaytsev ", - "keywords": ["canvas", "graphic", "graphics", "SVG", "node-canvas", "parser", "HTML5", "object model"], - "repository": "git://github.com/kangax/fabric.js", - "licenses": [{ - "type": "MIT", - "url": "http://github.com/kangax/fabric.js/raw/master/LICENSE" - }], + "keywords": [ + "canvas", + "graphic", + "graphics", + "SVG", + "node-canvas", + "parser", + "HTML5", + "object model" + ], + "repository": { + "type": "git", + "url": "https://github.com/kangax/fabric.js" + }, + "bugs": { + "url": "https://github.com/kangax/fabric.js/issues" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/kangax/fabric.js/raw/master/LICENSE" + } + ], "scripts": { "build": "node build.js modules=ALL exclude=json,cufon,gestures", "test": "node test.js && jshint src" @@ -20,12 +37,14 @@ "xmldom": "0.1.x" }, "devDependencies": { - "qunit": "0.5.x", - "jshint": "2.4.x", - "uglify-js": "2.4.x", + "execSync": "0.0.x", "jscs": "1.2.x", - "execSync": "0.0.x" + "jshint": "2.4.x", + "qunit": "0.5.x", + "uglify-js": "2.4.x" + }, + "engines": { + "node": ">=0.4.0 && <1.0.0" }, - "engines": { "node": ">=0.4.0 && <1.0.0" }, "main": "./dist/fabric.js" } diff --git a/src/canvas.class.js b/src/canvas.class.js index 7c1a66a3..4b040283 100644 --- a/src/canvas.class.js +++ b/src/canvas.class.js @@ -820,7 +820,7 @@ else { cssScale = { width: this.upperCanvasEl.width / bounds.width, - height: this.upperCanvasEl.height / bounds.height, + height: this.upperCanvasEl.height / bounds.height }; } return { diff --git a/src/shapes/line.class.js b/src/shapes/line.class.js index 2d1b519e..52309ed9 100644 --- a/src/shapes/line.class.js +++ b/src/shapes/line.class.js @@ -119,12 +119,12 @@ origin: 'originX', axis1: 'x1', axis2: 'x2', - dimension: 'width', + dimension: 'width' }, { // possible values of origin nearest: 'left', center: 'center', - farthest: 'right', + farthest: 'right' } ), @@ -137,12 +137,12 @@ origin: 'originY', axis1: 'y1', axis2: 'y2', - dimension: 'height', + dimension: 'height' }, { // possible values of origin nearest: 'top', center: 'center', - farthest: 'bottom', + farthest: 'bottom' } ), diff --git a/test/lib/event.simulate.js b/test/lib/event.simulate.js index 290f873d..74194a8d 100644 --- a/test/lib/event.simulate.js +++ b/test/lib/event.simulate.js @@ -1,6 +1,6 @@ /** * simulateEvent(@element, eventName[, options]) -> Element - * + * * - @element: element to fire event on * - eventName: name of event to fire (only MouseEvents and HTMLEvents interfaces are supported) * - options: optional object to fine-tune event properties - pointerX, pointerY, ctrlKey, etc. @@ -29,44 +29,44 @@ bubbles: true, cancelable: true }; - + global.simulateEvent = function(element, eventName) { - + var options = extendObject(extendObject({ }, defaultOptions), arguments[2] || { }), - oEvent, + oEvent, eventType; - + element = typeof element == 'string' ? document.getElementById(element) : element; - + for (var name in eventMatchers) { if (eventMatchers[name].test(eventName)) { - eventType = name; - break; + eventType = name; + break; } } - + if (!eventType) { throw new SyntaxError('This event is not supported'); } - + if (document.createEvent) { try { - // Opera doesn't support event types like "KeyboardEvent", + // Opera doesn't support event types like "KeyboardEvent", // but allows to create event of type "HTMLEvents", then fire key event on it oEvent = document.createEvent(eventType); } catch(err) { oEvent = document.createEvent('HTMLEvents'); } - + if (eventType == 'HTMLEvents') { oEvent.initEvent(eventName, options.bubbles, options.cancelable); } else if (eventType === 'KeyboardEvent') { // TODO (kangax): this needs to be tested if (oEvent.initKeyEvent) { - oEvent.initKeyEvent(eventName, options.bubbles, options.cancelable, document.defaultView, - options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.keyCode, + oEvent.initKeyEvent(eventName, options.bubbles, options.cancelable, document.defaultView, + options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.keyCode, options.charCode); } else if (oEvent.initEvent) { @@ -74,7 +74,7 @@ } } else { - oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView, + oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView, options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element); }