1 /**
  2  * The MIT License (MIT)
  3  *
  4  * Copyright (c) 2016 DeNA Co., Ltd.
  5  *
  6  * Permission is hereby granted, free of charge, to any person obtaining a copy
  7  * of this software and associated documentation files (the "Software"), to deal
  8  * in the Software without restriction, including without limitation the rights
  9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10  * copies of the Software, and to permit persons to whom the Software is
 11  * furnished to do so, subject to the following conditions:
 12  *
 13  * The above copyright notice and this permission notice shall be included in
 14  * all copies or substantial portions of the Software.
 15  *
 16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22  * SOFTWARE.
 23  */
 24 
 25 /// <reference path="base.js"/>
 26 /// <reference path="object.js"/>
 27 /// <reference path="event.js"/>
 28 
 29 /**
 30  * A singleton class that creates HTMLImageElement objects used in this library.
 31  * @constructor
 32  */
 33 createjs.ImageFactory = function() {
 34   /**
 35    * The images created by this object.
 36    * @type {Object.<string,HTMLImageElement>}
 37    * @private
 38    */
 39   this.images_ = {};
 40 };
 41 
 42 /**
 43  * The instance of the createjs.ImageFactory object.
 44  * @type {createjs.ImageFactory}
 45  * @private
 46  */
 47 createjs.ImageFactory.instance_ = null;
 48 
 49 /**
 50  * Returns the global instance of the createjs.ImageFactory object.
 51  * @return {createjs.ImageFactory}
 52  * @private
 53  */
 54 createjs.ImageFactory.getInstance_ = function() {
 55   /// <returns type="createjs.ImageFactory"/>
 56   if (!createjs.ImageFactory.instance_) {
 57     createjs.ImageFactory.instance_ = new createjs.ImageFactory();
 58   }
 59   return createjs.ImageFactory.instance_;
 60 };
 61 
 62 /**
 63  * Creates an HTMLImageElement object.
 64  * @param {string} path
 65  * @param {string} source
 66  * @param {EventListener} listener
 67  * @param {number} format
 68  * @return {HTMLImageElement}
 69  * @private
 70  */
 71 createjs.ImageFactory.create_ = function(path, source, listener, format) {
 72   /// <param type="string" name="path"/>
 73   /// <param type="string" name="source"/>
 74   /// <param type="EventListener" name="listener"/>
 75   /// <param type="number" name="format"/>
 76   /// <returns type="HTMLImageElement"/>
 77   var image = /** @type {HTMLImageElement} */ (document.createElement('img'));
 78   var scheme = (source.charCodeAt(0) << 24) + (source.charCodeAt(1) << 16) +
 79       (source.charCodeAt(2) << 8) + source.charCodeAt(3);
 80   if (scheme != 0x64617461) {
 81     // Set the crossOrigin attribute only when the given URI is not a Data URI.
 82     // Mobile Safari throws an exception when it creates a WebGL texture from
 83     // an anonymously-shared HTMLImageElement object with its source a Data URI.
 84     image.crossOrigin = 'anonymous';
 85   }
 86   image.addEventListener('load', listener, false);
 87   image.addEventListener('error', listener, false);
 88   image.format_ = format;
 89   image.src = source;
 90   return image;
 91 };
 92 
 93 /**
 94  * Retrieves an HTMLImageElement object spooled by the createjs.ImageFactory
 95  * object.
 96  * @param {string} path
 97  * @param {string} source
 98  * @param {EventListener} listener
 99  * @param {number} format
100  * @return {HTMLImageElement}
101  * @const
102  */
103 createjs.ImageFactory.get = function(path, source, listener, format) {
104   /// <param type="string" name="path"/>
105   /// <param type="string" name="source"/>
106   /// <param type="EventListener" name="listener"/>
107   /// <param type="number" name="format"/>
108   /// <returns type="HTMLImageElement"/>
109   var instance = createjs.ImageFactory.getInstance_();
110   var image = instance.images_[path];
111   if (!image) {
112     image = createjs.ImageFactory.create_(path, source, listener, format);
113     instance.images_[path] = image;
114   } else if (!image.complete) {
115     // This cached image is created by another object and being loaded now. Add
116     // the specified listener so the image calls its handleEvent() method as
117     // well.
118     image.addEventListener('load', listener, false);
119     image.addEventListener('error', listener, false);
120   }
121   return image;
122 };
123 
124 /**
125  * Removes all event listeners attached by the 'createjs.ImageFactory.get()'
126  * method.
127  * @param {EventTarget} image
128  * @param {EventListener} listener
129  * @const
130  */
131 createjs.ImageFactory.removeListeners = function(image, listener) {
132   image.removeEventListener('load', listener, false);
133   image.removeEventListener('error', listener, false);
134 };
135 
136 /**
137  * Deletes all images attached to the createjs.ImageFactory object.
138  * @param {boolean=} opt_destroy
139  * @return {Object.<string,HTMLImageElement>}
140  * @const
141  */
142 createjs.ImageFactory.reset = function(opt_destroy) {
143   /// <param type="boolean" optional="true" name="opt_destroy"/>
144   /// <return type="Object"/>
145   var instance = createjs.ImageFactory.instance_;
146   if (!instance) {
147     return null;
148   }
149   var images = instance.images_;
150   if (opt_destroy) {
151     instance.images_ = {};
152   }
153   return images;
154 };
155