utils.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module image/imageupload/utils
  7. */
  8. /* global fetch, File */
  9. /**
  10. * Checks if a given file is an image.
  11. *
  12. * @param {File} file
  13. * @returns {Boolean}
  14. */
  15. export function isImageType( file ) {
  16. const types = /^image\/(jpeg|png|gif|bmp)$/;
  17. return types.test( file.type );
  18. }
  19. /**
  20. * Creates a promise which fetches the image local source (base64 or blob) and resolves with a `File` object.
  21. *
  22. * @param {module:engine/view/element~Element} image Image which source to fetch.
  23. * @returns {Promise.<File>} A promise which resolves when image source is fetched and converted to `File` instance.
  24. * It resolves with a `File` object. If there were any errors during file processing the promise will be rejected.
  25. */
  26. export function fetchLocalImage( image ) {
  27. return new Promise( ( resolve, reject ) => {
  28. const imageSrc = image.getAttribute( 'src' );
  29. // Fetch works asynchronously and so does not block browser UI when processing data.
  30. fetch( imageSrc )
  31. .then( resource => resource.blob() )
  32. .then( blob => {
  33. const mimeType = getImageMimeType( blob, imageSrc );
  34. const ext = mimeType.replace( 'image/', '' );
  35. const filename = `image.${ ext }`;
  36. const file = createFileFromBlob( blob, filename, mimeType );
  37. file ? resolve( file ) : reject();
  38. } )
  39. .catch( reject );
  40. } );
  41. }
  42. /**
  43. * Checks whether given node is an image element with local source (base64 or blob).
  44. *
  45. * @param {module:engine/view/node~Node} node Node to check.
  46. * @returns {Boolean}
  47. */
  48. export function isLocalImage( node ) {
  49. if ( !node.is( 'element', 'img' ) || !node.getAttribute( 'src' ) ) {
  50. return false;
  51. }
  52. return node.getAttribute( 'src' ).match( /^data:image\/\w+;base64,/g ) ||
  53. node.getAttribute( 'src' ).match( /^blob:/g );
  54. }
  55. // Extracts image type based on its blob representation or its source.
  56. //
  57. // @param {String} src Image src attribute value.
  58. // @param {Blob} blob Image blob representation.
  59. // @returns {String}
  60. function getImageMimeType( blob, src ) {
  61. if ( blob.type ) {
  62. return blob.type;
  63. } else if ( src.match( /data:(image\/\w+);base64/ ) ) {
  64. return src.match( /data:(image\/\w+);base64/ )[ 1 ].toLowerCase();
  65. } else {
  66. // Fallback to 'jpeg' as common extension.
  67. return 'image/jpeg';
  68. }
  69. }
  70. // Creates `File` instance from the given `Blob` instance using specified filename.
  71. //
  72. // @param {Blob} blob The `Blob` instance from which file will be created.
  73. // @param {String} filename Filename used during file creation.
  74. // @param {String} mimeType File mime type.
  75. // @returns {File|null} The `File` instance created from the given blob or `null` if `File API` is not available.
  76. function createFileFromBlob( blob, filename, mimeType ) {
  77. try {
  78. return new File( [ blob ], filename, { type: mimeType } );
  79. } catch ( err ) {
  80. // Edge does not support `File` constructor ATM, see https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9551546/.
  81. // However, the `File` function is present (so cannot be checked with `!window.File` or `typeof File === 'function'`), but
  82. // calling it with `new File( ... )` throws an error. This try-catch prevents that. Also when the function will
  83. // be implemented correctly in Edge the code will start working without any changes (see #247).
  84. return null;
  85. }
  86. }