magicpen-media
Advanced tools
Comparing version 1.5.1 to 1.5.2
/*global URL, Blob, btoa*/ | ||
var _ = require('lodash'), | ||
fs = require('fs'), | ||
pathModule = require('path'), | ||
mime = require('mime'), | ||
getTemporaryFilePath = require('gettemporaryfilepath'); | ||
const _ = require('lodash'); | ||
const fs = require('fs'); | ||
const pathModule = require('path'); | ||
const mime = require('mime'); | ||
const getTemporaryFilePath = require('gettemporaryfilepath'); | ||
function sanitizeContentType(contentType) { | ||
return contentType && contentType.trim().replace(/\s*;.*$/, ''); // Strip charset etc. | ||
return contentType && contentType.trim().replace(/\s*;.*$/, ''); // Strip charset etc. | ||
} | ||
function entitify(value) { | ||
return String(value).replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<'); | ||
return String(value) | ||
.replace(/&/g, '&') | ||
.replace(/"/g, '"') | ||
.replace(/</g, '<'); | ||
} | ||
module.exports = { | ||
name: 'magicpen-media', | ||
version: require('../package.json').version, | ||
installInto: function (magicPen) { | ||
magicPen.addStyle('media', function (media, options) { | ||
if (typeof options === 'string') { | ||
options = { contentType: options }; | ||
} else { | ||
options = options || {}; | ||
} | ||
name: 'magicpen-media', | ||
version: require('../package.json').version, | ||
installInto(magicPen) { | ||
magicPen.addStyle('media', function(media, options) { | ||
if (typeof options === 'string') { | ||
options = { contentType: options }; | ||
} else { | ||
options = options || {}; | ||
} | ||
var contentType = options.contentType; | ||
var majorContentType = typeof contentType === 'string' && contentType.replace(/\/.*/, ''); | ||
var width = options.width || 0; | ||
var height = options.height || 0; | ||
var alt = options.alt; | ||
var title = options.title; | ||
var fallbackToDisc = options.fallbackToDisc; | ||
let contentType = options.contentType; | ||
const majorContentType = | ||
typeof contentType === 'string' && contentType.replace(/\/.*/, ''); | ||
const width = options.width || 0; | ||
const height = options.height || 0; | ||
const alt = options.alt; | ||
let title = options.title; | ||
const fallbackToDisc = options.fallbackToDisc; | ||
if (typeof media === 'string' && !/data:/.test(media) && (typeof contentType === 'undefined' || contentType.indexOf('/') === -1)) { | ||
var extension = pathModule.extname(media); | ||
if (extension) { | ||
contentType = mime.types[extension.replace(/^\./, '')] || contentType; | ||
if ( | ||
typeof media === 'string' && | ||
!/data:/.test(media) && | ||
(typeof contentType === 'undefined' || contentType.indexOf('/') === -1) | ||
) { | ||
const extension = pathModule.extname(media); | ||
if (extension) { | ||
contentType = | ||
mime.getType(extension.replace(/^\./, '')) || contentType; | ||
} | ||
} | ||
this.alt({ | ||
html: { | ||
width, | ||
height, | ||
content() { | ||
let src; | ||
if (typeof media === 'string') { | ||
src = media; | ||
if (!/^data:/.test(media)) { | ||
if (typeof title === 'undefined') { | ||
title = media; | ||
} | ||
} | ||
} else if ( | ||
typeof URL !== 'undefined' && | ||
typeof URL.createObjectURL === 'function' && | ||
typeof Blob !== 'undefined' | ||
) { | ||
src = URL.createObjectURL( | ||
new Blob([media], { type: sanitizeContentType(contentType) }) | ||
); | ||
} else { | ||
src = 'data:' + sanitizeContentType(contentType) + ';base64,'; | ||
if (Buffer.isBuffer(media)) { | ||
src += media.toString('base64'); | ||
} else if (typeof btoa === 'function') { | ||
src += btoa(media); | ||
} else { | ||
src += new Buffer(media).toString('base64'); | ||
} | ||
} | ||
this.alt({ | ||
html: { | ||
width: width, | ||
height: height, | ||
content: function () { | ||
var src; | ||
if (typeof media === 'string') { | ||
src = media; | ||
if (!/^data:/.test(media)) { | ||
if (typeof title === 'undefined') { | ||
title = media; | ||
} | ||
} | ||
} else if (typeof URL !== 'undefined' && typeof URL.createObjectURL === 'function' && typeof Blob !== 'undefined') { | ||
src = URL.createObjectURL(new Blob([media], { type: sanitizeContentType(contentType) })); | ||
} else { | ||
src = 'data:' + sanitizeContentType(contentType) + ';base64,'; | ||
if (Buffer.isBuffer(media)) { | ||
src += media.toString('base64'); | ||
} else if (typeof btoa === 'function') { | ||
src += btoa(media); | ||
} else { | ||
src += new Buffer(media).toString('base64'); | ||
} | ||
} | ||
const attributes = ['src="' + entitify(src) + '"']; | ||
var attributes = [ 'src="' + entitify(src) + '"' ]; | ||
if (typeof alt !== 'undefined') { | ||
attributes.push('alt="' + entitify(String(alt)) + '"'); | ||
} | ||
if (typeof title !== 'undefined') { | ||
attributes.push('title="' + entitify(String(title)) + '"'); | ||
} | ||
if (typeof alt !== 'undefined') { | ||
attributes.push('alt="' + entitify(String(alt)) + '"'); | ||
} | ||
if (typeof title !== 'undefined') { | ||
attributes.push('title="' + entitify(String(title)) + '"'); | ||
} | ||
const styleProperties = []; | ||
if (width) { | ||
styleProperties.push( | ||
'max-width: ' + 0.6 * width + 'em', | ||
'max-width: ' + width + 'ch' | ||
); | ||
} | ||
if (height) { | ||
styleProperties.push('max-height: ' + height + 'em'); | ||
} | ||
if (styleProperties.length) { | ||
attributes.push( | ||
'style="' + entitify(styleProperties.join('; ')) + '"' | ||
); | ||
} | ||
var styleProperties = []; | ||
if (width) { | ||
styleProperties.push('max-width: ' + (0.6 * width) + 'em', 'max-width: ' + width + 'ch'); | ||
} | ||
if (height) { | ||
styleProperties.push('max-height: ' + height + 'em'); | ||
} | ||
if (styleProperties.length) { | ||
attributes.push('style="' + entitify(styleProperties.join('; ')) + '"'); | ||
} | ||
var attributeStr = attributes.length ? ' ' + attributes.join(' ') : ''; | ||
var html = ''; | ||
if (options.link) { | ||
html += '<a href="' + entitify(options.link === true ? src : options.link) + '">'; | ||
} | ||
if (!majorContentType || majorContentType === 'image') { | ||
html += '<img' + attributeStr + '>'; | ||
} else { | ||
html += '<' + majorContentType + attributeStr + '></' + majorContentType + '>'; | ||
} | ||
if (options.link) { | ||
html += '</a>'; | ||
} | ||
return html; | ||
} | ||
}, | ||
fallback: function () { | ||
function writeToDisc(data) { | ||
if (data.constructor.name === 'Uint8Array') { | ||
data = new Buffer(data); | ||
} | ||
var fileName; | ||
if (typeof fallbackToDisc === 'string') { | ||
fileName = fallbackToDisc; | ||
} else { | ||
fileName = getTemporaryFilePath({ suffix: '.' + (mime.extensions[contentType] || majorContentType || 'data') }); | ||
} | ||
fs.writeFileSync(fileName, data); | ||
return fileName; | ||
} | ||
if (typeof media === 'string') { | ||
var matchDataUrl = media.match(/^data:([\w\-\+\.]+\/[\w\-\+\.]+)?(?:;charset=([\w\/\-]+))?(;base64)?,([\u0000-\u007f]*)$/); | ||
if (matchDataUrl) { | ||
contentType = matchDataUrl[1] || contentType || 'text/plain'; | ||
if (matchDataUrl[3] && options.fallbackToDisc && fs.writeFileSync) { | ||
this.text(writeToDisc(new Buffer(matchDataUrl[4], 'base64')) + ' (' + contentType + ')'); | ||
} else { | ||
this.text('data url (' + contentType + ')'); | ||
} | ||
} else { | ||
this.text(media + ' (' + (contentType || 'media') + ')'); | ||
} | ||
} else { | ||
// Uint8Array or Buffer | ||
if (options.fallbackToDisc && fs.writeFileSync) { | ||
this.text(writeToDisc(media) + ' (' + contentType + ')'); | ||
} else { | ||
this.text(media.constructor.name + '[' + media.length + '] (' + (contentType || 'media') + ')'); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
magicPen.addStyle('image', function (image, options) { | ||
if (typeof options === 'string') { | ||
options = { contentType: options }; | ||
const attributeStr = attributes.length | ||
? ' ' + attributes.join(' ') | ||
: ''; | ||
let html = ''; | ||
if (options.link) { | ||
html += | ||
'<a href="' + | ||
entitify(options.link === true ? src : options.link) + | ||
'">'; | ||
} | ||
if (!majorContentType || majorContentType === 'image') { | ||
html += '<img' + attributeStr + '>'; | ||
} else { | ||
options = options || {}; | ||
html += | ||
'<' + | ||
majorContentType + | ||
attributeStr + | ||
'></' + | ||
majorContentType + | ||
'>'; | ||
} | ||
this.media(image, _.extend({ contentType: 'image' }, options)); | ||
}); | ||
if (options.link) { | ||
html += '</a>'; | ||
} | ||
return html; | ||
} | ||
}, | ||
fallback() { | ||
function writeToDisc(data) { | ||
if (data.constructor.name === 'Uint8Array') { | ||
data = new Buffer(data); | ||
} | ||
let fileName; | ||
if (typeof fallbackToDisc === 'string') { | ||
fileName = fallbackToDisc; | ||
} else { | ||
fileName = getTemporaryFilePath({ | ||
suffix: | ||
'.' + | ||
(mime.getExtension(contentType) || majorContentType || 'data') | ||
}); | ||
} | ||
fs.writeFileSync(fileName, data); | ||
return fileName; | ||
} | ||
magicPen.addStyle('audio', function (audio, options) { | ||
if (typeof options === 'string') { | ||
options = { contentType: options }; | ||
if (typeof media === 'string') { | ||
const matchDataUrl = media.match( | ||
/^data:([\w+.-]+\/[\w+.-]+)?(?:;charset=([\w/-]+))?(;base64)?,([ -\x7f]*)$/ | ||
); | ||
if (matchDataUrl) { | ||
contentType = matchDataUrl[1] || contentType || 'text/plain'; | ||
if ( | ||
matchDataUrl[3] && | ||
options.fallbackToDisc && | ||
fs.writeFileSync | ||
) { | ||
this.text( | ||
writeToDisc(new Buffer(matchDataUrl[4], 'base64')) + | ||
' (' + | ||
contentType + | ||
')' | ||
); | ||
} else { | ||
this.text('data url (' + contentType + ')'); | ||
} | ||
} else { | ||
options = options || {}; | ||
this.text(media + ' (' + (contentType || 'media') + ')'); | ||
} | ||
this.media(audio, _.extend({ contentType: 'audio' }, options)); | ||
}); | ||
} else { | ||
// Uint8Array or Buffer | ||
magicPen.addStyle('video', function (video, options) { | ||
if (typeof options === 'string') { | ||
options = { contentType: options }; | ||
if (options.fallbackToDisc && fs.writeFileSync) { | ||
this.text(writeToDisc(media) + ' (' + contentType + ')'); | ||
} else { | ||
options = options || {}; | ||
this.text( | ||
media.constructor.name + | ||
'[' + | ||
media.length + | ||
'] (' + | ||
(contentType || 'media') + | ||
')' | ||
); | ||
} | ||
this.media(video, _.extend({ contentType: 'video' }, options)); | ||
}); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
magicPen.addStyle('image', function(image, options) { | ||
if (typeof options === 'string') { | ||
options = { contentType: options }; | ||
} else { | ||
options = options || {}; | ||
} | ||
this.media(image, _.extend({ contentType: 'image' }, options)); | ||
}); | ||
magicPen.addStyle('audio', function(audio, options) { | ||
if (typeof options === 'string') { | ||
options = { contentType: options }; | ||
} else { | ||
options = options || {}; | ||
} | ||
this.media(audio, _.extend({ contentType: 'audio' }, options)); | ||
}); | ||
magicPen.addStyle('video', function(video, options) { | ||
if (typeof options === 'string') { | ||
options = { contentType: options }; | ||
} else { | ||
options = options || {}; | ||
} | ||
this.media(video, _.extend({ contentType: 'video' }, options)); | ||
}); | ||
} | ||
}; |
{ | ||
"name": "magicpen-media", | ||
"version": "1.5.1", | ||
"version": "1.5.2", | ||
"description": "Add media support to magicpen (images, audio, video)", | ||
@@ -10,15 +10,19 @@ "repository": { | ||
"main": "lib/magicPenMedia.js", | ||
"author": "Andreas Lind <andreas@one.com>", | ||
"license": "MIT", | ||
"author": "Andreas Lind <andreaslindpetersen@gmail.com>", | ||
"devDependencies": { | ||
"browserify": "8.1.1", | ||
"bundle-collapser": "1.2.0", | ||
"coveralls": "2.11.2", | ||
"istanbul": "0.3.17", | ||
"jshint": "2.8.0", | ||
"magicpen": "4.12.0", | ||
"mocha": "2.2.5", | ||
"sinon": "1.15.4", | ||
"unexpected": "9.0.0", | ||
"unexpected-fs": "1.1.0", | ||
"unexpected-sinon": "6.4.1" | ||
"browserify": "^16.2.3", | ||
"bundle-collapser": "^1.3.0", | ||
"coveralls": "^3.0.2", | ||
"eslint": "^5.8.0", | ||
"eslint-config-pretty-standard": "^2.0.0", | ||
"eslint-plugin-prettier": "^3.0.0", | ||
"magicpen": "^5.12.0", | ||
"mocha": "^5.2.0", | ||
"nyc": "^13.1.0", | ||
"prettier": "^1.14.3", | ||
"sinon": "^7.1.0", | ||
"unexpected": "^10.39.1", | ||
"unexpected-fs": "^3.0.0", | ||
"unexpected-sinon": "^10.10.1" | ||
}, | ||
@@ -30,13 +34,18 @@ "files": [ | ||
"scripts": { | ||
"lint": "jshint .", | ||
"test": "mocha && npm run lint", | ||
"travis": "npm test && npm run coverage && (<coverage/lcov.info coveralls || true)", | ||
"coverage": "NODE_ENV=development istanbul cover --report text --report lcov _mocha -- --reporter dot && echo google-chrome coverage/lcov-report/index.html", | ||
"prepublish": "browserify -p bundle-collapser/plugin -e lib/magicPenMedia -s magicPenMedia > magicPenMedia.min.js" | ||
"lint": "eslint .", | ||
"test": "mocha", | ||
"ci": "npm test && npm run lint && npm run coverage", | ||
"coverage": "NODE_ENV=development nyc --reporter=lcov --reporter=text --all -- npm test && echo google-chrome coverage/lcov-report/index.html", | ||
"prepublishOnly": "browserify -p bundle-collapser/plugin -e lib/magicPenMedia -s magicPenMedia > magicPenMedia.min.js" | ||
}, | ||
"dependencies": { | ||
"gettemporaryfilepath": "0.0.1", | ||
"lodash": "3.10.0", | ||
"mime": "1.3.4" | ||
"gettemporaryfilepath": "^1.0.0", | ||
"lodash": "^4.17.11", | ||
"mime": "^2.3.1" | ||
}, | ||
"nyc": { | ||
"include": [ | ||
"lib/**" | ||
] | ||
} | ||
} |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
667558
5
19010
5
14
2
+ Addedgettemporaryfilepath@1.0.1(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedmime@2.6.0(transitive)
- Removedgettemporaryfilepath@0.0.1(transitive)
- Removedlodash@3.10.0(transitive)
- Removedmime@1.3.4(transitive)
Updatedgettemporaryfilepath@^1.0.0
Updatedlodash@^4.17.11
Updatedmime@^2.3.1