Merge branch '1.11.x' of https://github.com/chamilo/chamilo-lms into 1.11.x

pull/2487/head
José Loguercio 10 years ago
commit f3fe661978
  1. 5
      .github/ISSUE_TEMPLATE.md
  2. 2
      README.md
  3. 8
      app/Migrations/Schema/V110/Version20151221150100.php
  4. 3
      app/Migrations/Schema/V111/Version111.php
  5. 2
      app/Resources/public/assets/MathJax/.bower.json
  6. 10
      app/Resources/public/assets/blueimp-canvas-to-blob/.bower.json
  7. 2
      app/Resources/public/assets/blueimp-canvas-to-blob/js/canvas-to-blob.js
  8. 13
      app/Resources/public/assets/blueimp-canvas-to-blob/package.json
  9. 2
      app/Resources/public/assets/blueimp-canvas-to-blob/test/index.html
  10. 18
      app/Resources/public/assets/blueimp-canvas-to-blob/test/test.js
  11. 8
      app/Resources/public/assets/blueimp-load-image/.bower.json
  12. 18
      app/Resources/public/assets/blueimp-load-image/README.md
  13. 2
      app/Resources/public/assets/blueimp-load-image/index.html
  14. 161
      app/Resources/public/assets/blueimp-load-image/js/demo.js
  15. 2
      app/Resources/public/assets/blueimp-load-image/js/load-image-exif-map.js
  16. 2
      app/Resources/public/assets/blueimp-load-image/js/load-image-exif.js
  17. 22
      app/Resources/public/assets/blueimp-load-image/js/load-image-meta.js
  18. 20
      app/Resources/public/assets/blueimp-load-image/js/load-image-orientation.js
  19. 2
      app/Resources/public/assets/blueimp-load-image/js/load-image.all.min.js
  20. 2
      app/Resources/public/assets/blueimp-load-image/js/load-image.all.min.js.map
  21. 60
      app/Resources/public/assets/blueimp-load-image/js/load-image.js
  22. 15
      app/Resources/public/assets/blueimp-load-image/package.json
  23. 4
      app/Resources/public/assets/blueimp-load-image/test/index.html
  24. 353
      app/Resources/public/assets/blueimp-load-image/test/test.js
  25. 8
      app/Resources/public/assets/blueimp-tmpl/.bower.json
  26. 2
      app/Resources/public/assets/blueimp-tmpl/js/compile.js
  27. 2
      app/Resources/public/assets/blueimp-tmpl/js/demo.js
  28. 4
      app/Resources/public/assets/blueimp-tmpl/js/runtime.js
  29. 4
      app/Resources/public/assets/blueimp-tmpl/js/tmpl.js
  30. 2
      app/Resources/public/assets/blueimp-tmpl/js/tmpl.min.js
  31. 2
      app/Resources/public/assets/blueimp-tmpl/js/tmpl.min.js.map
  32. 14
      app/Resources/public/assets/blueimp-tmpl/package.json
  33. 2
      app/Resources/public/assets/blueimp-tmpl/test/index.html
  34. 52
      app/Resources/public/assets/blueimp-tmpl/test/test.js
  35. 2
      app/Resources/public/assets/bootstrap-daterangepicker/.bower.json
  36. 2
      app/Resources/public/assets/ckeditor/.bower.json
  37. 2
      app/Resources/public/assets/cropper/.bower.json
  38. 2
      app/Resources/public/assets/fontawesome/.bower.json
  39. 2
      app/Resources/public/assets/fullcalendar/.bower.json
  40. 8
      app/Resources/public/assets/i18next/.bower.json
  41. 6
      app/Resources/public/assets/i18next/CHANGELOG.md
  42. 17
      app/Resources/public/assets/i18next/README.md
  43. 16
      app/Resources/public/assets/i18next/i18next.js
  44. 4
      app/Resources/public/assets/i18next/i18next.min.js
  45. 2
      app/Resources/public/assets/image-map-resizer/.bower.json
  46. 2
      app/Resources/public/assets/jquery-timeago/.bower.json
  47. 2
      app/Resources/public/assets/jquery-ui/.bower.json
  48. 2
      app/Resources/public/assets/jquery.scrollbar/.bower.json
  49. 2
      app/Resources/public/assets/jqueryui-timepicker-addon/.bower.json
  50. 8
      app/Resources/public/assets/mediaelement/.bower.json
  51. 142
      app/Resources/public/assets/mediaelement/README.md
  52. BIN
      app/Resources/public/assets/mediaelement/build/flashmediaelement-cdn.swf
  53. BIN
      app/Resources/public/assets/mediaelement/build/flashmediaelement-debug.swf
  54. BIN
      app/Resources/public/assets/mediaelement/build/flashmediaelement.swf
  55. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-cs.js
  56. 70
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-de.js
  57. 75
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-en.js
  58. 49
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-es.js
  59. 53
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-fr.js
  60. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-hu.js
  61. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-it.js
  62. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-ja.js
  63. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-ko.js
  64. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-pl.js
  65. 37
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-pt-br.js
  66. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-pt.js
  67. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-ro.js
  68. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-ru.js
  69. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-sk.js
  70. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-zh-cn.js
  71. 46
      app/Resources/public/assets/mediaelement/build/lang/me-i18n-locale-zh.js
  72. 1287
      app/Resources/public/assets/mediaelement/build/mediaelement-and-player.js
  73. 6
      app/Resources/public/assets/mediaelement/build/mediaelement-and-player.min.js
  74. 194
      app/Resources/public/assets/mediaelement/build/mediaelement.js
  75. 2
      app/Resources/public/assets/mediaelement/build/mediaelement.min.js
  76. 5
      app/Resources/public/assets/mediaelement/build/mediaelementplayer.css
  77. 1091
      app/Resources/public/assets/mediaelement/build/mediaelementplayer.js
  78. 2
      app/Resources/public/assets/mediaelement/build/mediaelementplayer.min.css
  79. 4
      app/Resources/public/assets/mediaelement/build/mediaelementplayer.min.js
  80. 52
      app/Resources/public/assets/mediaelement/changelog.md
  81. 2
      app/Resources/public/assets/modernizr/.bower.json
  82. 2
      app/Resources/public/assets/moment/.bower.json
  83. 8
      app/Resources/public/assets/pwstrength-bootstrap/.bower.json
  84. 2
      app/Resources/public/assets/pwstrength-bootstrap/bower.json
  85. 2
      app/Resources/public/assets/pwstrength-bootstrap/dist/pwstrength-bootstrap.js
  86. 2
      app/Resources/public/assets/pwstrength-bootstrap/dist/pwstrength-bootstrap.min.js
  87. 15
      app/Resources/public/assets/pwstrength-bootstrap/locales/de.json
  88. 15
      app/Resources/public/assets/pwstrength-bootstrap/locales/pl.json
  89. 15
      app/Resources/public/assets/pwstrength-bootstrap/locales/tr.json
  90. 2
      app/Resources/public/assets/simpleWebRTC/.bower.json
  91. 8
      app/Resources/public/assets/webcamjs/.bower.json
  92. 2
      app/Resources/public/assets/webcamjs/bower.json
  93. 2
      app/Resources/public/assets/webcamjs/package.json
  94. 7
      app/Resources/public/assets/webcamjs/webcam.js
  95. 4
      app/Resources/public/assets/webcamjs/webcam.min.js
  96. 8
      app/Resources/public/assets/zxcvbn/.bower.json
  97. 2
      app/Resources/public/assets/zxcvbn/LICENSE.txt
  98. 51
      app/Resources/public/assets/zxcvbn/README.md
  99. 10
      app/Resources/public/assets/zxcvbn/dist/zxcvbn.js
  100. 22
      app/Resources/public/assets/zxcvbn/dist/zxcvbn.js.map
  101. Some files were not shown because too many files have changed in this diff Show More

@ -0,0 +1,5 @@
### Expected behavior / Resultado esperado / Résultat attendu
### Actual behavior / Resultado real / Résultat réel
### Steps to reproduce / Pasos para reproducir / Étapes pour reproduire

@ -177,4 +177,4 @@ In short, we ask you to send us Pull Requests based on a branch that you create
with this purpose into your repository forked from the original Chamilo repository.
# Documentation
For more information on Chamilo, visit https://stable.chamilo.org/documentation
For more information on Chamilo, visit https://1.11.chamilo.org/documentation/index.html

@ -29,9 +29,9 @@ class Version20151221150100 extends AbstractMigrationChamilo
$this->addSql("
UPDATE track_e_attempt a
INNER JOIN c_quiz_answer qa
ON a.question_id = qa.question_id
ON (a.question_id = qa.question_id AND a.c_id = qa.c_id)
INNER JOIN c_quiz_question q
ON qa.question_id = q.id
ON (qa.question_id = q.id AND qa.c_id = q.c_id)
SET a.answer = qa.id_auto
WHERE
a.answer = qa.id AND
@ -42,9 +42,9 @@ class Version20151221150100 extends AbstractMigrationChamilo
$this->addSql("
UPDATE c_quiz_answer a
INNER JOIN c_quiz_answer b
ON a.question_id = b.question_id
ON (a.question_id = b.question_id AND b.c_id = a.c_id)
INNER JOIN c_quiz_question q
ON b.question_id = q.id
ON (b.question_id = q.id AND b.c_id = q.c_id)
SET a.correct = b.id_auto
WHERE
a.correct = b.id AND

@ -270,7 +270,6 @@ class Version111 extends AbstractMigrationChamilo
$this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES ('show_link_ticket_notification', NULL, 'radio', 'Platform', 'false', 'ShowLinkTicketNotificationTitle', 'ShowLinkTicketNotificationComment', NULL, NULL, 0)");
$this->addSql("INSERT INTO settings_current (variable, subkey, type, category, selected_value, title, comment, access_url) VALUES ('sso_authentication_subclass', NULL, 'textfield', 'Security', '', 'SSOSubclassTitle', 'SSOSubclassComment', 1)");
$this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('ticket_allow_student_add', 'true', 'Yes'), ('ticket_allow_student_add', 'false', 'No')");
$this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('ticket_allow_category_edition', 'true', 'Yes'), ('ticket_allow_category_edition', 'false', 'No')");
$this->addSql("INSERT INTO settings_options (variable, value, display_text) VALUES ('ticket_send_warning_to_all_admins', 'true', 'Yes'), ('ticket_send_warning_to_all_admins', 'false', 'No')");
@ -314,6 +313,8 @@ class Version111 extends AbstractMigrationChamilo
$this->addSql('DELETE FROM settings_current WHERE variable = "course_create_active_tools" AND subkey = "online_conference"');
$this->addSql('DELETE FROM settings_options WHERE variable = "visio_use_rtmpt"');
$this->addSql('DELETE FROM course_module WHERE name = "conference"');
$this->addSql('ALTER TABLE c_student_publication_assignment CHANGE add_to_calendar add_to_calendar INT NOT NULL;');
$this->addSql('ALTER TABLE extra_field ADD visible_to_others TINYINT(1) DEFAULT NULL, CHANGE visible visible_to_self TINYINT(1) DEFAULT NULL');
}
/**

@ -21,7 +21,7 @@
"tag": "2.5.3",
"commit": "ba9afeb5a743249acdea17540b48b14ebc95dbe4"
},
"_source": "git://github.com/mathjax/MathJax.git",
"_source": "https://github.com/mathjax/MathJax.git",
"_target": "2.5.*",
"_originalSource": "MathJax"
}

@ -1,14 +1,14 @@
{
"name": "blueimp-canvas-to-blob",
"homepage": "https://github.com/blueimp/JavaScript-Canvas-to-Blob",
"version": "3.3.0",
"_release": "3.3.0",
"version": "3.4.0",
"_release": "3.4.0",
"_resolution": {
"type": "version",
"tag": "v3.3.0",
"commit": "443806e20bf0cc6e5b812b0cf686f3109d791074"
"tag": "v3.4.0",
"commit": "ca0326180f984600aa25eab8a19c4be11b5f048c"
},
"_source": "git://github.com/blueimp/JavaScript-Canvas-to-Blob.git",
"_source": "https://github.com/blueimp/JavaScript-Canvas-to-Blob.git",
"_target": ">=2.1.1",
"_originalSource": "blueimp-canvas-to-blob"
}

@ -12,7 +12,7 @@
* http://stackoverflow.com/q/4998908
*/
/*global window, atob, Blob, ArrayBuffer, Uint8Array, define, module */
/* global atob, Blob, define */
;(function (window) {
'use strict'

@ -1,6 +1,6 @@
{
"name": "blueimp-canvas-to-blob",
"version": "3.3.0",
"version": "3.4.0",
"title": "JavaScript Canvas to Blob",
"description": "Canvas to Blob is a polyfill for the standard JavaScript canvas.toBlob method. It can be used to create Blob objects from an HTML canvas element.",
"keywords": [
@ -22,12 +22,15 @@
"license": "MIT",
"main": "./js/canvas-to-blob.js",
"devDependencies": {
"mocha-phantomjs": "4.0.1",
"standard": "6.0.7",
"uglify-js": "2.6.1"
"phantomjs-prebuilt": "2.1.13",
"mocha-phantomjs-core": "1.3.1",
"standard": "8.3.0",
"uglify-js": "2.7.3"
},
"scripts": {
"test": "standard js/*.js test/*.js && mocha-phantomjs test/index.html",
"lint": "standard js/*.js test/*.js",
"unit": "phantomjs node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html",
"test": "npm run lint && npm run unit",
"build": "cd js && uglifyjs canvas-to-blob.js -c -m -o canvas-to-blob.min.js --source-map canvas-to-blob.min.js.map",
"preversion": "npm test",
"version": "npm run build && git add -A js",

@ -24,7 +24,7 @@
<body>
<div id="mocha"></div>
<script src="vendor/mocha.js"></script>
<script src="vendor/expect.js"></script>
<script src="vendor/chai.js"></script>
<script>
window.initMochaPhantomJS && initMochaPhantomJS();
mocha.setup('bdd');

@ -9,7 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global window, describe, it, Blob */
/* global describe, it, Blob */
;(function (expect) {
'use strict'
@ -26,7 +26,7 @@
window.loadImage(blob, function (canvas) {
canvas.toBlob(
function (newBlob) {
expect(newBlob).to.be.a(Blob)
expect(newBlob).to.be.a.instanceOf(Blob)
done()
}
)
@ -37,7 +37,7 @@
window.loadImage(blob, function (canvas) {
canvas.toBlob(
function (newBlob) {
expect(newBlob.type).to.be('image/png')
expect(newBlob.type).to.equal('image/png')
done()
},
'image/png'
@ -49,7 +49,7 @@
window.loadImage(blob, function (canvas) {
canvas.toBlob(
function (newBlob) {
expect(newBlob.type).to.be('image/jpeg')
expect(newBlob.type).to.equal('image/jpeg')
done()
},
'image/jpeg'
@ -62,8 +62,8 @@
canvas.toBlob(
function (newBlob) {
window.loadImage(newBlob, function (img) {
expect(img.width).to.be(canvas.width)
expect(img.height).to.be(canvas.height)
expect(img.width).to.equal(canvas.width)
expect(img.height).to.equal(canvas.height)
done()
})
}
@ -80,8 +80,8 @@
.getImageData(0, 0, canvas.width, canvas.height)
var newCanvasData = newCanvas.getContext('2d')
.getImageData(0, 0, newCanvas.width, newCanvas.height)
expect(canvasData.width).to.be(newCanvasData.width)
expect(canvasData.height).to.be(newCanvasData.height)
expect(canvasData.width).to.equal(newCanvasData.width)
expect(canvasData.height).to.equal(newCanvasData.height)
done()
}, {canvas: true})
}
@ -89,4 +89,4 @@
}, {canvas: true})
})
})
}(this.expect))
}(this.chai.expect))

@ -1,12 +1,12 @@
{
"name": "blueimp-load-image",
"homepage": "https://github.com/blueimp/JavaScript-Load-Image",
"version": "2.6.2",
"_release": "2.6.2",
"version": "2.7.0",
"_release": "2.7.0",
"_resolution": {
"type": "version",
"tag": "v2.6.2",
"commit": "d6fdf1575c2f0376d29750a626d096f997e9572a"
"tag": "v2.7.0",
"commit": "8ee49d987e6951db1c4db6c5270abaa66e6b6659"
},
"_source": "https://github.com/blueimp/JavaScript-Load-Image.git",
"_target": ">=1.13.0",

@ -194,9 +194,15 @@ Requires `canvas: true`.
* **crop**: Crops the image to the maxWidth/maxHeight constraints if set to
`true`.
Enabling the `crop` option also enables the `canvas` option.
* **orientation**: Allows to transform the canvas coordinates according to the
EXIF orientation specification.
Setting the `orientation` also enables the `canvas` option.
* **orientation**: Transform the canvas according to the specified Exif
orientation, which can be an `integer` in the range of `1` to `8` or the boolean
value `true`.
When set to `true`, it will set the orientation value based on the EXIF data of
the image, which will be parsed automatically if the exif library is available.
Setting the `orientation` also enables the `canvas` option.
Setting `orientation` to `true` alsoe enables the `meta` option.
* **meta**: Automatically parses the image meta data if set to `true`.
The meta data is passed to the callback as second argument.
* **canvas**: Returns the image as
[canvas](https://developer.mozilla.org/en/HTML/Canvas) element if set to `true`.
* **crossOrigin**: Sets the crossOrigin property on the img element for loading
@ -266,9 +272,9 @@ Blob objects of resized images can be created via
[canvas.toBlob()](https://github.com/blueimp/JavaScript-Canvas-to-Blob).
### Exif parser
If you include the Load Image Exif Parser extension, the **parseMetaData**
callback **data** contains the additional property **exif** if Exif data could
be found in the given image.
If you include the Load Image Exif Parser extension, the argument passed to the
callback for **parseMetaData** will contain the additional property **exif** if
Exif data could be found in the given image.
The **exif** object stores the parsed Exif tags:
```js

@ -57,10 +57,10 @@ It also provides a method to parse image meta data to extract <a href="https://e
</div>
<br>
<script src="js/load-image.js"></script>
<script src="js/load-image-orientation.js"></script>
<script src="js/load-image-meta.js"></script>
<script src="js/load-image-exif.js"></script>
<script src="js/load-image-exif-map.js"></script>
<script src="js/load-image-orientation.js"></script>
<!-- jQuery and Jcrop are not required by JavaScript Load Image, but included for the demo -->
<script src="js/vendor/jquery.js"></script>
<script src="js/vendor/jquery.Jcrop.js"></script>

@ -9,7 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global window, document, loadImage, HTMLCanvasElement, $ */
/* global loadImage, HTMLCanvasElement, $ */
$(function () {
'use strict'
@ -20,32 +20,7 @@ $(function () {
var actionsNode = $('#actions')
var currentFile
var coordinates
function replaceResults (img) {
var content
if (!(img.src || img instanceof HTMLCanvasElement)) {
content = $('<span>Loading image file failed</span>')
} else {
content = $('<a target="_blank">').append(img)
.attr('download', currentFile.name)
.attr('href', img.src || img.toDataURL())
}
result.children().replaceWith(content)
if (img.getContext) {
actionsNode.show()
}
}
function displayImage (file, options) {
currentFile = file
if (!loadImage(
file,
replaceResults,
options
)) {
result.children().replaceWith(
$('<span>Your browser does not support the URL or FileReader API.</span>')
)
}
}
function displayExifData (exif) {
var thumbnail = exif.get('Thumbnail')
var tags = exif.getAll()
@ -70,6 +45,40 @@ $(function () {
}
exifNode.show()
}
function updateResults (img, data) {
var content
if (!(img.src || img instanceof HTMLCanvasElement)) {
content = $('<span>Loading image file failed</span>')
} else {
content = $('<a target="_blank">').append(img)
.attr('download', currentFile.name)
.attr('href', img.src || img.toDataURL())
}
result.children().replaceWith(content)
if (img.getContext) {
actionsNode.show()
}
if (data && data.exif) {
displayExifData(data.exif)
}
}
function displayImage (file, options) {
currentFile = file
if (!loadImage(
file,
updateResults,
options
)) {
result.children().replaceWith(
$('<span>' +
'Your browser does not support the URL or FileReader API.' +
'</span>')
)
}
}
function dropChangeHandler (e) {
e.preventDefault()
e = e.originalEvent
@ -79,25 +88,23 @@ $(function () {
maxWidth: result.width(),
canvas: true,
pixelRatio: window.devicePixelRatio,
downsamplingRatio: 0.5
downsamplingRatio: 0.5,
orientation: true
}
if (!file) {
return
}
exifNode.hide()
thumbNode.hide()
loadImage.parseMetaData(file, function (data) {
if (data.exif) {
options.orientation = data.exif.get('Orientation')
displayExifData(data.exif)
}
displayImage(file, options)
})
displayImage(file, options)
}
// Hide URL/FileReader API requirement message in capable browsers:
if (window.createObjectURL || window.URL || window.webkitURL || window.FileReader) {
if (window.createObjectURL || window.URL || window.webkitURL ||
window.FileReader) {
result.children().hide()
}
$(document)
.on('dragover', function (e) {
e.preventDefault()
@ -105,45 +112,51 @@ $(function () {
e.dataTransfer.dropEffect = 'copy'
})
.on('drop', dropChangeHandler)
$('#file-input').on('change', dropChangeHandler)
$('#edit').on('click', function (event) {
event.preventDefault()
var imgNode = result.find('img, canvas')
var img = imgNode[0]
var pixelRatio = window.devicePixelRatio || 1
imgNode.Jcrop({
setSelect: [
40,
40,
(img.width / pixelRatio) - 40,
(img.height / pixelRatio) - 40
],
onSelect: function (coords) {
coordinates = coords
},
onRelease: function () {
$('#file-input')
.on('change', dropChangeHandler)
$('#edit')
.on('click', function (event) {
event.preventDefault()
var imgNode = result.find('img, canvas')
var img = imgNode[0]
var pixelRatio = window.devicePixelRatio || 1
imgNode.Jcrop({
setSelect: [
40,
40,
(img.width / pixelRatio) - 40,
(img.height / pixelRatio) - 40
],
onSelect: function (coords) {
coordinates = coords
},
onRelease: function () {
coordinates = null
}
}).parent().on('click', function (event) {
event.preventDefault()
})
})
$('#crop')
.on('click', function (event) {
event.preventDefault()
var img = result.find('img, canvas')[0]
var pixelRatio = window.devicePixelRatio || 1
if (img && coordinates) {
updateResults(loadImage.scale(img, {
left: coordinates.x * pixelRatio,
top: coordinates.y * pixelRatio,
sourceWidth: coordinates.w * pixelRatio,
sourceHeight: coordinates.h * pixelRatio,
minWidth: result.width(),
maxWidth: result.width(),
pixelRatio: pixelRatio,
downsamplingRatio: 0.5
}))
coordinates = null
}
}).parent().on('click', function (event) {
event.preventDefault()
})
})
$('#crop').on('click', function (event) {
event.preventDefault()
var img = result.find('img, canvas')[0]
var pixelRatio = window.devicePixelRatio || 1
if (img && coordinates) {
replaceResults(loadImage.scale(img, {
left: coordinates.x * pixelRatio,
top: coordinates.y * pixelRatio,
sourceWidth: coordinates.w * pixelRatio,
sourceHeight: coordinates.h * pixelRatio,
minWidth: result.width(),
maxWidth: result.width(),
pixelRatio: pixelRatio,
downsamplingRatio: 0.5
}))
coordinates = null
}
})
})

@ -12,7 +12,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global define, module, require, window */
/* global define */
;(function (factory) {
'use strict'

@ -9,7 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global define, module, require, window, console */
/* global define */
;(function (factory) {
'use strict'

@ -13,7 +13,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global define, module, require, window, DataView, Blob, Uint8Array, console */
/* global define, Blob */
;(function (factory) {
'use strict'
@ -49,12 +49,12 @@
// The options arguments accepts an object and supports the following properties:
// * maxMetaDataSize: Defines the maximum number of bytes to parse.
// * disableImageHead: Disables creating the imageHead property.
loadImage.parseMetaData = function (file, callback, options) {
loadImage.parseMetaData = function (file, callback, options, data) {
options = options || {}
data = data || {}
var that = this
// 256 KiB should contain all EXIF/ICC/IPTC segments:
var maxMetaDataSize = options.maxMetaDataSize || 262144
var data = {}
var noMetaData = !(window.DataView && file && file.size >= 12 &&
file.type === 'image/jpeg' && loadImage.blobSlice)
if (noMetaData || !loadImage.readFile(
@ -140,4 +140,20 @@
callback(data)
}
}
// Determines if meta data should be loaded automatically:
loadImage.hasMetaOption = function (options) {
return options.meta
}
var originalTransform = loadImage.transform
loadImage.transform = function (img, options, callback, file, data) {
if (loadImage.hasMetaOption(options || {})) {
loadImage.parseMetaData(file, function (data) {
originalTransform.call(loadImage, img, options, callback, file, data)
}, options, data)
} else {
originalTransform.apply(loadImage, arguments)
}
}
}))

@ -9,7 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global define, module, require, window */
/* global define */
;(function (factory) {
'use strict'
@ -26,16 +26,22 @@
'use strict'
var originalHasCanvasOption = loadImage.hasCanvasOption
var originalHasMetaOption = loadImage.hasMetaOption
var originalTransformCoordinates = loadImage.transformCoordinates
var originalGetTransformedOptions = loadImage.getTransformedOptions
// This method is used to determine if the target image
// should be a canvas element:
// Determines if the target image should be a canvas element:
loadImage.hasCanvasOption = function (options) {
return !!options.orientation ||
originalHasCanvasOption.call(loadImage, options)
}
// Determines if meta data should be loaded automatically:
loadImage.hasMetaOption = function (options) {
return options.orientation === true ||
originalHasMetaOption.call(loadImage, options)
}
// Transform image orientation based on
// the given EXIF orientation option:
loadImage.transformCoordinates = function (canvas, options) {
@ -97,11 +103,14 @@
// Transforms coordinate and dimension options
// based on the given orientation option:
loadImage.getTransformedOptions = function (img, opts) {
loadImage.getTransformedOptions = function (img, opts, data) {
var options = originalGetTransformedOptions.call(loadImage, img, opts)
var orientation = options.orientation
var newOptions
var i
if (orientation === true && data && data.exif) {
orientation = data.exif.get('Orientation')
}
if (!orientation || orientation > 8 || orientation === 1) {
return options
}
@ -111,7 +120,8 @@
newOptions[i] = options[i]
}
}
switch (options.orientation) {
newOptions.orientation = orientation
switch (orientation) {
case 2:
// horizontal flip
newOptions.left = options.right

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -9,7 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global define, module, window, document, URL, webkitURL, FileReader */
/* global define, URL, webkitURL, FileReader */
;(function ($) {
'use strict'
@ -17,26 +17,20 @@
// Loads an image for a given File object.
// Invokes the callback with an img or optional canvas
// element (if supported by the browser) as parameter:
var loadImage = function (file, callback, options) {
function loadImage (file, callback, options) {
var img = document.createElement('img')
var url
var oUrl
img.onerror = callback
img.onload = function () {
if (oUrl && !(options && options.noRevoke)) {
loadImage.revokeObjectURL(oUrl)
}
if (callback) {
callback(loadImage.scale(img, options))
}
img.onerror = function (event) {
return loadImage.onerror(img, event, file, callback, options)
}
img.onload = function (event) {
return loadImage.onload(img, event, file, callback, options)
}
if (loadImage.isInstanceOf('Blob', file) ||
// Files are also Blob instances, but some browsers
// (Firefox 3.6) support the File API but not Blobs:
loadImage.isInstanceOf('File', file)) {
url = oUrl = loadImage.createObjectURL(file)
// Store the file type for resize processing:
img._type = file.type
url = img._objectURL = loadImage.createObjectURL(file)
} else if (typeof file === 'string') {
url = file
if (options && options.crossOrigin) {
@ -53,10 +47,8 @@
var target = e.target
if (target && target.result) {
img.src = target.result
} else {
if (callback) {
callback(e)
}
} else if (callback) {
callback(e)
}
})
}
@ -66,11 +58,36 @@
(window.URL && URL.revokeObjectURL && URL) ||
(window.webkitURL && webkitURL)
function revokeHelper (img, options) {
if (img._objectURL && !(options && options.noRevoke)) {
loadImage.revokeObjectURL(img._objectURL)
delete img._objectURL
}
}
loadImage.isInstanceOf = function (type, obj) {
// Cross-frame instanceof check
return Object.prototype.toString.call(obj) === '[object ' + type + ']'
}
loadImage.transform = function (img, options, callback, file, data) {
callback(loadImage.scale(img, options, data), data)
}
loadImage.onerror = function (img, event, file, callback, options) {
revokeHelper(img, options)
if (callback) {
callback.call(img, event)
}
}
loadImage.onload = function (img, event, file, callback, options) {
revokeHelper(img, options)
if (callback) {
loadImage.transform(img, options, callback, file, {})
}
}
// Transform image coordinates, allows to override e.g.
// the canvas orientation based on the orientation option,
// gets canvas, options passed as arguments:
@ -136,8 +153,7 @@
return canvas
}
// This method is used to determine if the target image
// should be a canvas element:
// Determines if the target image should be a canvas element:
loadImage.hasCanvasOption = function (options) {
return options.canvas || options.crop || !!options.aspectRatio
}
@ -147,7 +163,7 @@
// Returns a canvas object if the browser supports canvas
// and the hasCanvasOption method returns true or a canvas
// object is passed as image, else the scaled image:
loadImage.scale = function (img, options) {
loadImage.scale = function (img, options, data) {
options = options || {}
var canvas = document.createElement('canvas')
var useCanvas = img.getContext ||
@ -188,7 +204,7 @@
}
}
if (useCanvas) {
options = loadImage.getTransformedOptions(img, options)
options = loadImage.getTransformedOptions(img, options, data)
sourceX = options.left || 0
sourceY = options.top || 0
if (options.sourceWidth) {

@ -1,6 +1,6 @@
{
"name": "blueimp-load-image",
"version": "2.6.2",
"version": "2.7.0",
"main": "index.js",
"title": "JavaScript Load Image",
"description": "JavaScript Load Image is a library to load images provided as File or Blob objects or via URL. It returns an optionally scaled and/or cropped HTML img or canvas element. It also provides a method to parse image meta data to extract Exif tags and thumbnails and to restore the complete image header after resizing.",
@ -31,13 +31,16 @@
"url": "git://github.com/blueimp/JavaScript-Load-Image.git"
},
"devDependencies": {
"mocha-phantomjs": "4.0.1",
"standard": "6.0.7",
"uglify-js": "2.6.1"
"phantomjs-prebuilt": "2.1.13",
"mocha-phantomjs-core": "1.3.1",
"standard": "8.3.0",
"uglify-js": "2.7.3"
},
"scripts": {
"test": "standard *.js js/*.js test/*.js && mocha-phantomjs test/index.html",
"build": "cd js && uglifyjs load-image.js load-image-orientation.js load-image-meta.js load-image-exif.js load-image-exif-map.js -c -m -o load-image.all.min.js --source-map load-image.all.min.js.map",
"lint": "standard *.js js/*.js test/*.js",
"unit": "phantomjs node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html",
"test": "npm run lint && npm run unit",
"build": "cd js && uglifyjs load-image.js load-image-meta.js load-image-exif.js load-image-exif-map.js load-image-orientation.js -c -m -o load-image.all.min.js --source-map load-image.all.min.js.map",
"preversion": "npm test",
"version": "npm run build && git add -A js",
"postversion": "git push --tags origin master master:gh-pages && npm publish"

@ -24,17 +24,17 @@
<body>
<div id="mocha"></div>
<script src="vendor/mocha.js"></script>
<script src="vendor/expect.js"></script>
<script src="vendor/chai.js"></script>
<script>
window.initMochaPhantomJS && initMochaPhantomJS();
mocha.setup('bdd');
</script>
<script src="vendor/canvas-to-blob.js"></script>
<script src="../js/load-image.js"></script>
<script src="../js/load-image-orientation.js"></script>
<script src="../js/load-image-meta.js"></script>
<script src="../js/load-image-exif.js"></script>
<script src="../js/load-image-exif-map.js"></script>
<script src="../js/load-image-orientation.js"></script>
<script src="test.js"></script>
<script>
mocha.checkLeaks();

@ -9,7 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global window, describe, it, Blob */
/* global describe, it, Blob */
;(function (expect, loadImage) {
'use strict'
@ -21,7 +21,7 @@
'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7'
var imageUrlGIF = 'data:image/gif;base64,' + b64DataGIF
var blobGIF = canCreateBlob && window.dataURLtoBlob(imageUrlGIF)
// 1x2px JPEG (color white, with the Exif orientation flag set to 6):
// 2x1px JPEG (color white, with the Exif orientation flag set to 6):
var b64DataJPEG = '/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAASUkqAAgAAA' +
'ABABIBAwABAAAABgASAAAAAAD/2wBDAAEBAQEBAQEBAQEBAQEB' +
'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ' +
@ -59,43 +59,43 @@
var img = loadImage(blobGIF, function () {
return
})
expect(img).to.be.an(Object)
expect(img).to.be.an.instanceOf(Object)
expect(img.onload).to.be.a('function')
expect(img.onerror).to.be.a('function')
})
it('Load image url', function (done) {
expect(loadImage(imageUrlGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(60)
expect(img.width).to.equal(80)
expect(img.height).to.equal(60)
done()
})).to.be.ok()
})).to.be.ok
})
it('Load image blob', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(60)
expect(img.width).to.equal(80)
expect(img.height).to.equal(60)
done()
})).to.be.ok()
})).to.be.ok
})
it('Return image loading error to callback', function (done) {
expect(loadImage('404', function (img) {
expect(img).to.be.a(window.Event)
expect(img.type).to.be('error')
expect(img).to.be.an.instanceOf(window.Event)
expect(img.type).to.equal('error')
done()
})).to.be.ok()
})).to.be.ok
})
it('Keep object URL if noRevoke is true', function (done) {
expect(loadImage(blobGIF, function (img) {
loadImage(img.src, function (img2) {
expect(img.width).to.be(img2.width)
expect(img.height).to.be(img2.height)
expect(img.width).to.equal(img2.width)
expect(img.height).to.equal(img2.height)
done()
})
}, {noRevoke: true})).to.be.ok()
}, {noRevoke: true})).to.be.ok
})
it('Discard object URL if noRevoke is undefined or false', function (done) {
@ -103,12 +103,12 @@
loadImage(img.src, function (img2) {
if (!window.callPhantom) {
// revokeObjectUrl doesn't seem to have an effect in PhantomJS
expect(img2).to.be.a(window.Event)
expect(img2.type).to.be('error')
expect(img2).to.be.an.instanceOf(window.Event)
expect(img2.type).to.equal('error')
}
done()
})
})).to.be.ok()
})).to.be.ok
})
})
@ -116,146 +116,146 @@
describe('max/min', function () {
it('Scale to maxWidth', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(40)
expect(img.height).to.be(30)
expect(img.width).to.equal(40)
expect(img.height).to.equal(30)
done()
}, {maxWidth: 40})).to.be.ok()
}, {maxWidth: 40})).to.be.ok
})
it('Scale to maxHeight', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(20)
expect(img.height).to.be(15)
expect(img.width).to.equal(20)
expect(img.height).to.equal(15)
done()
}, {maxHeight: 15})).to.be.ok()
}, {maxHeight: 15})).to.be.ok
})
it('Scale to minWidth', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(160)
expect(img.height).to.be(120)
expect(img.width).to.equal(160)
expect(img.height).to.equal(120)
done()
}, {minWidth: 160})).to.be.ok()
}, {minWidth: 160})).to.be.ok
})
it('Scale to minHeight', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(320)
expect(img.height).to.be(240)
expect(img.width).to.equal(320)
expect(img.height).to.equal(240)
done()
}, {minHeight: 240})).to.be.ok()
}, {minHeight: 240})).to.be.ok
})
it('Scale to minWidth but respect maxWidth', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(160)
expect(img.height).to.be(120)
expect(img.width).to.equal(160)
expect(img.height).to.equal(120)
done()
}, {minWidth: 240, maxWidth: 160})).to.be.ok()
}, {minWidth: 240, maxWidth: 160})).to.be.ok
})
it('Scale to minHeight but respect maxHeight', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(160)
expect(img.height).to.be(120)
expect(img.width).to.equal(160)
expect(img.height).to.equal(120)
done()
}, {minHeight: 180, maxHeight: 120})).to.be.ok()
}, {minHeight: 180, maxHeight: 120})).to.be.ok
})
it('Scale to minWidth but respect maxHeight', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(160)
expect(img.height).to.be(120)
expect(img.width).to.equal(160)
expect(img.height).to.equal(120)
done()
}, {minWidth: 240, maxHeight: 120})).to.be.ok()
}, {minWidth: 240, maxHeight: 120})).to.be.ok
})
it('Scale to minHeight but respect maxWidth', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(160)
expect(img.height).to.be(120)
expect(img.width).to.equal(160)
expect(img.height).to.equal(120)
done()
}, {minHeight: 180, maxWidth: 160})).to.be.ok()
}, {minHeight: 180, maxWidth: 160})).to.be.ok
})
it('Scale up with the given pixelRatio', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(320)
expect(img.height).to.be(240)
expect(img.style.width).to.be('160px')
expect(img.style.height).to.be('120px')
expect(img.width).to.equal(320)
expect(img.height).to.equal(240)
expect(img.style.width).to.equal('160px')
expect(img.style.height).to.equal('120px')
done()
}, {minWidth: 160, canvas: true, pixelRatio: 2})).to.be.ok()
}, {minWidth: 160, canvas: true, pixelRatio: 2})).to.be.ok
})
it('Scale down with the given pixelRatio', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(60)
expect(img.style.width).to.be('40px')
expect(img.style.height).to.be('30px')
expect(img.width).to.equal(80)
expect(img.height).to.equal(60)
expect(img.style.width).to.equal('40px')
expect(img.style.height).to.equal('30px')
done()
}, {maxWidth: 40, canvas: true, pixelRatio: 2})).to.be.ok()
}, {maxWidth: 40, canvas: true, pixelRatio: 2})).to.be.ok
})
it('Scale down with the given downsamplingRatio', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(20)
expect(img.height).to.be(15)
expect(img.width).to.equal(20)
expect(img.height).to.equal(15)
done()
}, {maxWidth: 20, canvas: true, downsamplingRatio: 0.5})).to.be.ok()
}, {maxWidth: 20, canvas: true, downsamplingRatio: 0.5})).to.be.ok
})
it('Ignore max settings if image dimensions are smaller', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(60)
expect(img.width).to.equal(80)
expect(img.height).to.equal(60)
done()
}, {maxWidth: 160, maxHeight: 120})).to.be.ok()
}, {maxWidth: 160, maxHeight: 120})).to.be.ok
})
it('Ignore min settings if image dimensions are larger', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(60)
expect(img.width).to.equal(80)
expect(img.height).to.equal(60)
done()
}, {minWidth: 40, minHeight: 30})).to.be.ok()
}, {minWidth: 40, minHeight: 30})).to.be.ok
})
})
describe('contain', function () {
it('Scale up to contain image in max dimensions', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(160)
expect(img.height).to.be(120)
expect(img.width).to.equal(160)
expect(img.height).to.equal(120)
done()
}, {maxWidth: 160, maxHeight: 160, contain: true})).to.be.ok()
}, {maxWidth: 160, maxHeight: 160, contain: true})).to.be.ok
})
it('Scale down to contain image in max dimensions', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(40)
expect(img.height).to.be(30)
expect(img.width).to.equal(40)
expect(img.height).to.equal(30)
done()
}, {maxWidth: 40, maxHeight: 40, contain: true})).to.be.ok()
}, {maxWidth: 40, maxHeight: 40, contain: true})).to.be.ok
})
})
describe('cover', function () {
it('Scale up to cover max dimensions with image dimensions', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(160)
expect(img.height).to.be(120)
expect(img.width).to.equal(160)
expect(img.height).to.equal(120)
done()
}, {maxWidth: 120, maxHeight: 120, cover: true})).to.be.ok()
}, {maxWidth: 120, maxHeight: 120, cover: true})).to.be.ok
})
it('Scale down to cover max dimensions with image dimensions', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(40)
expect(img.height).to.be(30)
expect(img.width).to.equal(40)
expect(img.height).to.equal(30)
done()
}, {maxWidth: 30, maxHeight: 30, cover: true})).to.be.ok()
}, {maxWidth: 30, maxHeight: 30, cover: true})).to.be.ok
})
})
})
@ -263,208 +263,219 @@
describe('Cropping', function () {
it('Crop to same values for maxWidth and maxHeight', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(40)
expect(img.height).to.be(40)
expect(img.width).to.equal(40)
expect(img.height).to.equal(40)
done()
}, {maxWidth: 40, maxHeight: 40, crop: true})).to.be.ok()
}, {maxWidth: 40, maxHeight: 40, crop: true})).to.be.ok
})
it('Crop to different values for maxWidth and maxHeight', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(40)
expect(img.height).to.be(60)
expect(img.width).to.equal(40)
expect(img.height).to.equal(60)
done()
}, {maxWidth: 40, maxHeight: 60, crop: true})).to.be.ok()
}, {maxWidth: 40, maxHeight: 60, crop: true})).to.be.ok
})
it('Crop using the given sourceWidth and sourceHeight dimensions', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(40)
expect(img.height).to.be(40)
expect(img.width).to.equal(40)
expect(img.height).to.equal(40)
done()
}, {sourceWidth: 40, sourceHeight: 40, crop: true})).to.be.ok()
}, {sourceWidth: 40, sourceHeight: 40, crop: true})).to.be.ok
})
it('Crop using the given left and top coordinates', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(40)
expect(img.height).to.be(20)
expect(img.width).to.equal(40)
expect(img.height).to.equal(20)
done()
}, {left: 40, top: 40, crop: true})).to.be.ok()
}, {left: 40, top: 40, crop: true})).to.be.ok
})
it('Crop using the given right and bottom coordinates', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(40)
expect(img.height).to.be(20)
expect(img.width).to.equal(40)
expect(img.height).to.equal(20)
done()
}, {right: 40, bottom: 40, crop: true})).to.be.ok()
}, {right: 40, bottom: 40, crop: true})).to.be.ok
})
it('Crop using the given 2:1 aspectRatio', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(40)
expect(img.width).to.equal(80)
expect(img.height).to.equal(40)
done()
}, {aspectRatio: 2})).to.be.ok()
}, {aspectRatio: 2})).to.be.ok
})
it('Crop using the given 2:3 aspectRatio', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(40)
expect(img.height).to.be(60)
expect(img.width).to.equal(40)
expect(img.height).to.equal(60)
done()
}, {aspectRatio: 2 / 3})).to.be.ok()
}, {aspectRatio: 2 / 3})).to.be.ok
})
it('Crop using maxWidth/maxHeight with the given pixelRatio', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(80)
expect(img.style.width).to.be('40px')
expect(img.style.height).to.be('40px')
expect(img.width).to.equal(80)
expect(img.height).to.equal(80)
expect(img.style.width).to.equal('40px')
expect(img.style.height).to.equal('40px')
done()
}, {maxWidth: 40, maxHeight: 40, crop: true, pixelRatio: 2})).to.be.ok()
}, {maxWidth: 40, maxHeight: 40, crop: true, pixelRatio: 2})).to.be.ok
})
it('Crop using sourceWidth/sourceHeight with the given pixelRatio', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(80)
expect(img.style.width).to.be('40px')
expect(img.style.height).to.be('40px')
expect(img.width).to.equal(80)
expect(img.height).to.equal(80)
expect(img.style.width).to.equal('40px')
expect(img.style.height).to.equal('40px')
done()
}, {sourceWidth: 40, sourceHeight: 40, crop: true, pixelRatio: 2})).to.be.ok()
}, {sourceWidth: 40, sourceHeight: 40, crop: true, pixelRatio: 2})).to.be.ok
})
})
describe('Orientation', function () {
it('Should keep the orientation', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(60)
expect(img.width).to.equal(80)
expect(img.height).to.equal(60)
done()
}, {orientation: 1})).to.be.ok()
}, {orientation: 1})).to.be.ok
})
it('Should rotate left', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(60)
expect(img.height).to.be(80)
expect(img.width).to.equal(60)
expect(img.height).to.equal(80)
done()
}, {orientation: 8})).to.be.ok()
}, {orientation: 8})).to.be.ok
})
it('Should rotate right', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(60)
expect(img.height).to.be(80)
expect(img.width).to.equal(60)
expect(img.height).to.equal(80)
done()
}, {orientation: 6})).to.be.ok()
}, {orientation: 6})).to.be.ok
})
it('Should adjust constraints to new coordinates', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(60)
expect(img.height).to.be(80)
expect(img.width).to.equal(60)
expect(img.height).to.equal(80)
done()
}, {orientation: 6, maxWidth: 60, maxHeight: 80})).to.be.ok()
}, {orientation: 6, maxWidth: 60, maxHeight: 80})).to.be.ok
})
it('Should adjust left and top to new coordinates', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(30)
expect(img.height).to.be(60)
expect(img.width).to.equal(30)
expect(img.height).to.equal(60)
done()
}, {orientation: 5, left: 30, top: 20})).to.be.ok()
}, {orientation: 5, left: 30, top: 20})).to.be.ok
})
it('Should adjust right and bottom to new coordinates', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(30)
expect(img.height).to.be(60)
expect(img.width).to.equal(30)
expect(img.height).to.equal(60)
done()
}, {orientation: 5, right: 30, bottom: 20})).to.be.ok()
}, {orientation: 5, right: 30, bottom: 20})).to.be.ok
})
it('Should adjust left and bottom to new coordinates', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(30)
expect(img.height).to.be(60)
expect(img.width).to.equal(30)
expect(img.height).to.equal(60)
done()
}, {orientation: 7, left: 30, bottom: 20})).to.be.ok()
}, {orientation: 7, left: 30, bottom: 20})).to.be.ok
})
it('Should adjust right and top to new coordinates', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(30)
expect(img.height).to.be(60)
expect(img.width).to.equal(30)
expect(img.height).to.equal(60)
done()
}, {orientation: 7, right: 30, top: 20})).to.be.ok()
}, {orientation: 7, right: 30, top: 20})).to.be.ok
})
it('Should rotate left with the given pixelRatio', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(120)
expect(img.height).to.be(160)
expect(img.style.width).to.be('60px')
expect(img.style.height).to.be('80px')
expect(img.width).to.equal(120)
expect(img.height).to.equal(160)
expect(img.style.width).to.equal('60px')
expect(img.style.height).to.equal('80px')
done()
}, {orientation: 8, pixelRatio: 2})).to.be.ok()
}, {orientation: 8, pixelRatio: 2})).to.be.ok
})
it('Should rotate right with the given pixelRatio', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(120)
expect(img.height).to.be(160)
expect(img.style.width).to.be('60px')
expect(img.style.height).to.be('80px')
expect(img.width).to.equal(120)
expect(img.height).to.equal(160)
expect(img.style.width).to.equal('60px')
expect(img.style.height).to.equal('80px')
done()
}, {orientation: 6, pixelRatio: 2})).to.be.ok()
}, {orientation: 6, pixelRatio: 2})).to.be.ok
})
it('Should ignore too small orientation value', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(60)
expect(img.width).to.equal(80)
expect(img.height).to.equal(60)
done()
}, {orientation: -1})).to.be.ok()
}, {orientation: -1})).to.be.ok
})
it('Should ignore too large orientation value', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.width).to.be(80)
expect(img.height).to.be(60)
expect(img.width).to.equal(80)
expect(img.height).to.equal(60)
done()
}, {orientation: 9})).to.be.ok()
}, {orientation: 9})).to.be.ok
})
it('Should rotate right based on the exif orientation value', function (done) {
expect(loadImage(blobJPEG, function (img, data) {
expect(data).to.be.ok
expect(data.exif).to.be.ok
expect(data.exif.get('Orientation')).to.equal(6)
expect(img.width).to.equal(1)
expect(img.height).to.equal(2)
done()
}, {orientation: true})).to.be.ok
})
})
describe('Canvas', function () {
it('Return img element to callback if canvas is not true', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.getContext).to.not.be.ok()
expect(img.nodeName.toLowerCase()).to.be('img')
expect(img.getContext).to.not.be.ok
expect(img.nodeName.toLowerCase()).to.equal('img')
done()
})).to.be.ok()
})).to.be.ok
})
it('Return canvas element to callback if canvas is true', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.getContext).to.be.ok()
expect(img.nodeName.toLowerCase()).to.be('canvas')
expect(img.getContext).to.be.ok
expect(img.nodeName.toLowerCase()).to.equal('canvas')
done()
}, {canvas: true})).to.be.ok()
}, {canvas: true})).to.be.ok
})
it('Return scaled canvas element to callback', function (done) {
expect(loadImage(blobGIF, function (img) {
expect(img.getContext).to.be.ok()
expect(img.nodeName.toLowerCase()).to.be('canvas')
expect(img.width).to.be(40)
expect(img.height).to.be(30)
expect(img.getContext).to.be.ok
expect(img.nodeName.toLowerCase()).to.equal('canvas')
expect(img.width).to.equal(40)
expect(img.height).to.equal(30)
done()
}, {canvas: true, maxWidth: 40})).to.be.ok()
}, {canvas: true, maxWidth: 40})).to.be.ok
})
it('Accept a canvas element as parameter for loadImage.scale', function (done) {
@ -472,39 +483,49 @@
img = loadImage.scale(img, {
maxWidth: 40
})
expect(img.getContext).to.be.ok()
expect(img.nodeName.toLowerCase()).to.be('canvas')
expect(img.width).to.be(40)
expect(img.height).to.be(30)
expect(img.getContext).to.be.ok
expect(img.nodeName.toLowerCase()).to.equal('canvas')
expect(img.width).to.equal(40)
expect(img.height).to.equal(30)
done()
}, {canvas: true})).to.be.ok()
}, {canvas: true})).to.be.ok
})
})
describe('Metadata', function () {
it('Should parse Exif information', function (done) {
loadImage.parseMetaData(blobJPEG, function (data) {
expect(data.exif).to.be.ok()
expect(data.exif.get('Orientation')).to.be(6)
expect(data.exif).to.be.ok
expect(data.exif.get('Orientation')).to.equal(6)
done()
})
})
it('Should parse the complete image head', function (done) {
loadImage.parseMetaData(blobJPEG, function (data) {
expect(data.imageHead).to.be.ok()
expect(data.imageHead).to.be.ok
loadImage.parseMetaData(
createBlob(data.imageHead, 'image/jpeg'),
function (data) {
expect(data.exif).to.be.ok()
expect(data.exif.get('Orientation')).to.be(6)
expect(data.exif).to.be.ok
expect(data.exif.get('Orientation')).to.equal(6)
done()
}
)
})
})
it('Should parse meta data automatically', function (done) {
expect(loadImage(blobJPEG, function (img, data) {
expect(data).to.be.ok
expect(data.imageHead).to.be.ok
expect(data.exif).to.be.ok
expect(data.exif.get('Orientation')).to.equal(6)
done()
}, {meta: true})).to.be.ok
})
})
}(
this.expect,
this.chai.expect,
this.loadImage
))

@ -1,12 +1,12 @@
{
"name": "blueimp-tmpl",
"homepage": "https://github.com/blueimp/JavaScript-Templates",
"version": "3.4.0",
"_release": "3.4.0",
"version": "3.5.0",
"_release": "3.5.0",
"_resolution": {
"type": "version",
"tag": "v3.4.0",
"commit": "dcb7a7b44c733c5df0b6000e777bc6942646607e"
"tag": "v3.5.0",
"commit": "19dfc68580d036de22f1767ef8fde1a6da75b64b"
},
"_source": "https://github.com/blueimp/JavaScript-Templates.git",
"_target": ">=2.5.4",

@ -10,8 +10,6 @@
* http://www.opensource.org/licenses/MIT
*/
/*global require, __dirname, process, console */
;(function () {
'use strict'
var path = require('path')

@ -9,7 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
/* global document, tmpl */
/* global tmpl */
;(function () {
'use strict'

@ -9,7 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global define, module */
/* global define */
;(function ($) {
'use strict'
@ -20,7 +20,7 @@
}
}
tmpl.cache = {}
tmpl.encReg = /[<>&"'\x00]/g
tmpl.encReg = /[<>&"'\x00]/g // eslint-disable-line no-control-regex
tmpl.encMap = {
'<': '&lt;',
'>': '&gt;',

@ -12,7 +12,7 @@
* http://ejohn.org/blog/javascript-micro-templating/
*/
/*global document, define, module */
/* global define */
;(function ($) {
'use strict'
@ -55,7 +55,7 @@
return "_s+='"
}
}
tmpl.encReg = /[<>&"'\x00]/g
tmpl.encReg = /[<>&"'\x00]/g // eslint-disable-line no-control-regex
tmpl.encMap = {
'<': '&lt;',
'>': '&gt;',

@ -1,2 +1,2 @@
!function(e){"use strict";var n=function(e,t){var r=/[^\w\-\.:]/.test(e)?new Function(n.arg+",tmpl","var _e=tmpl.encode"+n.helper+",_s='"+e.replace(n.regexp,n.func)+"';return _s;"):n.cache[e]=n.cache[e]||n(n.load(e));return t?r(t,n):function(e){return r(e,n)}};n.cache={},n.load=function(e){return document.getElementById(e).innerHTML},n.regexp=/([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,n.func=function(e,n,t,r,c,u){return n?{"\n":"\\n","\r":"\\r"," ":"\\t"," ":" "}[n]||"\\"+n:t?"="===t?"'+_e("+r+")+'":"'+("+r+"==null?'':"+r+")+'":c?"';":u?"_s+='":void 0},n.encReg=/[<>&"'\x00]/g,n.encMap={"<":"&lt;",">":"&gt;","&":"&amp;",'"':"&quot;","'":"&#39;"},n.encode=function(e){return(null==e?"":""+e).replace(n.encReg,function(e){return n.encMap[e]||""})},n.arg="o",n.helper=",print=function(s,e){_s+=e?(s==null?'':s):_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return n}):"object"==typeof module&&module.exports?module.exports=n:e.tmpl=n}(this);
!function(e){"use strict";var n=function(e,t){var r=/[^\w\-\.:]/.test(e)?new Function(n.arg+",tmpl","var _e=tmpl.encode"+n.helper+",_s='"+e.replace(n.regexp,n.func)+"';return _s;"):n.cache[e]=n.cache[e]||n(n.load(e));return t?r(t,n):function(e){return r(e,n)}};n.cache={},n.load=function(e){return document.getElementById(e).innerHTML},n.regexp=/([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g,n.func=function(e,n,t,r,c,u){return n?{"\n":"\\n","\r":"\\r","\t":"\\t"," ":" "}[n]||"\\"+n:t?"="===t?"'+_e("+r+")+'":"'+("+r+"==null?'':"+r+")+'":c?"';":u?"_s+='":void 0},n.encReg=/[<>&"'\x00]/g,n.encMap={"<":"&lt;",">":"&gt;","&":"&amp;",'"':"&quot;","'":"&#39;"},n.encode=function(e){return(null==e?"":""+e).replace(n.encReg,function(e){return n.encMap[e]||""})},n.arg="o",n.helper=",print=function(s,e){_s+=e?(s==null?'':s):_e(s);},include=function(s,d){_s+=tmpl(s,d);}","function"==typeof define&&define.amd?define(function(){return n}):"object"==typeof module&&module.exports?module.exports=n:e.tmpl=n}(this);
//# sourceMappingURL=tmpl.min.js.map

@ -1 +1 @@
{"version":3,"sources":["tmpl.js"],"names":["$","tmpl","str","data","f","test","Function","arg","helper","replace","regexp","func","cache","load","id","document","getElementById","innerHTML","s","p1","p2","p3","p4","p5","\n","\r","\t"," ","encReg","encMap","<",">","&","\"","'","encode","c","define","amd","module","exports","this"],"mappings":"CAgBE,SAAUA,GACV,YACA,IAAIC,GAAO,SAAUC,EAAKC,GACxB,GAAIC,GAAK,aAAaC,KAAKH,GAEvB,GAAII,UACJL,EAAKM,IAAM,QACX,qBAAuBN,EAAKO,OAAS,QACnCN,EAAIO,QAAQR,EAAKS,OAAQT,EAAKU,MAAQ,gBAJxCV,EAAKW,MAAMV,GAAOD,EAAKW,MAAMV,IAAQD,EAAKA,EAAKY,KAAKX,GAMxD,OAAOC,GAAOC,EAAED,EAAMF,GAAQ,SAAUE,GACtC,MAAOC,GAAED,EAAMF,IAGnBA,GAAKW,SACLX,EAAKY,KAAO,SAAUC,GACpB,MAAOC,UAASC,eAAeF,GAAIG,WAErChB,EAAKS,OAAS,2EACdT,EAAKU,KAAO,SAAUO,EAAGC,EAAIC,EAAIC,EAAIC,EAAIC,GACvC,MAAIJ,IAEAK,KAAM,MACNC,KAAM,MACNC,IAAM,MACNC,IAAK,KACLR,IAAO,KAAOA,EAEdC,EACS,MAAPA,EACK,QAAUC,EAAK,MAEjB,MAAQA,EAAK,aAAeA,EAAK,MAEtCC,EACK,KAELC,EACK,QADT,QAIFtB,EAAK2B,OAAS,eACd3B,EAAK4B,QACHC,IAAK,OACLC,IAAK,OACLC,IAAK,QACLC,IAAK,SACLC,IAAK,SAEPjC,EAAKkC,OAAS,SAAUjB,GACtB,OAAa,MAALA,EAAY,GAAK,GAAKA,GAAGT,QAC/BR,EAAK2B,OACL,SAAUQ,GACR,MAAOnC,GAAK4B,OAAOO,IAAM,MAI/BnC,EAAKM,IAAM,IACXN,EAAKO,OAAS,0FAEQ,kBAAX6B,SAAyBA,OAAOC,IACzCD,OAAO,WACL,MAAOpC,KAEkB,gBAAXsC,SAAuBA,OAAOC,QAC9CD,OAAOC,QAAUvC,EAEjBD,EAAEC,KAAOA,GAEXwC","file":"tmpl.min.js"}
{"version":3,"sources":["tmpl.js"],"names":["$","tmpl","str","data","f","test","Function","arg","helper","replace","regexp","func","cache","load","id","document","getElementById","innerHTML","s","p1","p2","p3","p4","p5","\n","\r","\t"," ","encReg","encMap","<",">","&","\"","'","encode","c","define","amd","module","exports","this"],"mappings":"CAgBE,SAAUA,GACV,YACA,IAAIC,GAAO,SAAUC,EAAKC,GACxB,GAAIC,GAAK,aAAaC,KAAKH,GAEvB,GAAII,UACJL,EAAKM,IAAM,QACX,qBAAuBN,EAAKO,OAAS,QACnCN,EAAIO,QAAQR,EAAKS,OAAQT,EAAKU,MAAQ,gBAJxCV,EAAKW,MAAMV,GAAOD,EAAKW,MAAMV,IAAQD,EAAKA,EAAKY,KAAKX,GAMxD,OAAOC,GAAOC,EAAED,EAAMF,GAAQ,SAAUE,GACtC,MAAOC,GAAED,EAAMF,IAGnBA,GAAKW,SACLX,EAAKY,KAAO,SAAUC,GACpB,MAAOC,UAASC,eAAeF,GAAIG,WAErChB,EAAKS,OAAS,2EACdT,EAAKU,KAAO,SAAUO,EAAGC,EAAIC,EAAIC,EAAIC,EAAIC,GACvC,MAAIJ,IAEAK,KAAM,MACNC,KAAM,MACNC,KAAM,MACNC,IAAK,KACLR,IAAO,KAAOA,EAEdC,EACS,MAAPA,EACK,QAAUC,EAAK,MAEjB,MAAQA,EAAK,aAAeA,EAAK,MAEtCC,EACK,KAELC,EACK,QADT,QAIFtB,EAAK2B,OAAS,eACd3B,EAAK4B,QACHC,IAAK,OACLC,IAAK,OACLC,IAAK,QACLC,IAAK,SACLC,IAAK,SAEPjC,EAAKkC,OAAS,SAAUjB,GACtB,OAAa,MAALA,EAAY,GAAK,GAAKA,GAAGT,QAC/BR,EAAK2B,OACL,SAAUQ,GACR,MAAOnC,GAAK4B,OAAOO,IAAM,MAI/BnC,EAAKM,IAAM,IACXN,EAAKO,OAAS,0FAEQ,kBAAX6B,SAAyBA,OAAOC,IACzCD,OAAO,WACL,MAAOpC,KAEkB,gBAAXsC,SAAuBA,OAAOC,QAC9CD,OAAOC,QAAUvC,EAEjBD,EAAEC,KAAOA,GAEXwC","file":"tmpl.min.js"}

@ -1,6 +1,6 @@
{
"name": "blueimp-tmpl",
"version": "3.4.0",
"version": "3.5.0",
"title": "JavaScript Templates",
"description": "1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.",
"keywords": [
@ -19,13 +19,15 @@
},
"license": "MIT",
"devDependencies": {
"expect.js": "0.3.1",
"mocha": "2.3.4",
"standard": "6.0.7",
"uglify-js": "2.6.1"
"chai": "3.5.0",
"mocha": "3.1.0",
"standard": "8.3.0",
"uglify-js": "2.7.3"
},
"scripts": {
"test": "standard js/*.js test/*.js && mocha",
"lint": "standard js/*.js test/*.js",
"unit": "mocha",
"test": "npm run lint && npm run unit",
"build": "cd js && uglifyjs tmpl.js -c -m -o tmpl.min.js --source-map tmpl.min.js.map",
"preversion": "npm test",
"version": "npm run build && git add -A js",

@ -24,7 +24,7 @@
<body>
<div id="mocha"></div>
<script src="vendor/mocha.js"></script>
<script src="vendor/expect.js"></script>
<script src="vendor/chai.js"></script>
<script>
mocha.setup('bdd');
</script>

@ -9,7 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
/*global beforeEach, afterEach, describe, it, require */
/* global beforeEach, afterEach, describe, it */
;(function (context, expect, tmpl) {
'use strict'
@ -53,7 +53,7 @@
it('String template', function () {
expect(
tmpl('{%=o.value%}', data)
).to.be(
).to.equal(
'value'
)
})
@ -61,7 +61,7 @@
it('Load template by id', function () {
expect(
tmpl('template', data)
).to.be(
).to.equal(
'value'
)
})
@ -69,7 +69,7 @@
it('Retun function when called without data parameter', function () {
expect(
tmpl('{%=o.value%}')(data)
).to.be(
).to.equal(
'value'
)
})
@ -86,7 +86,7 @@
it('Escape HTML special characters with {%=o.prop%}', function () {
expect(
tmpl('{%=o.special%}', data)
).to.be(
).to.equal(
'&lt;&gt;&amp;&quot;&#39;'
)
})
@ -94,7 +94,7 @@
it('Allow HTML special characters with {%#o.prop%}', function () {
expect(
tmpl('{%#o.special%}', data)
).to.be(
).to.equal(
'<>&"\'\x00'
)
})
@ -102,7 +102,7 @@
it('Function call', function () {
expect(
tmpl('{%=o.func()%}', data)
).to.be(
).to.equal(
'value'
)
})
@ -110,7 +110,7 @@
it('Dot notation', function () {
expect(
tmpl('{%=o.deep.value%}', data)
).to.be(
).to.equal(
'value'
)
})
@ -118,7 +118,7 @@
it('Handle single quotes', function () {
expect(
tmpl('\'single quotes\'{%=": \'"%}', data)
).to.be(
).to.equal(
"'single quotes': &#39;"
)
})
@ -126,7 +126,7 @@
it('Handle double quotes', function () {
expect(
tmpl('"double quotes"{%=": \\""%}', data)
).to.be(
).to.equal(
'"double quotes": &quot;'
)
})
@ -134,7 +134,7 @@
it('Handle backslashes', function () {
expect(
tmpl('\\backslashes\\{%=": \\\\"%}', data)
).to.be(
).to.equal(
'\\backslashes\\: \\'
)
})
@ -148,7 +148,7 @@
'{%=o.zeroValue%}',
data
)
).to.be(
).to.equal(
'false0'
)
})
@ -162,7 +162,7 @@
'{%#o.zeroValue%}',
data
)
).to.be(
).to.equal(
'false0'
)
})
@ -173,7 +173,7 @@
'\n\r\t{%=o.value%} \n\r\t{%=o.value%} ',
data
)
).to.be(
).to.equal(
'\n\r\tvalue \n\r\tvalue '
)
})
@ -183,7 +183,7 @@
it('Escape HTML special characters with print(data)', function () {
expect(
tmpl('{% print(o.special); %}', data)
).to.be(
).to.equal(
'&lt;&gt;&amp;&quot;&#39;'
)
})
@ -191,7 +191,7 @@
it('Allow HTML special characters with print(data, true)', function () {
expect(
tmpl('{% print(o.special, true); %}', data)
).to.be(
).to.equal(
'<>&"\'\x00'
)
})
@ -205,7 +205,7 @@
'{% print(o.zeroValue); %}',
data
)
).to.be(
).to.equal(
'false0'
)
})
@ -219,7 +219,7 @@
'{% print(o.zeroValue, true); %}',
data
)
).to.be(
).to.equal(
'false0'
)
})
@ -227,7 +227,7 @@
it('Include template', function () {
expect(
tmpl('{% include("template", {value: "value"}); %}', data)
).to.be(
).to.equal(
'value'
)
})
@ -235,7 +235,7 @@
it('If condition', function () {
expect(
tmpl('{% if (o.value) { %}true{% } else { %}false{% } %}', data)
).to.be(
).to.equal(
'true'
)
})
@ -246,7 +246,7 @@
'{% if (o.undefinedValue) { %}false{% } else { %}true{% } %}',
data
)
).to.be(
).to.equal(
'true'
)
})
@ -258,7 +258,7 @@
'{%=o.list[i]%}{% } %}',
data
)
).to.be(
).to.equal(
'12345'
)
})
@ -270,7 +270,7 @@
'print(o.list[i]);} %}',
data
)
).to.be(
).to.equal(
'12345'
)
})
@ -282,7 +282,7 @@
'include("template", {value: o.list[i]});} %}',
data
).replace(/[\r\n]/g, '')
).to.be(
).to.equal(
'12345'
)
})
@ -293,13 +293,13 @@
'{% if (o.list.length % 5 === 0) { %}5 list items{% } %}',
data
).replace(/[\r\n]/g, '')
).to.be(
).to.equal(
'5 list items'
)
})
})
}(
this,
this.expect || require('expect.js'),
(this.chai || require('chai')).expect,
this.tmpl || require('../js/tmpl')
))

@ -25,7 +25,7 @@
"tag": "v1.3.23",
"commit": "f000ab2a40a0e930c2913855b96a4e4d59c8920f"
},
"_source": "git://github.com/dangrossman/bootstrap-daterangepicker.git",
"_source": "https://github.com/dangrossman/bootstrap-daterangepicker.git",
"_target": "1.3.*",
"_originalSource": "bootstrap-daterangepicker"
}

@ -21,7 +21,7 @@
"_resolution": {
"type": "version",
"tag": "4.5.9",
"commit": "ba2580967f7409784921b4320e297522175e45bb"
"commit": "5de42515a5ca7015de75627ad8067f786d7fc425"
},
"_source": "https://github.com/AngelFQC/ckeditor-releases.git",
"_target": "*",

@ -57,7 +57,7 @@
"tag": "v1.0.0",
"commit": "c0805bc83c9270a0be4afdfbd02d517de7a4c970"
},
"_source": "git://github.com/fengyuanchen/cropper.git",
"_source": "https://github.com/fengyuanchen/cropper.git",
"_target": "1.0.*",
"_originalSource": "cropper"
}

@ -30,7 +30,7 @@
"tag": "v4.4.0",
"commit": "f2cc73da12f0e6d828bc2daaa72bff457067bf39"
},
"_source": "git://github.com/FortAwesome/Font-Awesome.git",
"_source": "https://github.com/FortAwesome/Font-Awesome.git",
"_target": "4.4.*",
"_originalSource": "fontawesome"
}

@ -56,7 +56,7 @@
"tag": "v2.3.2",
"commit": "29fb42d6316bd2c293fbcaf699af4427f80abebb"
},
"_source": "git://github.com/arshaw/fullcalendar.git",
"_source": "https://github.com/fullcalendar/fullcalendar.git",
"_target": "2.3.2",
"_originalSource": "fullcalendar"
}

@ -18,12 +18,12 @@
"karma.conf.js"
],
"homepage": "https://github.com/i18next/i18next",
"version": "3.4.1",
"_release": "3.4.1",
"version": "3.4.3",
"_release": "3.4.3",
"_resolution": {
"type": "version",
"tag": "v3.4.1",
"commit": "ae96d7a2f3e18dc749f505ee9d0456d863eb6424"
"tag": "v3.4.3",
"commit": "3e92f068aa901030014f3b0f27fcd3ed6ab0c535"
},
"_source": "https://github.com/i18next/i18next.git",
"_target": ">=2.4.0",

@ -1,3 +1,9 @@
### 3.4.3
- Fix Interpolator formatter exception error propagation due to not reset RegExp indices [#820](https://github.com/i18next/i18next/issues/820)
### 3.4.2
- assert dir function does not crash if no language available
### 3.4.1
- fix issue with format containing formatSeparator for interpolation formatting

@ -8,14 +8,8 @@
i18next is a very popular internationalization framework for browser or any other javascript environment (eg. node.js).
--------------
**News**
Having done a big rewrite of i18next in spring we are proud to announce the next big step to get your webproject translated with less effort. We just released [locize](locize.com) a translation management system built around the i18next ecosystem.
With using locize you directly support the future of i18next.
![ecosystem](http://i18next.com/img/frameworks.png)
--------------
i18next provides:
@ -39,3 +33,12 @@ For more information visit the website:
Our focus is providing the core to building a booming ecosystem. Independent of the building blocks you choose, be it react, angular or even good old jquery proper translation capabilities are just [one step away](http://i18next.com/docs/ecosystem/#frameworks).
--------------
**locize.com**
Having done a big rewrite of i18next in spring we are proud to announce the next big step to get your webproject translated with less effort. We just released [locize](http://locize.com/) a translation management system built around the i18next ecosystem.
With using locize you directly support the future of i18next.
--------------

@ -1199,6 +1199,15 @@
this.nestingPrefix = iOpts.nestingPrefix ? regexEscape(iOpts.nestingPrefix) : iOpts.nestingPrefixEscaped || regexEscape('$t(');
this.nestingSuffix = iOpts.nestingSuffix ? regexEscape(iOpts.nestingSuffix) : iOpts.nestingSuffixEscaped || regexEscape(')');
// the regexp
this.resetRegExp();
};
Interpolator.prototype.reset = function reset() {
if (this.options) this.init(this.options);
};
Interpolator.prototype.resetRegExp = function resetRegExp() {
// the regexp
var regexpStr = this.prefix + '(.+?)' + this.suffix;
this.regexp = new RegExp(regexpStr, 'g');
@ -1210,10 +1219,6 @@
this.nestingRegexp = new RegExp(nestingRegexpStr, 'g');
};
Interpolator.prototype.reset = function reset() {
if (this.options) this.init(this.options);
};
Interpolator.prototype.interpolate = function interpolate(str, data, lng) {
var _this = this;
@ -1234,6 +1239,8 @@
return _this.format(getPath(data, k), f, lng);
};
this.resetRegExp();
// unescape if has unescapePrefix/Suffix
while (match = this.regexpUnescape.exec(str)) {
var _value = handleFormat(match[1].trim());
@ -2013,6 +2020,7 @@
I18n.prototype.dir = function dir(lng) {
if (!lng) lng = this.language;
if (!lng) return 'rtl';
var rtlLngs = ['ar', 'shu', 'sqr', 'ssh', 'xaa', 'yhd', 'yud', 'aao', 'abh', 'abv', 'acm', 'acq', 'acw', 'acx', 'acy', 'adf', 'ads', 'aeb', 'aec', 'afb', 'ajp', 'apc', 'apd', 'arb', 'arq', 'ars', 'ary', 'arz', 'auz', 'avl', 'ayh', 'ayl', 'ayn', 'ayp', 'bbz', 'pga', 'he', 'iw', 'ps', 'pbt', 'pbu', 'pst', 'prp', 'prd', 'ur', 'ydd', 'yds', 'yih', 'ji', 'yi', 'hbo', 'men', 'xmn', 'fa', 'jpr', 'peo', 'pes', 'prs', 'dv', 'sam'];

File diff suppressed because one or more lines are too long

@ -40,7 +40,7 @@
"tag": "v0.5.4",
"commit": "eef318b0892b5ecec2c95a9c2f7f06c420978cbe"
},
"_source": "git://github.com/davidjbradshaw/image-map-resizer.git",
"_source": "https://github.com/davidjbradshaw/image-map-resizer.git",
"_target": "0.5.*",
"_originalSource": "image-map-resizer"
}

@ -17,7 +17,7 @@
"tag": "v1.4.3",
"commit": "5293dacee881e78b25bd4f699161fca81dff5205"
},
"_source": "git://github.com/rmm5t/jquery-timeago.git",
"_source": "https://github.com/rmm5t/jquery-timeago.git",
"_target": "1.4.*",
"_originalSource": "jquery-timeago"
}

@ -15,7 +15,7 @@
"tag": "1.11.4",
"commit": "c34f8dbf3ba57b3784b93f26119f436c0e8288e1"
},
"_source": "git://github.com/components/jqueryui.git",
"_source": "https://github.com/components/jqueryui.git",
"_target": "1.11.*",
"_originalSource": "jquery-ui"
}

@ -21,7 +21,7 @@
"tag": "0.2.10",
"commit": "058c143d6623f8d39cd45becc1205b9aee325246"
},
"_source": "git://github.com/gromo/jquery.scrollbar.git",
"_source": "https://github.com/gromo/jquery.scrollbar.git",
"_target": "0.2.*",
"_originalSource": "jquery.scrollbar"
}

@ -17,7 +17,7 @@
"tag": "v1.5.5",
"commit": "8498e17dc6c4b5aa21f3a2bbe8c20f3a461c3211"
},
"_source": "git://github.com/trentrichardson/jQuery-Timepicker-Addon.git",
"_source": "https://github.com/trentrichardson/jQuery-Timepicker-Addon.git",
"_target": "1.5.*",
"_originalSource": "jqueryui-timepicker-addon"
}

@ -23,12 +23,12 @@
"./build/mediaelement-and-player.js",
"./build/mediaelementplayer.css"
],
"version": "2.22.1",
"_release": "2.22.1",
"version": "2.23.2",
"_release": "2.23.2",
"_resolution": {
"type": "version",
"tag": "2.22.1",
"commit": "add004709742e81e578022ff6adafd372d25e107"
"tag": "2.23.2",
"commit": "b427851d5ff9fc43eda0e58e02e821ec161e3e7a"
},
"_source": "https://github.com/johndyer/mediaelement.git",
"_target": "2.*",

@ -1,4 +1,4 @@
# `<video>` and `<audio>` made easy.
# `MediaElement.js`: `<video>` and `<audio>` made easy.
One file. Any browser. Same UI.
@ -9,112 +9,62 @@ One file. Any browser. Same UI.
* Thanks: my employer, [Dallas Theological Seminary](http://www.dts.edu/)
* Contributors: [all contributors](https://github.com/johndyer/mediaelement/graphs/contributors)
# Table of Contents
## Installation and Usage
* [Introduction](#intro)
* [Browser and Device support](#browser-support)
* [Installation and Usage](#installation)
* [API and Configuration](#api)
* [Guidelines for Contributors](#guidelines)
* [Change Log](#changelog)
* [TODO list](#todo)
<a id="intro"></a>
## Introduction
_MediaElementPlayer: HTML5 `<video>` and `<audio>` player_
A complete HTML/CSS audio/video player built on top `MediaElement.js` and `jQuery`. Many great HTML5 players have a completely separate Flash UI in fallback mode, but MediaElementPlayer.js uses the same HTML/CSS for all players.
## Change Log
`MediaElement.js` is a set of custom Flash and Silverlight plugins that mimic the HTML5 MediaElement API for browsers that don't support HTML5 or don't support the media codecs you're using.
Instead of using Flash as a _fallback_, Flash is used to make the browser seem HTML5 compliant and enable codecs like H.264 (via Flash) and even WMV (via Silverlight) on all browsers.
Changes available at [Change Log](changelog.md)
<a id="browser-support"></a>
## Browser and Device support
### 1. Add Script and Stylesheet
```html
<script src="jquery.js"></script>
<script src="mediaelement-and-player.min.js"></script>
<link rel="stylesheet" href="mediaelementplayer.css" />
```
### 2. Add `<video>` or `<audio>` tags
If your users have JavaScript and/or Flash, the easiest route for all browsers and mobile devices is to use a single MP4 or MP3 file.
```html
<video src="myvideo.mp4" width="320" height="240"></video>
```
```html
<audio src="myaudio.mp3"></audio>
```
#### Optional: multiple codecs
This includes multiple codecs for various browsers (H.264 for IE9+, Safari, and Chrome, WebM for Firefox 4 and Opera, Ogg for Firefox 3).
```html
<video width="320" height="240" poster="poster.jpg" controls="controls" preload="none">
<source type="video/mp4" src="myvideo.mp4" />
<source type="video/webm" src="myvideo.webm" />
<source type="video/ogg" src="myvideo.ogv" />
</video>
```
#### Optional: Browsers with JavaScript disabled
In very rare cases, you might have a non-HTML5 browser with Flash turned on and JavaScript turned off. In that specific case, you can also include the Flash `<object>` code.
```html
<video width="320" height="240" poster="poster.jpg" controls="controls" preload="none">
<source type="video/mp4" src="myvideo.mp4" />
<source type="video/webm" src="myvideo.webm" />
<source type="video/ogg" src="myvideo.ogv" />
<object width="320" height="240" type="application/x-shockwave-flash" data="flashmediaelement.swf">
<param name="movie" value="flashmediaelement.swf" />
<param name="flashvars" value="controls=true&amp;poster=myvideo.jpg&amp;file=myvideo.mp4" />
<img src="myvideo.jpg" width="320" height="240" title="No video playback capabilities" />
</object>
</video>
```
### 3. Startup
#### Automatic start
You can avoid running any startup scripts by added `class="mejs-player"` to the `<video>` or `<audio>` tag. Options can be added using the `data-mejsoptions` attribute
```html
<video src="myvideo.mp4" width="320" height="240"
class="mejs-player"
data-mejsoptions='{"alwaysShowControls": true}'></video>
```
#### Normal JavaScript
```html
<script>
var player = new MediaElementPlayer('#player', {success: function(mediaElement, originalNode) {
// do things
}});
</script>
```
#### jQuery plugin
```html
<script>
$('video').mediaelementplayer({success: function(mediaElement, originalNode) {
// do things
}});
</script>
```
## How it Works:
_MediaElement.js: HTML5 `<video>` and `<audio>` shim_
Format | Support
------ | -------
**mp4** | Please visit http://caniuse.com/#feat=mpeg4 for comprehensive information
**webm** | Please visit http://caniuse.com/#feat=webm for comprehensive information
**mp3** | Please visit http://caniuse.com/#feat=mp3 for comprehensive information
**m3u8** | Safari and iOS (native); all browsers that support **Flash** (version 10 or later)
**rtmp/flv** | All browsers that support **Flash** (version 10 or later)
**wmv/wma** | All browsers that support **Silverlight**
**YouTube** | All browsers since it uses `iframe` tag
`MediaElement.js` is a set of custom Flash and Silverlight plugins that mimic the HTML5 MediaElement API for browsers that don't support HTML5 or don't support the media codecs you're using.
Instead of using Flash as a _fallback_, Flash is used to make the browser seem HTML5 compliant and enable codecs like H.264 (via Flash) and even WMV (via Silverlight) on all browsers.
```html
<script src="mediaelement.js"></script>
<video src="myvideo.mp4" width="320" height="240"></video>
<a id="installation"></a>
## Installation and Usage
The full documentation on how to install `MediaElement.js` is available at [Installation](installation.md).
A brief guide on how to create and use instances of `MediaElement` available at [Usage](usage.md).
<a id="api"></a>
## API and Configuration
`MediaElement.js` has many options that you can take advantage from. Visit [API and Configuration](api.md) for more details.
<script>
var v = document.getElementsByTagName("video")[0];
new MediaElement(v, {success: function(media) {
media.play();
}});
</script>
```
You can use this as a standalone library if you wish, or just stick with the full MediaElementPlayer.
<a id="guidelines"></a>
## Guidelines for Contributors
## Building MediaElement.js
If you want to contribute to improve this package, please read [Guidelines](guidelines.md).
When developing MediaElement, make changes to the files in the `/src/` directory (not `/build/`) and test the changes with `/test/test.html`.
<a id="changelog"></a>
## Change Log
Changes available at [Change Log](changelog.md)
To compile the changes
<a id="todo"></a>
## TODO list
1. Install `node.js` with `npm` https://nodejs.org/
2. At the command prompt type `npm install` which will download all the necessary tools
3. Type `grunt` to build MediaElement.js
4. To compile the Flash swf, you'll need to install Flex 4.6. See instructions in Gruntfile.js for details.
New features and pending bugs can be found at [TODO list](TODO.md).

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Czech translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.cs === 'undefined') {
exports.cs = {
'mejs.audio-player' : "Přehrávač hudby",
'mejs.captions-subtitles' : "Titulky",
'mejs.close' : "Zavřít",
'mejs.download-file' : "Stáhnout soubor",
'mejs.download-video' : "Stáhnout video",
'mejs.fullscreen' : "Celá obrazovka",
'mejs.fullscreen-off' : "Vypnout režim celá obrazovka",
'mejs.fullscreen-on' : "Na celou obrazovku",
'mejs.mute' : "Vypnout zvuk",
'mejs.mute-toggle' : "Vypnout/zapnout zvuk",
'mejs.none' : "Žádný",
'mejs.pause' : "Pozastavit",
'mejs.play' : "Přehrát",
'mejs.time-help-text' : "Použijte tlačítka se šipkami doleva / doprava pro posun o jednu vteřinu, tlačítka se šipkami nahoru / dolů pro posun o deset vteřin.",
'mejs.time-skip-back' : "Zpět o %1 vteřin",
'mejs.time-slider' : "Posuvný běžec nastavení času",
'mejs.unmute' : "Zapnout zvuk",
'mejs.video-player' : "Přehrávač videa",
'mejs.volume-help-text' : "Použijte tlačítka se šipkami nahoru / dolů pro zesílení nebo zeslabení hlasitosti.",
'mejs.volume-slider' : "Posuvný běžec nastavení hlasitosti"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,70 @@
/*!
* This is a i18n.locale language object.
*
* German
*
* @author
* Sascha "SoftCreatR" Greuel
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.de === 'undefined') {
exports.de = {
// me-shim
'mejs.download-file': 'Datei herunterladen',
// mep-feature-contextmenu
'mejs.fullscreen-off': 'Vollbildmodus beenden',
'mejs.fullscreen-on' : 'Vollbild',
'mejs.download-video' : 'Video herunterladen',
// mep-feature-fullscreen
'mejs.fullscreen' : 'Vollbild',
// mep-feature-jumpforward
'mejs.time-jump-forward': '%1 Sekunde(n) vorspulen',
// mep-feature-playpause
'mejs.play': 'Abspielen',
'mejs.pause': 'Pause',
// mep-feature-postroll
'mejs.close' : 'Schließen',
// mep-feature-progress
'mejs.time-slider': 'Zeitschieberegler',
'mejs.time-help-text': 'Verwende die Pfeiltaste nach links/rechts, um eine Sekunde zu spulen, hoch/runter um zehn Sekunden zu spulen.',
// mep-feature-skipback
'mejs.time-skip-back': '%1 Sekunde(n) zurückspulen',
// mep-feature-tracks
'mejs.captions-subtitles' : 'Überschriften/Untertitel',
'mejs.none' : 'Keine',
// mep-feature-volume
'mejs.mute-toggle' : 'Stummschaltung umschalten',
'mejs.volume-help-text': 'Verwende die Pfeiltaste nach oben/nach unten um die Lautstärke zu erhöhen oder zu verringern.',
'mejs.unmute' : 'Stummschaltung aufheben',
'mejs.mute' : 'Stummschalten',
'mejs.volume-slider': 'Lautstärkeregler',
// mep-player
'mejs.video-player': 'Video-Player',
'mejs.audio-player': 'Audio-Player',
// mep-feature-ads
'mejs.ad-skip': 'Werbung überspringen',
'mejs.ad-skip-info': 'Überspringen in %1 Sekunde(n)',
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,75 @@
/*!
* This is a i18n.locale language object.
*
* English; This can serve as a template for other languages to translate
*
* @author
* TBD
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.en === 'undefined') {
exports.en = {
// me-shim
'mejs.download-file': 'Download File',
// mep-feature-contextmenu
'mejs.fullscreen-off': 'Turn off Fullscreen',
'mejs.fullscreen-on' : 'Go Fullscreen',
// Duplicated from mep-feature-volume
// 'mejs.unmute' : 'Unmute',
// 'mejs.mute' : 'Mute',
'mejs.download-video' : 'Download Video',
// mep-feature-fullscreen
'mejs.fullscreen' : 'Fullscreen',
// mep-feature-jumpforward
'mejs.time-jump-forward': 'Jump forward %1 seconds',
// mep-feature-playpause
'mejs.play': 'Play',
'mejs.pause': 'Pause',
// mep-feature-postroll
'mejs.close' : 'Close',
// mep-feature-progress
'mejs.time-slider': 'Time Slider',
'mejs.time-help-text': 'Use Left/Right Arrow keys to advance one second, Up/Down arrows to advance ten seconds.',
// mep-feature-skipback
'mejs.time-skip-back': 'Skip back %1 seconds',
// mep-feature-tracks
'mejs.captions-subtitles' : 'Captions/Subtitles',
'mejs.none' : 'None',
// mep-feature-volume
'mejs.mute-toggle' : 'Mute Toggle',
'mejs.volume-help-text': 'Use Up/Down Arrow keys to increase or decrease volume.',
'mejs.unmute' : 'Unmute',
'mejs.mute' : 'Mute',
'mejs.volume-slider': 'Volume Slider',
// mep-player
'mejs.video-player': 'Video Player',
'mejs.audio-player': 'Audio Player',
// mep-feature-ads
'mejs.ad-skip': 'Skip ad',
'mejs.ad-skip-info': 'Skip in %1 seconds',
'mejs.source-chooser': 'Source Chooser'
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,49 @@
/*!
* This is a i18n.locale language object.
*
* Spanish; Castilian translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.es === 'undefined') {
exports.es = {
'mejs.ad-skip': "Salta publicidad",
'mejs.ad-skip-info': "Salta en %1 segundos",
'mejs.audio-player' : "Reproductor de audio",
'mejs.captions-subtitles' : "Leyendas/Subtítulos",
'mejs.close' : "Cerrar",
'mejs.download-file' : "Descargar archivo",
'mejs.download-video' : "Descargar vídeo",
'mejs.fullscreen' : "Pantalla completa",
'mejs.fullscreen-off' : "Desconectar pantalla completa",
'mejs.fullscreen-on' : "Ir a pantalla completa",
'mejs.mute' : "Silencio",
'mejs.mute-toggle' : "Alternar silencio",
'mejs.none' : "Ninguno",
'mejs.pause' : "Pausa",
'mejs.play' : "Reproducción",
'mejs.time-help-text' : "Use las flechas Izquierda/Derecha para avanzar un segundo y las flechas Arriba/Abajo para avanzar diez segundos.",
'mejs.time-skip-back' : "Saltar atrás %1 segundos",
'mejs.time-slider' : "Control deslizante de tiempo",
'mejs.unmute' : "Reactivar silencio",
'mejs.video-player' : "Reproductor de video",
'mejs.volume-help-text' : "Use las flechas Arriba/Abajo para subir o bajar el volumen.",
'mejs.volume-slider' : "Control deslizante de volumen",
'mejs.source-chooser': "Selector de media"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,53 @@
/*!
* This is a i18n.locale language object.
*
* French translation by
* Luc Poupard, Twitter: @klohFR
* Jalios, Twitter: @Jalios
*
* @author
* Luc Poupard (Twitter: @klohFR)
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.fr === 'undefined') {
exports.fr = {
'mejs.ad-skip' : "Passer la publicité",
'mejs.ad-skip-info' : "Passer la publicité dans %1 secondes",
'mejs.audio-player' : "Lecteur Audio",
'mejs.captions-subtitles' : "Sous-titres",
'mejs.close' : "Fermer",
'mejs.download-file' : "Télécharger le fichier",
'mejs.download-video' : "Télécharger la vidéo",
'mejs.fullscreen' : "Plein écran",
'mejs.fullscreen-off' : "Quitter le mode plein écran",
'mejs.fullscreen-on' : "Afficher en plein écran",
'mejs.mute' : "Désactiver le son",
'mejs.mute-toggle' : "Activer/désactiver le son",
'mejs.none' : "Aucun",
'mejs.pause' : "Pause",
'mejs.play' : "Lecture",
'mejs.time-help-text' : "Utilisez les flèches Gauche/Droite du clavier pour avancer d'une seconde, les flèches Haut/Bas pour avancer de 10 secondes.",
'mejs.time-jump-forward' : "Avancer de %1 secondes",
'mejs.time-skip-back' : "Reculer de %1 secondes",
'mejs.time-slider' : "Curseur temporel",
'mejs.unmute' : "Activer le son",
'mejs.video-player' : "Lecteur Vidéo",
'mejs.volume-help-text' : "Utilisez les flèches Haut/Bas du clavier pour augmenter ou diminuer le volume.",
'mejs.volume-slider' : "Volume",
'mejs.source-chooser': 'Sélecteur de média'
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Hungarian translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.hu === 'undefined') {
exports.hu = {
'mejs.audio-player' : "Audiolejátszó",
'mejs.captions-subtitles' : "Képaláírás/Feliratok",
'mejs.close' : "Bezárás",
'mejs.download-file' : "Fájl letöltése",
'mejs.download-video' : "Videó letöltése",
'mejs.fullscreen' : "Teljes képernyő",
'mejs.fullscreen-off' : "Teljes képernyő kikapcsolása",
'mejs.fullscreen-on' : "Átlépés teljes képernyős módra",
'mejs.mute' : "Némítás",
'mejs.mute-toggle' : "Némítás kapcsolója",
'mejs.none' : "Nincs",
'mejs.pause' : "Szünet",
'mejs.play' : "Lejátszás",
'mejs.time-help-text' : "Használja a Bal/Jobb nyíl gombokat az egy másodperces léptetéshez, a Fel/Le nyíl gombokat a tíz másodperces léptetéshez.",
'mejs.time-skip-back' : "Ugrás vissza %1 másodperccel",
'mejs.time-slider' : "Idő csúszka",
'mejs.unmute' : "Némítás feloldása",
'mejs.video-player' : "Videolejátszó",
'mejs.volume-help-text' : "Használja a Fel/Le nyíl gombokat a hangerő növeléséhez vagy csökkentéséhez.",
'mejs.volume-slider' : "Hangerőcsúszka"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Italian translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.it === 'undefined') {
exports.it = {
'mejs.audio-player' : "Lettore Audio",
'mejs.captions-subtitles' : "Acquisizioni/sottotitoli",
'mejs.close' : "Chiudere",
'mejs.download-file' : "Scaricare il file",
'mejs.download-video' : "Scaricare il video",
'mejs.fullscreen' : "Schermo intero",
'mejs.fullscreen-off' : "Disattivare lo schermo intero",
'mejs.fullscreen-on' : "Attivare lo schermo intero",
'mejs.mute' : "Muto",
'mejs.mute-toggle' : "Toggle muto",
'mejs.none' : "Nessuno",
'mejs.pause' : "Pausa",
'mejs.play' : "Eseguire",
'mejs.time-help-text' : "Utilizzare i tasti Freccia sinistra/Freccia destra per avanzare di un secondo, Freccia Su/Giù per avanzare dieci secondi.",
'mejs.time-skip-back' : "Riavvolgere %1 secondi",
'mejs.time-slider' : "Barra di scorrimento",
'mejs.unmute' : "Disattivare muto",
'mejs.video-player' : "Lettore Video",
'mejs.volume-help-text' : "Utilizzare i tasti Freccia Su/Giù per aumentare o diminuire il volume.",
'mejs.volume-slider' : "Barra del volume"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Japanese translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.ja === 'undefined') {
exports.ja = {
'mejs.audio-player' : "オーディオプレーヤー",
'mejs.captions-subtitles' : "キャプション/字幕",
'mejs.close' : "閉じる",
'mejs.download-file' : "ファイルをダウンロードする",
'mejs.download-video' : "動画をダウンロードする",
'mejs.fullscreen' : "全画面",
'mejs.fullscreen-off' : "全画面をオフにする",
'mejs.fullscreen-on' : "全画面にする",
'mejs.mute' : "ミュート",
'mejs.mute-toggle' : "ミュートトグル",
'mejs.none' : "なし",
'mejs.pause' : "一時停止",
'mejs.play' : "再生",
'mejs.time-help-text' : "1秒進めるには左/右矢印をキーを、10秒進めるには上/下矢印を使います。",
'mejs.time-skip-back' : "%1秒スキップバックする",
'mejs.time-slider' : "タイムスライダー",
'mejs.unmute' : "ミュートを解除",
'mejs.video-player' : "ビデオプレーヤー",
'mejs.volume-help-text' : "音量を上げたり下げたりするには、上/下矢印を使います。",
'mejs.volume-slider' : "音量スライダー"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Korean translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.ko === 'undefined') {
exports.ko = {
'mejs.audio-player' : "오디오 플레이어",
'mejs.captions-subtitles' : "캡션/자막",
'mejs.close' : "종료",
'mejs.download-file' : "파일 다운로드",
'mejs.download-video' : "비디오 다운로드",
'mejs.fullscreen' : "전체화면",
'mejs.fullscreen-off' : "전체화면 해제",
'mejs.fullscreen-on' : "전체화면 가기",
'mejs.mute' : "말 없는",
'mejs.mute-toggle' : "음소거 전환",
'mejs.none' : "없음",
'mejs.pause' : "정지",
'mejs.play' : "작동",
'mejs.time-help-text' : "1초 전진하려면 좌/우측 화살표를 사용하시고 10초 전진하려면 위/아래 화살표를 사용하세요.",
'mejs.time-skip-back' : "1초 % 를 뒤로 건너뛰세요",
'mejs.time-slider' : "시간 슬라이더",
'mejs.unmute' : "음소거 해제",
'mejs.video-player' : "비디오 플레이어",
'mejs.volume-help-text' : "볼륨을 높이거나 낮추려면 위/아래 화살표를 이용하세요.",
'mejs.volume-slider' : "볼륨 슬라이더"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Polish translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.pl === 'undefined') {
exports.pl = {
'mejs.audio-player' : "Odtwarzacz audio",
'mejs.captions-subtitles' : "Podpisy/napisy",
'mejs.close' : "Zamknij",
'mejs.download-file' : "Pobierz plik",
'mejs.download-video' : "Pobierz wideo",
'mejs.fullscreen' : "Pełny ekran",
'mejs.fullscreen-off' : "Wyłącz pełny ekran",
'mejs.fullscreen-on' : "Przejdź na pełny ekran",
'mejs.mute' : "Wycisz",
'mejs.mute-toggle' : "Przełączanie wyciszania",
'mejs.none' : "Brak",
'mejs.pause' : "Wstrzymaj",
'mejs.play' : "Odtwarzaj",
'mejs.time-help-text' : "Strzałki w lewo/w prawo powodują przewijanie o sekundę, strzałki w górę/w dół o dziesięć sekund.",
'mejs.time-skip-back' : "Cofnij o %1 sek.",
'mejs.time-slider' : "Suwak czasu",
'mejs.unmute' : "Wyłącz wyciszenie",
'mejs.video-player' : "Odtwarzacz wideo",
'mejs.volume-help-text' : "Aby zwiększyć lub zmniejszyć głośność, użyj strzałek w górę/w dół.",
'mejs.volume-slider' : "Suwak głośności"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,37 @@
/*!
* This is a i18n.locale language object.
*
* Brazilian Portuguese translation by Armando Meziat
*
* @author
* Armando Meziat
* - Twitter: @odnamrataizem
* - GitHub: https://github.com/odnamrataizem/
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports['pt-BR'] === 'undefined') {
exports.pt = {
'mejs.none' : "Sem legendas",
'mejs.unmute' : "Tirar silêncio",
'mejs.fullscreen' : "Tela inteira",
'mejs.download-file' : "Baixar arquivo",
'mejs.mute-toggle' : "Alternar silêncio",
'mejs.captions-subtitles' : "Legendas",
'mejs.download-video' : "Baixar vídeo",
'mejs.mute' : "Silenciar",
'mejs.fullscreen-off' : "Sair da tela inteira",
'mejs.fullscreen-on' : "Ir para tela inteira",
'mejs.close' : "Fechar"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Portuguese translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.pt === 'undefined') {
exports.pt = {
'mejs.audio-player' : "Leitor de áudio",
'mejs.captions-subtitles' : "Legendas",
'mejs.close' : "Fechar",
'mejs.download-file' : "Descarregar o ficheiro",
'mejs.download-video' : "Descarregar o vídeo",
'mejs.fullscreen' : "Ecrã completo",
'mejs.fullscreen-off' : "Desligar ecrã completo",
'mejs.fullscreen-on' : "Ir para ecrã completo",
'mejs.mute' : "Silêncio",
'mejs.mute-toggle' : "Alternar silêncio",
'mejs.none' : "Nenhum",
'mejs.pause' : "Pausa",
'mejs.play' : "Reprodução",
'mejs.time-help-text' : "Use as teclas das setas para a esquerda/direita para avançar um segundo, e as setas para cima/baixo para avançar dez segundos.",
'mejs.time-skip-back' : "Retroceder %1 segundos",
'mejs.time-slider' : "Deslizador do tempo",
'mejs.unmute' : "Voltar ao som",
'mejs.video-player' : "Leitor de vídeo",
'mejs.volume-help-text' : "Use as teclas das setas para cima/baixo para aumentar ou diminuir o volume.",
'mejs.volume-slider' : "Deslizador do volume"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Romanian translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.ro === 'undefined') {
exports.ro = {
'mejs.audio-player' : "Player audio",
'mejs.captions-subtitles' : "Legende/Subtitrări",
'mejs.close' : "Închide",
'mejs.download-file' : "Descarcă fişierul",
'mejs.download-video' : "Descarcă fişierul video",
'mejs.fullscreen' : "Ecran complet",
'mejs.fullscreen-off' : "Opreşte ecranul complet",
'mejs.fullscreen-on' : "Treci la ecran complet",
'mejs.mute' : "Fără sunet",
'mejs.mute-toggle' : "Comutare dezactivare sunet",
'mejs.none' : "Niciunul",
'mejs.pause' : "Pauză",
'mejs.play' : "Redare",
'mejs.time-help-text' : "Utilizează tastele săgeată Stânga/Dreapta pentru a avansa o secundă şi săgeţile Sus/Jos pentru a avansa zece secunde.",
'mejs.time-skip-back' : "Sari înapoi %1 secunde",
'mejs.time-slider' : "Cursor timp",
'mejs.unmute' : "Cu sunet",
'mejs.video-player' : "Player video",
'mejs.volume-help-text' : "Utilizează tastele de săgeată Sus/Jos pentru a creşte/micşora volumul",
'mejs.volume-slider' : "Cursor volum"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Russian translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.ru === 'undefined') {
exports.ru = {
'mejs.audio-player' : "Аудиоплеер",
'mejs.captions-subtitles' : "Титры/Субтитры",
'mejs.close' : "Закрыть",
'mejs.download-file' : "Скачать файл",
'mejs.download-video' : "Скачать видео",
'mejs.fullscreen' : "Широкий экран",
'mejs.fullscreen-off' : "Выключить широкий экран",
'mejs.fullscreen-on' : "Перейти к широкому экрану",
'mejs.mute' : "Отключить звук",
'mejs.mute-toggle' : "Без звука",
'mejs.none' : "Нет",
'mejs.pause' : "Пауза",
'mejs.play' : "Воспроизвести",
'mejs.time-help-text' : "Используйте Левую/Правую клавиши со стрелками, чтобы продвинуться на одну секунду, клавиши со стрелками Вверх/Вниз, чтобы продвинуться на десять секунд.",
'mejs.time-skip-back' : "Пропустить назад %1 секунд",
'mejs.time-slider' : "Слайдер времени",
'mejs.unmute' : "Отменить выключение звука",
'mejs.video-player' : "Видеоплеер",
'mejs.volume-help-text' : "Используйте клавиши со стрелками Вверх/Вниз, чтобы увеличить или уменьшить громкость.",
'mejs.volume-slider' : "Слайдер громкости"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Slovak translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.sk === 'undefined') {
exports.sk = {
'mejs.audio-player' : "Prehrávač zvuku",
'mejs.captions-subtitles' : "Skryté titulky/Titulky",
'mejs.close' : "Zavrieť",
'mejs.download-file' : "Prevziať súbor",
'mejs.download-video' : "Prevziať video",
'mejs.fullscreen' : "Celá obrazovka",
'mejs.fullscreen-off' : "Vypnúť celú obrazovku",
'mejs.fullscreen-on' : "Prejsť na celú obrazovku",
'mejs.mute' : "Stlmiť",
'mejs.mute-toggle' : "Prepínač stlmenia",
'mejs.none' : "Žiadne",
'mejs.pause' : "Pozastaviť",
'mejs.play' : "Prehrať",
'mejs.time-help-text' : "Klávesmi so šípkou doľava/doprava posuniete o jednu sekundu, šípkami nahor/ nadol posuniete o desať sekúnd.",
'mejs.time-skip-back' : "Preskočiť dozadu o %1 s.",
'mejs.time-slider' : "Posúvač času",
'mejs.unmute' : "Zrušiť stlmenie",
'mejs.video-player' : "Prehrávač videa",
'mejs.volume-help-text' : "Klávesmi so šípkou nahor/nadol zvýšite alebo znížite hlasitosť.",
'mejs.volume-slider' : "Posúvač hlasitosti"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Chinese simplified translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports['zh-CN'] === 'undefined') {
exports['zh-CN'] = {
'mejs.audio-player' : "音频播放器",
'mejs.captions-subtitles' : "字幕/标题",
'mejs.close' : "关闭",
'mejs.download-file' : "下载文件",
'mejs.download-video' : "下载视频",
'mejs.fullscreen' : "全屏",
'mejs.fullscreen-off' : "关闭全屏",
'mejs.fullscreen-on' : "转向全屏",
'mejs.mute' : "静音",
'mejs.mute-toggle' : "静音切换",
'mejs.none' : "无",
'mejs.pause' : "暂停",
'mejs.play' : "播放",
'mejs.time-help-text' : "使用作/右箭头快进1秒,使用上/下箭头快进10秒。",
'mejs.time-skip-back' : "后退%1秒",
'mejs.time-slider' : "时间滑动棒",
'mejs.unmute' : "取消静音",
'mejs.video-player' : "视频播放器",
'mejs.volume-help-text' : "使用上/下箭头提高或降低音量。",
'mejs.volume-slider' : "音量选择键"
};
}
}(mejs.i18n.locale.strings));

@ -0,0 +1,46 @@
/*!
* This is a i18n.locale language object.
*
* Chinese traditionnal translation by Jalios, Twitter: @Jalios
*
* @author
* Jalios (Twitter: @Jalios)
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.zh === 'undefined') {
exports.zh = {
'mejs.audio-player' : "音頻播放器",
'mejs.captions-subtitles' : "字幕/標題",
'mejs.close' : "關閉",
'mejs.download-file' : "下載文件",
'mejs.download-video' : "下載視頻",
'mejs.fullscreen' : "全屏",
'mejs.fullscreen-off' : "關閉全屏",
'mejs.fullscreen-on' : "轉向全屏",
'mejs.mute' : "靜音",
'mejs.mute-toggle' : "靜音切換",
'mejs.none' : "沒有",
'mejs.pause' : "暫停",
'mejs.play' : "播放",
'mejs.time-help-text' : "使用左/右箭頭快進1秒,上/下箭頭快進10秒。",
'mejs.time-skip-back' : "跳躍式迴繞%1秒",
'mejs.time-slider' : "時間滑動棒",
'mejs.unmute' : "取消靜音",
'mejs.video-player' : "視頻播放器",
'mejs.volume-help-text' : "使用上/下箭頭提高或降低音量。",
'mejs.volume-slider' : "音量控制鍵"
};
}
}(mejs.i18n.locale.strings));

File diff suppressed because one or more lines are too long

@ -16,7 +16,7 @@
var mejs = mejs || {};
// version number
mejs.version = '2.22.0';
mejs.version = '2.23.2';
// player number (for missing, same id attr)
@ -28,7 +28,7 @@ mejs.plugins = {
{version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
],
flash: [
{version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/rtmp','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/dailymotion', 'video/x-dailymotion', 'application/x-mpegURL']}
{version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/rtmp','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a', 'audio/mp4', 'audio/mpeg', 'video/dailymotion', 'video/x-dailymotion', 'application/x-mpegURL', 'audio/ogg']}
// 'video/youtube', 'video/x-youtube',
// ,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
],
@ -300,7 +300,23 @@ mejs.Utility = {
return url.substr(0, url.indexOf("://")+3);
}
return "//"; // let user agent figure this out
}
},
// taken from underscore
debounce: function(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
};
@ -883,7 +899,7 @@ mejs.PluginMediaElement.prototype = {
if (this.hasAttribute(name)) {
return this.attributes[name];
}
return '';
return null;
},
setAttribute: function(name, value){
this.attributes[name] = value;
@ -944,6 +960,9 @@ mejs.MediaElementDefaults = {
timerRate: 250,
// initial volume for player
startVolume: 0.8,
// custom error message in case media cannot be played; otherwise, Download File
// link will be displayed
customError: "",
success: function () { },
error: function () { }
};
@ -992,7 +1011,7 @@ mejs.HtmlMediaElementShim = {
// test for HTML5 and plugin capabilities
playback = this.determinePlayback(htmlMediaElement, options, mejs.MediaFeatures.supportsMediaTag, isMediaTag, src);
playback.url = (playback.url !== null) ? mejs.Utility.absolutizeUrl(playback.url) : '';
playback.scheme = mejs.Utility.determineScheme(playback.url);
playback.scheme = mejs.Utility.determineScheme(playback.url);
if (playback.method == 'native') {
// second fix for android
@ -1026,7 +1045,7 @@ mejs.HtmlMediaElementShim = {
l,
n,
type,
result = { method: '', url: '', htmlMediaElement: htmlMediaElement, isVideo: (htmlMediaElement.tagName.toLowerCase() != 'audio'), scheme: ''},
result = { method: '', url: '', htmlMediaElement: htmlMediaElement, isVideo: (htmlMediaElement.tagName.toLowerCase() !== 'audio'), scheme: ''},
pluginName,
pluginVersions,
pluginInfo,
@ -1080,16 +1099,16 @@ mejs.HtmlMediaElementShim = {
// STEP 2: Test for playback method
// special case for Android which sadly doesn't implement the canPlayType function (always returns '')
if (mejs.MediaFeatures.isBustedAndroid) {
if (result.isVideo && mejs.MediaFeatures.isBustedAndroid) {
htmlMediaElement.canPlayType = function(type) {
return (type.match(/video\/(mp4|m4v)/gi) !== null) ? 'maybe' : '';
};
}
// special case for Chromium to specify natively supported video codecs (i.e. WebM and Theora)
if (mejs.MediaFeatures.isChromium) {
if (result.isVideo && mejs.MediaFeatures.isChromium) {
htmlMediaElement.canPlayType = function(type) {
return (type.match(/video\/(webm|ogv|ogg)/gi) !== null) ? 'maybe' : '';
return (type.match(/video\/(webm|ogv|ogg)/gi) !== null) ? 'maybe' : '';
};
}
@ -1258,7 +1277,7 @@ mejs.HtmlMediaElementShim = {
errorContent += '<img src="' + poster + '" width="100%" height="100%" alt="" />';
}
errorContent += '<span>' + mejs.i18n.t('Download File') + '</span></a>';
errorContent += '<span>' + mejs.i18n.t('mejs.download-file') + '</span></a>';
}
errorContainer.innerHTML = errorContent;
@ -1282,7 +1301,7 @@ mejs.HtmlMediaElementShim = {
initVars;
// copy tagName from html media element
pluginMediaElement.tagName = htmlMediaElement.tagName
pluginMediaElement.tagName = htmlMediaElement.tagName;
// copy attributes from html media element to plugin media element
for (var i = 0; i < htmlMediaElement.attributes.length; i++) {
@ -1334,10 +1353,21 @@ mejs.HtmlMediaElementShim = {
if (playback.method === 'flash' || playback.method === 'silverlight') {
var canPlayVideo = htmlMediaElement.getAttribute('type') === 'audio/mp4',
childrenSources = htmlMediaElement.getElementsByTagName('source');
if (childrenSources && !canPlayVideo) {
for (var i = 0, total = childrenSources.length; i < total; i++) {
if (childrenSources[i].getAttribute('type') === 'audio/mp4') {
canPlayVideo = true;
}
}
}
// flash/silverlight vars
initVars = [
'id=' + pluginid,
'isvideo=' + ((playback.isVideo) ? "true" : "false"),
'isvideo=' + ((playback.isVideo || canPlayVideo) ? "true" : "false"),
'autoplay=' + ((autoplay) ? "true" : "false"),
'preload=' + preload,
'width=' + width,
@ -1385,7 +1415,7 @@ mejs.HtmlMediaElementShim = {
if (pluginMediaElement.pluginApi != null && pluginMediaElement.success) {
pluginMediaElement.success(pluginMediaElement, htmlMediaElement);
}
}
};
// event call from plugin
window[pluginid + '_event'] = function(eventName, values) {
@ -1504,7 +1534,8 @@ mejs.HtmlMediaElementShim = {
videoId: videoId,
height: height,
width: width,
scheme: playback.scheme
scheme: playback.scheme,
variables: options.youtubeIframeVars
};
// favor iframe version of YouTube
@ -1513,7 +1544,6 @@ mejs.HtmlMediaElementShim = {
} else if (mejs.PluginDetector.hasPluginVersion('flash', [10,0,0]) ) {
mejs.YouTubeApi.createFlash(youtubeSettings, options);
}
break;
// DEMO Code. Does NOT work.
@ -1530,19 +1560,19 @@ mejs.HtmlMediaElementShim = {
player.playVideo = function() {
player.api( 'play' );
}
};
player.stopVideo = function() {
player.api( 'unload' );
}
};
player.pauseVideo = function() {
player.api( 'pause' );
}
};
player.seekTo = function( seconds ) {
player.api( 'seekTo', seconds );
}
};
player.setVolume = function( volume ) {
player.api( 'setVolume', volume );
}
};
player.setMuted = function( muted ) {
if( muted ) {
player.lastVolume = player.api( 'getVolume' );
@ -1551,11 +1581,11 @@ mejs.HtmlMediaElementShim = {
player.api( 'setVolume', player.lastVolume );
delete player.lastVolume;
}
}
};
// parity with YT player
player.getPlayerState = function() {
return playerState;
}
};
function createEvent(player, pluginMediaElement, eventName, e) {
var event = {
@ -1694,21 +1724,22 @@ mejs.YouTubeApi = {
}
},
createIframe: function(settings) {
var
pluginMediaElement = settings.pluginMediaElement,
pluginMediaElement = settings.pluginMediaElement,
defaultVars = {controls:0, wmode:'transparent'},
player = new YT.Player(settings.containerId, {
height: settings.height,
width: settings.width,
videoId: settings.videoId,
playerVars: {controls:0,wmode:'transparent'},
playerVars: $.extend({}, defaultVars, settings.variables),
events: {
'onReady': function() {
'onReady': function(e) {
// wrapper to match
player.setVideoSize = function(width, height) {
player.setSize(width, height);
}
};
// hook up iframe object to MEjs
settings.pluginMediaElement.pluginApi = player;
@ -1716,11 +1747,17 @@ mejs.YouTubeApi = {
// init mejs
pluginMediaElement.success(pluginMediaElement, pluginMediaElement.pluginElement);
mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'canplay');
// create timer
setInterval(function() {
mejs.YouTubeApi.createEvent(player, pluginMediaElement, 'timeupdate');
}, 250);
}, 250);
if (typeof pluginMediaElement.attributes.autoplay !== 'undefined') {
player.playVideo();
}
},
'onStateChange': function(e) {
@ -1844,7 +1881,7 @@ mejs.YouTubeApi = {
window[callbackName] = function(e) {
mejs.YouTubeApi.handleStateChange(e, player, pluginMediaElement);
}
};
player.addEventListener('onStateChange', callbackName);
@ -1908,9 +1945,6 @@ window.MediaElement = mejs.MediaElement;
* This file does not contain translations, you have to add them manually.
* The schema is always the same: me-i18n-locale-[IETF-language-tag].js
*
* Examples are provided both for german and chinese translation.
*
*
* What is the concept beyond i18n?
* http://en.wikipedia.org/wiki/Internationalization_and_localization
*
@ -1944,6 +1978,7 @@ window.MediaElement = mejs.MediaElement;
"use strict";
var i18n = {
"default": 'en',
"locale": {
// Ensure previous values aren't overwritten.
"language" : (exports.i18n && exports.i18n.locale.language) || '',
@ -2001,8 +2036,8 @@ window.MediaElement = mejs.MediaElement;
* Translate strings to the page language or a given language.
*
*
* @param str
* A string containing the English string to translate.
* @param uid
* A string containing a unique id of the translated text to retrieve.
*
* @param options
* - 'context' (defaults to the default context): The context the source string
@ -2011,13 +2046,22 @@ window.MediaElement = mejs.MediaElement;
* @return
* The translated string, escaped via i18n.methods.checkPlain()
*/
i18n.methods.t = function (str, options) {
i18n.methods.t = function (uid, options) {
var str;
// Fetch the localized version of the string.
if (i18n.locale.strings && i18n.locale.strings[options.context] && i18n.locale.strings[options.context][str]) {
str = i18n.locale.strings[options.context][str];
if (i18n.locale.strings && i18n.locale.strings[options.context]) {
str = i18n.locale.strings[options.context][uid];
}
// Fallback to default language if requested uid is not translated
if (!str && i18n.locale.strings && i18n.locale.strings[i18n["default"]]) {
str = i18n.locale.strings[i18n["default"]][uid];
}
// As a last resort, use the requested uid, to mimic original behavior of i18n utils (in which uid was the english text)
str = str || uid;
return i18n.methods.checkPlain(str);
};
@ -2064,3 +2108,79 @@ window.MediaElement = mejs.MediaElement;
}
}(mejs.i18n.locale.strings));
/*!
* This is a i18n.locale language object.
*
* English; This can serve as a template for other languages to translate
*
* @author
* TBD
*
* @see
* me-i18n.js
*
* @params
* - exports - CommonJS, window ..
*/
;(function(exports, undefined) {
"use strict";
if (typeof exports.en === 'undefined') {
exports.en = {
// me-shim
'mejs.download-file': 'Download File',
// mep-feature-contextmenu
'mejs.fullscreen-off': 'Turn off Fullscreen',
'mejs.fullscreen-on' : 'Go Fullscreen',
// Duplicated from mep-feature-volume
// 'mejs.unmute' : 'Unmute',
// 'mejs.mute' : 'Mute',
'mejs.download-video' : 'Download Video',
// mep-feature-fullscreen
'mejs.fullscreen' : 'Fullscreen',
// mep-feature-jumpforward
'mejs.time-jump-forward': 'Jump forward %1 seconds',
// mep-feature-playpause
'mejs.play': 'Play',
'mejs.pause': 'Pause',
// mep-feature-postroll
'mejs.close' : 'Close',
// mep-feature-progress
'mejs.time-slider': 'Time Slider',
'mejs.time-help-text': 'Use Left/Right Arrow keys to advance one second, Up/Down arrows to advance ten seconds.',
// mep-feature-skipback
'mejs.time-skip-back': 'Skip back %1 seconds',
// mep-feature-tracks
'mejs.captions-subtitles' : 'Captions/Subtitles',
'mejs.none' : 'None',
// mep-feature-volume
'mejs.mute-toggle' : 'Mute Toggle',
'mejs.volume-help-text': 'Use Up/Down Arrow keys to increase or decrease volume.',
'mejs.unmute' : 'Unmute',
'mejs.mute' : 'Mute',
'mejs.volume-slider': 'Volume Slider',
// mep-player
'mejs.video-player': 'Video Player',
'mejs.audio-player': 'Audio Player',
// mep-feature-ads
'mejs.ad-skip': 'Skip ad',
'mejs.ad-skip-info': 'Skip in %1 seconds',
'mejs.source-chooser': 'Source Chooser'
};
}
}(mejs.i18n.locale.strings));

File diff suppressed because one or more lines are too long

@ -723,10 +723,12 @@
}
.mejs-captions-text {
padding: 3px 5px;
padding: 0;
background: url("background.png");
background: rgba(20, 20, 20, 0.5);
white-space: pre-wrap;
-webkit-box-shadow: 5px 0 0 rgba(20, 20, 20, 0.5), -5px 0 0 rgba(20, 20, 20, 0.5);
box-shadow: 5px 0 0 rgba(20, 20, 20, 0.5), -5px 0 0 rgba(20, 20, 20, 0.5);
}
/* End: Track (Captions and Chapters) */
@ -815,7 +817,6 @@
}
.mejs-controls .mejs-sourcechooser-button .mejs-sourcechooser-selector {
visibility: hidden;
position: absolute;
bottom: 26px;
right: -10px;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,9 +1,49 @@
### Version History
*2.23.2 (2016/10/01)*
* Added fix for time rail width described on #1356 @ron666
* Integrated markers feature (https://github.com/johndyer/mediaelement/pull/1814) @hkasera
* Added French translation for Source Chooser feature (https://github.com/johndyer/mediaelement/pull/1850) @OlivierJaquemet
* Fixed German translation file (https://github.com/johndyer/mediaelement/pull/1852) @SoftCreatR
* Add complete list of supported language in translation demo file (https://github.com/johndyer/mediaelement/pull/1853) @OlivierJaquemet
* Fix for controls when no features are set in the configuration (https://github.com/johndyer/mediaelement/pull/1797) @ron666
* Fixed issues with translatable elements in several features files that were not being translated properly and fixed typo in Spanish translation @ron666
* Fixed YouTube loop issue according to @michaelbucklin recommendation @ron666
* Fixed compilation error when using YUICompressor on i18n file (https://github.com/johndyer/mediaelement/pull/1861) @OlivierJaquemet
*2.23.1 (2016/09/26)*
* Fix documentation in regards of control icons with CSS in different path (https://github.com/johndyer/mediaelement/pull/1837) @jangrewe
* Added a new element to customize YouTube iframe, to solve #1840 (https://github.com/johndyer/mediaelement/pull/1842) @ron666
* Fix issues with Chromium not playing audio files properly (https://github.com/johndyer/mediaelement/pull/1843) @ron666
* Fix for issue related to space bar and Firefox triggering click event, causing issues in Accessibility (https://github.com/johndyer/mediaelement/pull/1848) @ron666
* Update I18N to use unique id instead of strings (https://github.com/johndyer/mediaelement/pull/1845) @OlivierJaquemet
* Make the sourcechooser feature keyboard-friendly for Accessibility purposes (https://github.com/johndyer/mediaelement/pull/1841) @tennety
* Integration of `grunt` task to set translation files inside `/build/` folder (https://github.com/johndyer/mediaelement/pull/1834) @ron666
*2.23.0 (2016/09/06)*
* Changed way to detect fullscreen method by using _onloadstart_ event (https://github.com/johndyer/mediaelement/pull/1815) @ale-grosselle
* Preserve volume muted when resizing player (https://github.com/johndyer/mediaelement/pull/1813) @ron666
* Allow double lines of captions, added missing _captions_ type in tracks workflow and minor typo fix (https://github.com/johndyer/mediaelement/pull/1800) @ron666
* Touch devices controls fix for #1820 (https://github.com/johndyer/mediaelement/issues/603) @ron666
* Show controls when video is paused or ended (https://github.com/johndyer/mediaelement/pull/1786) @ron666
* Progress bar variables set properly to fix #1600 (https://github.com/johndyer/mediaelement/pull/1824) @ron666
* Configurable controls visibility time (https://github.com/johndyer/mediaelement/pull/1787) @ron666
* Added delay when hovering out of control button (https://github.com/johndyer/mediaelement/pull/1615) @schrolli
* Added new Grunt task to compile all html5 elements including console messages (https://github.com/johndyer/mediaelement/pull/1614) @schrolli
* Added call to format time properly when metadata has been loaded (https://github.com/johndyer/mediaelement/pull/1826) @ron666
* Added time tracker tooltip configuration to enable/disable it (#1692) (https://github.com/johndyer/mediaelement/pull/1830) @ron666
* Set source properly on YouTube videos properly per @dazweeja's comments (https://github.com/johndyer/mediaelement/pull/1829) @ron666
* Documentation improvements and addition of TODO list (https://github.com/johndyer/mediaelement/pull/1805) @ron666
* Added missing error message configuration in documentation and in player settings
*2.22.1 (2016/08/18)*
* Fix wrong parameter sent to defaultSeekForwardInterval and defaultSeekBackwardInterval options (https://github.com/johndyer/mediaelement/pull/1784) @marjune163
* Fullscreen in Safari Mac must show player skin (https://github.com/johndyer/mediaelement/pull/1794) @ale-grosselle
* Add missing string to the English locale template https://github.com/johndyer/mediaelement/pull/1782 @ocean90
* Fix for aspect ratio when playing Hls Flash video if m3u8 does not have a resolution indicated (#1790) (https://github.com/johndyer/mediaelement/pull/1791) @ale-grosselle
* Only focus the play button when the control bar is not hidden (https://github.com/johndyer/mediaelement/pull/1798) @schrolli
* Avoid hiding audio controls when tabbing (#1668) (https://github.com/johndyer/mediaelement/pull/1804) @ron666
@ -19,7 +59,7 @@
* Update Flash HLS to accept audio (https://github.com/johndyer/mediaelement/pull/1763) @ale-grosselle
* Updated Korean translation (#1743) @Jinkwon
* Improve video ID parsing for YouTube URLs (https://github.com/johndyer/mediaelement/pull/1774) @ocean90
* Removed extrainous call to removePlugin @johndyer
* Removed extraneous call to removePlugin @johndyer
*2.21.2 (2016/05/08)*
@ -860,13 +900,3 @@ Fixes and updates
*1.0.0 (2010/08/09)*
* initial release
*Someday/Maybe features*
* deeper WebVTT support (alignment, color, etc.) - include captionator
* Full support for Ender.js, including mediaelement-and-player-standalone which includes ender.
* thin line when controls are off
* system-wide events
* Ogg/Theora playback
* Better alignment with native MediaElement (using shimichanga.com techniques)

@ -8,7 +8,7 @@
"tag": "v2.8.3",
"commit": "d6bb30c0f12ebb3ddd01e90b0bf435e1c34e6f11"
},
"_source": "git://github.com/Modernizr/Modernizr.git",
"_source": "https://github.com/Modernizr/Modernizr.git",
"_target": "2.8.*",
"_originalSource": "modernizr"
}

@ -24,7 +24,7 @@
"tag": "2.9.0",
"commit": "8b35bc74c0e88c1a8c58ccb90117a9edc9f6a479"
},
"_source": "git://github.com/moment/moment.git",
"_source": "https://github.com/moment/moment.git",
"_target": "~2.9.0",
"_originalSource": "moment"
}

@ -1,6 +1,6 @@
{
"name": "pwstrength-bootstrap",
"version": "2.0.2",
"version": "2.0.3",
"homepage": "https://github.com/ablanco/jquery.pwstrength.bootstrap",
"authors": [
"Alejandro Blanco <alejandro.b.e@gmail.com>"
@ -35,11 +35,11 @@
"Gruntfile.js",
"package.json"
],
"_release": "2.0.2",
"_release": "2.0.3",
"_resolution": {
"type": "version",
"tag": "2.0.2",
"commit": "cafffc55da15c4e9c2c7ee32fa39231c460ef718"
"tag": "2.0.3",
"commit": "134e8360142c8be075011424ee3e22a9917ce99c"
},
"_source": "https://github.com/ablanco/jquery.pwstrength.bootstrap.git",
"_target": "*",

@ -1,6 +1,6 @@
{
"name": "pwstrength-bootstrap",
"version": "2.0.2",
"version": "2.0.3",
"homepage": "https://github.com/ablanco/jquery.pwstrength.bootstrap",
"authors": [
"Alejandro Blanco <alejandro.b.e@gmail.com>"

@ -1,6 +1,6 @@
/*!
* jQuery Password Strength plugin for Twitter Bootstrap
* Version: 2.0.2
* Version: 2.0.3
*
* Copyright (c) 2008-2013 Tane Piper
* Copyright (c) 2013 Alejandro Blanco

File diff suppressed because one or more lines are too long

@ -0,0 +1,15 @@
{
"wordLength": "Das Passwort ist zu kurz",
"wordNotEmail": "Das Passwort darf die E-Mail Adresse nicht enthalten",
"wordSimilarToUsername": "Das Passwort darf den Benutzernamen nicht enthalten",
"wordTwoCharacterClasses": "Bitte Buchstaben und Ziffern verwenden",
"wordRepetitions": "Zu viele Wiederholungen",
"wordSequences": "Das Passwort enthält Buchstabensequenzen",
"errorList": "Fehler:",
"veryWeak": "Sehr schwach",
"weak": "Schwach",
"normal": "Normal",
"medium": "Mittel",
"strong": "Stark",
"veryStrong": "Sehr stark"
}

@ -0,0 +1,15 @@
{
"wordLength": "Hasło jest zbyt krótkie",
"wordNotEmail": "Hasło nie może być Twoim emailem",
"wordSimilarToUsername": "Hasło nie może zawierać nazwy użytkownika",
"wordTwoCharacterClasses": "Użyj innych klas znaków",
"wordRepetitions": "Zbyt wiele powtórzeń",
"wordSequences": "Hasło zawiera sekwencje",
"errorList": "Błędy:",
"veryWeak": "Bardzo słabe",
"weak": "Słabe",
"normal": "Normalne",
"medium": "Średnie",
"strong": "Silne",
"veryStrong": "Bardzo silne"
}

@ -0,0 +1,15 @@
{
"wordLength": "Girdiğiniz şifre çok Kısa",
"wordNotEmail": "E-mail adresinizi şifreniz içerisinde kullanmayınız",
"wordSimilarToUsername": "Kullanıcı Adınızı şifreniz içerisinde kullanmayınız",
"wordTwoCharacterClasses": "Başka karakter sınıfı kullanınız",
"wordRepetitions": "Çok fazla tekrar var",
"wordSequences": "Şifreniz Dizi içermektedir",
"errorList": "Hatalar:",
"veryWeak": "Çok Zayıf",
"weak": "Zayıf",
"normal": "Normal",
"medium": "Orta",
"strong": "Güçlü",
"veryStrong": "Çok Güçlü"
}

@ -8,7 +8,7 @@
"tag": "v1.15.4",
"commit": "6f84fbcd42bd6ab1af8134ef0c495e8a6c3175f7"
},
"_source": "git://github.com/HenrikJoreteg/SimpleWebRTC.git",
"_source": "https://github.com/HenrikJoreteg/SimpleWebRTC.git",
"_target": "1.15.*",
"_originalSource": "simpleWebRTC"
}

@ -1,6 +1,6 @@
{
"name": "webcamjs",
"version": "1.0.15",
"version": "1.0.16",
"homepage": "https://github.com/jhuckaby/webcamjs",
"authors": [
"Joseph Huckaby <jhuckaby@gmail.com>"
@ -21,11 +21,11 @@
"demos",
"flash"
],
"_release": "1.0.15",
"_release": "1.0.16",
"_resolution": {
"type": "version",
"tag": "v1.0.15",
"commit": "15b3fedfc1bd5e6cb8b0ed4460ee0f56a8adbfa8"
"tag": "v1.0.16",
"commit": "d8b625b82df47f7ae70093cd375bf711dea3f1e4"
},
"_source": "https://github.com/jhuckaby/webcamjs.git",
"_target": "1.0.*",

@ -1,6 +1,6 @@
{
"name": "webcamjs",
"version": "1.0.15",
"version": "1.0.16",
"homepage": "https://github.com/jhuckaby/webcamjs",
"authors": [
"Joseph Huckaby <jhuckaby@gmail.com>"

@ -1,6 +1,6 @@
{
"name": "webcamjs",
"version": "1.0.15",
"version": "1.0.16",
"description": "HTML5 Webcam Image Capture Library with Flash Fallback",
"author": "Joseph Huckaby <jhuckaby@gmail.com>",
"homepage": "https://github.com/jhuckaby/webcamjs",

@ -1,4 +1,4 @@
// WebcamJS v1.0.15
// WebcamJS v1.0.16
// Webcam library for capturing JPEG/PNG images in JavaScript
// Attempts getUserMedia, falls back to Flash
// Author: Joseph Huckaby: http://github.com/jhuckaby
@ -34,7 +34,7 @@ FlashError.prototype = new IntermediateInheritor();
WebcamError.prototype = new IntermediateInheritor();
var Webcam = {
version: '1.0.15',
version: '1.0.16',
// globals
protocol: location.protocol.match(/https/i) ? 'https' : 'http',
@ -258,7 +258,8 @@ var Webcam = {
if (this.userMedia !== true) {
// call for turn off camera in flash
this.getMovie()._releaseCamera();
var movie = this.getMovie();
if (movie && movie._releaseCamera) movie._releaseCamera();
}
if (this.container) {

File diff suppressed because one or more lines are too long

@ -31,12 +31,12 @@
"test"
],
"homepage": "https://github.com/dropbox/zxcvbn",
"version": "4.3.0",
"_release": "4.3.0",
"version": "4.4.0",
"_release": "4.4.0",
"_resolution": {
"type": "version",
"tag": "4.3.0",
"commit": "62aca144af8c6ca9651ceaa981a52cce1df4fef1"
"tag": "v4.4.0",
"commit": "4c3d1c2b4a246cc8d7c81a61e341ad92ce14411b"
},
"_source": "https://github.com/dropbox/zxcvbn.git",
"_target": ">=4.2.0",

@ -1,4 +1,4 @@
Copyright (c) 2012-2015 Dan Wheeler and Dropbox, Inc.
Copyright (c) 2012-2016 Dan Wheeler and Dropbox, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

@ -10,17 +10,28 @@ ________________________________________________________________________
[![Build Status](https://travis-ci.org/dropbox/zxcvbn.svg?branch=master)](https://travis-ci.org/dropbox/zxcvbn)
[![Sauce Test Status](https://saucelabs.com/browser-matrix/dropbox-zxcvbn.svg)](https://saucelabs.com/u/dropbox-zxcvbn)
`zxcvbn` is a password strength estimator inspired by password crackers. Through pattern matching and conservative entropy calculations, it recognizes and weighs 30k common passwords, common names and surnames according to US census data, popular English words from Wikipedia and US television and movies, and other common patterns like dates, repeats (`aaa`), sequences (`abcd`), keyboard patterns (`qwertyuiop`), and l33t speak.
`zxcvbn` is a password strength estimator inspired by password crackers. Through pattern matching and conservative estimation, it recognizes and weighs 30k common passwords, common names and surnames according to US census data, popular English words from Wikipedia and US television and movies, and other common patterns like dates, repeats (`aaa`), sequences (`abcd`), keyboard patterns (`qwertyuiop`), and l33t speak.
Consider using zxcvbn as an algorithmic alternative to password composition policy — it is more secure, flexible, and usable when sites require a minimal complexity score in place of annoying rules like "passwords must contain three of {lower, upper, numbers, symbols}".
* __More secure__: policies often fail both ways, allowing weak passwords (`P@ssword1`) and disallowing strong passwords.
* __More flexible__: zxcvbn allows many password styles to flourish so long as it detects sufficient complexity — passphrases are rated highly given enough uncommon words, keyboard patterns are ranked based on length and number of turns, and capitalization adds more complexity when it's unpredictaBle.
* __More usable__: Use zxcvbn to build simple, rule-free interfaces that give instant feedback. In addition to scoring, zxcvbn includes minimal, targeted verbal feedback that can help guide users towards less guessable passwords.
* __More usable__: zxcvbn is designed to power simple, rule-free interfaces that give instant feedback. In addition to strength estimation, zxcvbn includes minimal, targeted verbal feedback that can help guide users towards less guessable passwords.
At Dropbox we use zxcvbn on our [signup page](https://www.dropbox.com/register) and change/reset password flows. zxcvbn is designed for node and the browser, but we use our [python port](https://github.com/dropbox/python-zxcvbn) inside the Dropbox desktop client and [Objective C port](https://github.com/dropbox/zxcvbn-ios) in our iOS app.
At Dropbox we use zxcvbn ([Release notes](https://github.com/dropbox/zxcvbn/releases)) on our web, desktop, iOS and Android clients. If JavaScript doesn't work for you, others have graciously ported the library to these languages:
[Release notes](https://github.com/dropbox/zxcvbn/releases)
* [`zxcvbn-c`](https://github.com/tsyrogit/zxcvbn-c) (C/C++)
* [`zxcvbn4j`](https://github.com/nulab/zxcvbn4j) (Java)
* [`zxcvbn-ios`](https://github.com/dropbox/zxcvbn-ios) (Objective-C)
* [`python-zxcvbn`](https://github.com/dropbox/python-zxcvbn) (Python)
* [`zxcvbn-go`](https://github.com/nbutton23/zxcvbn-go) (Go)
* [`zxcvbn-ruby`](https://github.com/envato/zxcvbn-ruby) (Ruby)
* [`zxcvbn-php`](https://github.com/bjeavons/zxcvbn-php) (PHP)
* [`zxcvbn-cs`](https://github.com/mickford/zxcvbn-cs) (C#/.NET)
* [`szxcvbn`](https://github.com/tekul/szxcvbn) (Scala)
Integrations with other frameworks:
* [`angular-zxcvbn`](https://github.com/ghostbar/angular-zxcvbn) (AngularJS)
For more motivation, see:
@ -44,7 +55,7 @@ bower install zxcvbn
Add this script to your `index.html`:
``` html
<script type="text/javascript" src="bower_components/zxcvbn/dist/zxcvbn.js">
<script src="bower_components/zxcvbn/dist/zxcvbn.js">
</script>
```
@ -56,7 +67,7 @@ To pull in updates and bug fixes:
bower update zxcvbn
```
## Node / npm
## Node / npm / MeteorJS
zxcvbn works identically on the server.
@ -67,11 +78,6 @@ $ node
> zxcvbn('Tr0ub4dour&3');
```
## Meteor (via [Atmosphere](https://atmospherejs.com/codetheweb/zxcvbn))
``` shell
meteor add codetheweb:zxcvbn
```
## RequireJS
Add [`zxcvbn.js`](https://raw.githubusercontent.com/dropbox/zxcvbn/master/dist/zxcvbn.js) to your project (using bower, npm or direct download) and import as usual:
@ -122,8 +128,7 @@ Download [zxcvbn.js](https://raw.githubusercontent.com/dropbox/zxcvbn/master/dis
Add to your .html:
``` html
<script type="text/javascript" src="path/to/zxcvbn.js">
</script>
<script type="text/javascript" src="path/to/zxcvbn.js"></script>
```
# Usage
@ -140,7 +145,7 @@ zxcvbn(password, user_inputs=[])
result.guesses # estimated guesses needed to crack password
result.guesses_log10 # order of magnitude of result.guesses
result.crack_time_seconds # dictionary of back-of-the-envelope crack time
result.crack_times_seconds # dictionary of back-of-the-envelope crack time
# estimations, in seconds, based on a few scenarios:
{
# online attack on a service that ratelimits password auth attempts.
@ -163,9 +168,9 @@ result.crack_time_seconds # dictionary of back-of-the-envelope crack time
offline_fast_hashing_1e10_per_second
}
result.crack_time_display # same keys as result.crack_time_seconds,
# with friendlier display string values:
# "less than a second", "3 hours", "centuries", etc.
result.crack_times_display # same keys as result.crack_times_seconds,
# with friendlier display string values:
# "less than a second", "3 hours", "centuries", etc.
result.score # Integer from 0-4 (useful for implementing a strength bar)
@ -204,19 +209,19 @@ zxcvbn operates below human perception of delay for most input: ~5-20ms for ~25
## script load latency
`zxcvbn.js` bundled and minified is about 390kb gzipped or 800kb uncompressed, most of which is dictionaries. Consider these tips if you're noticing page load latency on your site.
`zxcvbn.js` bundled and minified is about 400kB gzipped or 820kB uncompressed, most of which is dictionaries. Consider these tips if you're noticing page load latency on your site.
* Make sure your server is configured to compress static assets for browsers that support it. ([nginx tutorial](https://rtcamp.com/tutorials/nginx/enable-gzip/), [apache/IIS tutorial](http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/).)
* Make sure your server is configured to compress static assets for browsers that support it. ([nginx tutorial](https://rtcamp.com/tutorials/nginx/enable-gzip/), [Apache/IIS tutorial](http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/).)
Then try one of these alternatives:
1. Put your `<script src="zxcvbn.js">` tag at the end of your html, just before the closing `</body>` tag. This insures your page loads and renders before the browser fetches and loads `zxcvbn.js`. The downside with this approach is `zxcvbn()` becomes available later than had it been included in `<head>` — not an issue on most signup pages where users are filling out other fields first.
2. If you're using requirejs, try loading `zxcvbn.js` separately from your main bundle. Something to watch out for: if `zxcvbn.js` is required inside a keyboard handler waiting for user input, the entire script might be loaded only after the user presses their first key, creating nasty latency. Avoid this by calling your handler once upon page load, independent of user input, such that the `requirejs()` call runs earlier.
2. If you're using RequireJS, try loading `zxcvbn.js` separately from your main bundle. Something to watch out for: if `zxcvbn.js` is required inside a keyboard handler waiting for user input, the entire script might be loaded only after the user presses their first key, creating nasty latency. Avoid this by calling your handler once upon page load, independent of user input, such that the `requirejs()` call runs earlier.
3. Use the HTML5 [`async`](http://www.w3schools.com/tags/att_script_async.asp) script attribute. Downside: [doesn't work](http://caniuse.com/#feat=script-async) in IE7-9 or Opera Mini.
4. Include an inline `<script>` in `<head>` that asynchronously loads `zxcvbn.js` in the background. Despite the extra code I prefer this over (3) because it works in older browsers.
4. Include an inline `<script>` in `<head>` that asynchronously loads `zxcvbn.js` in the background. Advantage over (3): it works in older browsers.
``` javascript
// cross-browser asynchronous script loading for zxcvbn.
@ -270,11 +275,11 @@ For node developers, in addition to `dist`, the zxcvbn `npm` module includes a `
[Dropbox](https://dropbox.com) for supporting open source!
Leah Culver and Ryan Pearl for porting zxcvbn to [Objective C](https://github.com/dropbox/zxcvbn-ios) and [python](https://github.com/dropbox/python-zxcvbn).
Leah Culver and Ryan Pearl for porting zxcvbn to [Objective-C](https://github.com/dropbox/zxcvbn-ios) and [Python](https://github.com/dropbox/python-zxcvbn).
Mark Burnett for releasing his 10M password corpus and for his 2005 book, [Perfect Passwords: Selection, Protection, Authentication](http://www.amazon.com/Perfect-Passwords-Selection-Protection-Authentication/dp/1597490415).
Wiktionary contributors for building a [frequency list of English](http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists) as used in television and movies.
Wiktionary contributors for building a [frequency list of English words](http://en.wiktionary.org/wiki/Wiktionary:Frequency_lists) as used in television and movies.
Researchers at Concordia University for [studying password estimation rigorously](http://www.concordia.ca/cunews/main/stories/2015/03/25/does-your-password-pass-muster.html) and recommending zxcvbn.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save