PageRenderTime 59ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/build/seed-debug.js

https://github.com/atgwwx/kissy
JavaScript | 3493 lines | 2381 code | 249 blank | 863 comment | 479 complexity | 5f15647ec8de1016d71ea5d53b62e4fa MD5 | raw file
  1. /*
  2. Copyright 2014, KISSY v5.0.0
  3. MIT Licensed
  4. build time: Jul 1 22:55
  5. */
  6. /**
  7. * @ignore
  8. * A seed where KISSY grows up from, KISS Yeah !
  9. * @author https://github.com/kissyteam/kissy/contributors
  10. */
  11. /**
  12. * The KISSY global namespace object. you can use
  13. *
  14. *
  15. * KISSY.each/mix
  16. *
  17. * to do basic operation. or
  18. *
  19. *
  20. * KISSY.use('overlay,node', function(S, Overlay, Node){
  21. * //
  22. * });
  23. *
  24. * to do complex task with modules.
  25. * @singleton
  26. * @class KISSY
  27. */
  28. /* exported KISSY */
  29. /*jshint -W079 */
  30. var KISSY = (function (undefined) {
  31. // --no-module-wrap--
  32. var self = this,
  33. S;
  34. S = {
  35. /**
  36. * The build time of the library.
  37. * NOTICE: '20140701225543' will replace with current timestamp when compressing.
  38. * @private
  39. * @type {String}
  40. */
  41. __BUILD_TIME: '20140701225543',
  42. /**
  43. * KISSY Environment.
  44. * @private
  45. * @type {Object}
  46. */
  47. Env: {
  48. host: self,
  49. mods: {}
  50. },
  51. /**
  52. * KISSY Config.
  53. * If load kissy.js, Config.debug defaults to true.
  54. * Else If load kissy-min.js, Config.debug defaults to false.
  55. * @private
  56. * @property {Object} Config
  57. * @property {Boolean} Config.debug
  58. * @member KISSY
  59. */
  60. Config: {
  61. debug: '@DEBUG@',
  62. packages: {},
  63. fns: {}
  64. },
  65. /**
  66. * The version of the library.
  67. * NOTICE: '5.0.0' will replace with current version when compressing.
  68. * @type {String}
  69. */
  70. version: '5.0.0',
  71. /**
  72. * set KISSY configuration
  73. * @param {Object|String} configName Config object or config key.
  74. * @param {String} configName.base KISSY 's base path. Default: get from loader(-min).js or seed(-min).js
  75. * @param {String} configName.tag KISSY 's timestamp for native module. Default: KISSY 's build time.
  76. * @param {Boolean} configName.debug whether to enable debug mod.
  77. * @param {Boolean} configName.combine whether to enable combo.
  78. * @param {Object} configName.logger logger config
  79. * @param {Object[]} configName.logger.excludes exclude configs
  80. * @param {Object} configName.logger.excludes.0 a single exclude config
  81. * @param {RegExp} configName.logger.excludes.0.logger matched logger will be excluded from logging
  82. * @param {String} configName.logger.excludes.0.minLevel minimum logger level (enum of debug info warn error)
  83. * @param {String} configName.logger.excludes.0.maxLevel maximum logger level (enum of debug info warn error)
  84. * @param {Object[]} configName.logger.includes include configs
  85. * @param {Object} configName.logger.includes.0 a single include config
  86. * @param {RegExp} configName.logger.includes.0.logger matched logger will be included from logging
  87. * @param {String} configName.logger.excludes.0.minLevel minimum logger level (enum of debug info warn error)
  88. * @param {String} configName.logger.excludes.0.maxLevel maximum logger level (enum of debug info warn error)
  89. * @param {Object} configName.packages Packages definition with package name as the key.
  90. * @param {String} configName.packages.base Package base path.
  91. * @param {String} configName.packages.tag Timestamp for this package's module file.
  92. * @param {String} configName.packages.debug Whether force debug mode for current package.
  93. * @param {String} configName.packages.combine Whether allow combine for current package modules.
  94. * can only be used in production mode.
  95. * @param [configValue] config value.
  96. *
  97. * for example:
  98. * @example
  99. * KISSY.config({
  100. * combine: true,
  101. * base: '',
  102. * packages: {
  103. * 'gallery': {
  104. * base: 'http://a.tbcdn.cn/s/kissy/gallery/'
  105. * }
  106. * },
  107. * modules: {
  108. * 'gallery/x/y': {
  109. * requires: ['gallery/x/z']
  110. * }
  111. * }
  112. * });
  113. */
  114. config: function (configName, configValue) {
  115. var cfg,
  116. r,
  117. self = this,
  118. fn,
  119. Config = S.Config,
  120. configFns = Config.fns;
  121. if (typeof configName === 'string') {
  122. cfg = configFns[configName];
  123. if (configValue === undefined) {
  124. if (cfg) {
  125. r = cfg.call(self);
  126. } else {
  127. r = Config[configName];
  128. }
  129. } else {
  130. if (cfg) {
  131. r = cfg.call(self, configValue);
  132. } else {
  133. Config[configName] = configValue;
  134. }
  135. }
  136. } else {
  137. for (var p in configName) {
  138. configValue = configName[p];
  139. fn = configFns[p];
  140. if (fn) {
  141. fn.call(self, configValue);
  142. } else {
  143. Config[p] = configValue;
  144. }
  145. }
  146. }
  147. return r;
  148. }
  149. };
  150. var Loader = S.Loader = {};
  151. if (typeof location !== 'undefined') {
  152. if (location.search.indexOf('ks-debug') !== -1) {
  153. S.Config.debug = true;
  154. }
  155. }
  156. /**
  157. * Loader Status Enum
  158. * @enum {Number} KISSY.Loader.Status
  159. */
  160. Loader.Status = {
  161. /** error */
  162. ERROR: -1,
  163. /** init */
  164. INIT: 0,
  165. /** loading */
  166. LOADING: 1,
  167. /** loaded */
  168. LOADED: 2,
  169. /** attaching */
  170. ATTACHING: 3,
  171. /** attached */
  172. ATTACHED: 4
  173. };
  174. return S;
  175. })();/**
  176. * logger utils
  177. * @author yiminghe@gmail.com
  178. */
  179. (function (S) {
  180. function getLogger(logger) {
  181. var obj = {};
  182. for (var cat in loggerLevel) {
  183. /*jshint loopfunc: true*/
  184. (function (obj, cat) {
  185. obj[cat] = function (msg) {
  186. return LoggerManager.log(msg, cat, logger);
  187. };
  188. })(obj, cat);
  189. }
  190. return obj;
  191. }
  192. var config = {};
  193. if ('@DEBUG@') {
  194. config = {
  195. excludes: [
  196. {
  197. logger: /^s\/.*/,
  198. maxLevel: 'info',
  199. minLevel: 'debug'
  200. }
  201. ]
  202. };
  203. }
  204. var loggerLevel = {
  205. debug: 10,
  206. info: 20,
  207. warn: 30,
  208. error: 40
  209. };
  210. var LoggerManager = {
  211. config: function (cfg) {
  212. config = cfg || config;
  213. return config;
  214. },
  215. /**
  216. * Prints debug info.
  217. * @param msg {String} the message to log.
  218. * @param {String} [cat] the log category for the message. Default
  219. * categories are 'info', 'warn', 'error', 'time' etc.
  220. * @param {String} [logger] the logger of the the message (opt)
  221. */
  222. log: function (msg, cat, logger) {
  223. if ('@DEBUG@') {
  224. var matched = 1;
  225. if (logger) {
  226. var list, i, l, level, minLevel, maxLevel, reg;
  227. cat = cat || 'debug';
  228. level = loggerLevel[cat] || loggerLevel.debug;
  229. if ((list = config.includes)) {
  230. matched = 0;
  231. for (i = 0; i < list.length; i++) {
  232. l = list[i];
  233. reg = l.logger;
  234. maxLevel = loggerLevel[l.maxLevel] || loggerLevel.error;
  235. minLevel = loggerLevel[l.minLevel] || loggerLevel.debug;
  236. if (minLevel <= level && maxLevel >= level && logger.match(reg)) {
  237. matched = 1;
  238. break;
  239. }
  240. }
  241. } else if ((list = config.excludes)) {
  242. matched = 1;
  243. for (i = 0; i < list.length; i++) {
  244. l = list[i];
  245. reg = l.logger;
  246. maxLevel = loggerLevel[l.maxLevel] || loggerLevel.error;
  247. minLevel = loggerLevel[l.minLevel] || loggerLevel.debug;
  248. if (minLevel <= level && maxLevel >= level && logger.match(reg)) {
  249. matched = 0;
  250. break;
  251. }
  252. }
  253. }
  254. if (matched) {
  255. msg = logger + ': ' + msg;
  256. }
  257. }
  258. /*global console*/
  259. if (matched) {
  260. if (typeof console !== 'undefined' && console.log) {
  261. console[cat && console[cat] ? cat : 'log'](msg);
  262. }
  263. return msg;
  264. }
  265. }
  266. return undefined;
  267. },
  268. /**
  269. * get log instance for specified logger
  270. * @param {String} logger logger name
  271. * @returns {KISSY.LoggerManager} log instance
  272. */
  273. getLogger: function (logger) {
  274. return getLogger(logger);
  275. },
  276. /**
  277. * Throws error message.
  278. */
  279. error: function (msg) {
  280. if ('@DEBUG@') {
  281. // with stack info!
  282. throw msg instanceof Error ? msg : new Error(msg);
  283. }
  284. }
  285. };
  286. /**
  287. * Log class for specified logger
  288. * @class KISSY.LoggerManager
  289. * @private
  290. */
  291. /**
  292. * print debug log
  293. * @method debug
  294. * @member KISSY.LoggerManager
  295. * @param {String} str log str
  296. */
  297. /**
  298. * print info log
  299. * @method info
  300. * @member KISSY.LoggerManager
  301. * @param {String} str log str
  302. */
  303. /**
  304. * print warn log
  305. * @method log
  306. * @member KISSY.LoggerManager
  307. * @param {String} str log str
  308. */
  309. /**
  310. * print error log
  311. * @method error
  312. * @member KISSY.LoggerManager
  313. * @param {String} str log str
  314. */
  315. S.LoggerMangaer = LoggerManager;
  316. S.getLogger = LoggerManager.getLogger;
  317. S.log = LoggerManager.log;
  318. S.error = LoggerManager.error;
  319. S.Config.fns.logger = LoggerManager.config;
  320. })(KISSY);/**
  321. * @ignore
  322. * Utils for kissy loader
  323. * @author yiminghe@gmail.com
  324. */
  325. (function (S) {
  326. // --no-module-wrap--
  327. var Loader = S.Loader,
  328. Env = S.Env,
  329. mods = Env.mods,
  330. map = Array.prototype.map,
  331. host = Env.host,
  332. /**
  333. * @class KISSY.Loader.Utils
  334. * Utils for KISSY Loader
  335. * @singleton
  336. * @private
  337. */
  338. Utils = Loader.Utils = {},
  339. doc = host.document;
  340. function numberify(s) {
  341. var c = 0;
  342. // convert '1.2.3.4' to 1.234
  343. return parseFloat(s.replace(/\./g, function () {
  344. return (c++ === 0) ? '.' : '';
  345. }));
  346. }
  347. function splitSlash(str) {
  348. var parts = str.split(/\//);
  349. if (str.charAt(0) === '/' && parts[0]) {
  350. parts.unshift('');
  351. }
  352. if (str.charAt(str.length - 1) === '/' && str.length > 1 && parts[parts.length - 1]) {
  353. parts.push('');
  354. }
  355. return parts;
  356. }
  357. var m, v,
  358. ua = (host.navigator || {}).userAgent || '';
  359. // https://github.com/kissyteam/kissy/issues/545
  360. if (((m = ua.match(/AppleWebKit\/([\d.]*)/)) || (m = ua.match(/Safari\/([\d.]*)/))) && m[1]) {
  361. Utils.webkit = numberify(m[1]);
  362. }
  363. if ((m = ua.match(/Trident\/([\d.]*)/))) {
  364. Utils.trident = numberify(m[1]);
  365. }
  366. if ((m = ua.match(/Gecko/))) {
  367. Utils.gecko = 0.1; // Gecko detected, look for revision
  368. if ((m = ua.match(/rv:([\d.]*)/)) && m[1]) {
  369. Utils.gecko = numberify(m[1]);
  370. }
  371. }
  372. if ((m = ua.match(/MSIE ([^;]*)|Trident.*; rv(?:\s|:)?([0-9.]+)/)) &&
  373. (v = (m[1] || m[2]))) {
  374. Utils.ie = numberify(v);
  375. Utils.ieMode = doc.documentMode || Utils.ie;
  376. Utils.trident = Utils.trident || 1;
  377. }
  378. var urlReg = /http(s)?:\/\/([^/]+)(?::(\d+))?/,
  379. commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
  380. requireRegExp = /[^.'"]\s*require\s*\((['"])([^)]+)\1\)/g;
  381. function normalizeName(name) {
  382. // 'x/' 'x/y/z/'
  383. if (name.charAt(name.length - 1) === '/') {
  384. name += 'index';
  385. }
  386. // x.js === x
  387. if (Utils.endsWith(name, '.js')) {
  388. name = name.slice(0, -3);
  389. }
  390. return name;
  391. }
  392. function each(obj, fn) {
  393. var i = 0,
  394. myKeys, l;
  395. if (isArray(obj)) {
  396. l = obj.length;
  397. for (; i < l; i++) {
  398. if (fn(obj[i], i, obj) === false) {
  399. break;
  400. }
  401. }
  402. } else {
  403. myKeys = keys(obj);
  404. l = myKeys.length;
  405. for (; i < l; i++) {
  406. if (fn(obj[myKeys[i]], myKeys[i], obj) === false) {
  407. break;
  408. }
  409. }
  410. }
  411. }
  412. function keys(obj) {
  413. var ret = [];
  414. for (var key in obj) {
  415. ret.push(key);
  416. }
  417. return ret;
  418. }
  419. var isArray = Array.isArray || function (obj) {
  420. return Object.prototype.toString.call(obj) === '[object Array]';
  421. };
  422. function mix(to, from) {
  423. for (var i in from) {
  424. to[i] = from[i];
  425. }
  426. return to;
  427. }
  428. mix(Utils, {
  429. mix: mix,
  430. noop: function () {
  431. },
  432. map: map ?
  433. function (arr, fn, context) {
  434. return map.call(arr, fn, context || this);
  435. } :
  436. function (arr, fn, context) {
  437. var len = arr.length,
  438. res = new Array(len);
  439. for (var i = 0; i < len; i++) {
  440. var el = typeof arr === 'string' ? arr.charAt(i) : arr[i];
  441. if (el ||
  442. //ie<9 in invalid when typeof arr == string
  443. i in arr) {
  444. res[i] = fn.call(context || this, el, i, arr);
  445. }
  446. }
  447. return res;
  448. },
  449. startsWith: function (str, prefix) {
  450. return str.lastIndexOf(prefix, 0) === 0;
  451. },
  452. isEmptyObject: function (o) {
  453. for (var p in o) {
  454. if (p !== undefined) {
  455. return false;
  456. }
  457. }
  458. return true;
  459. },
  460. endsWith: function (str, suffix) {
  461. var ind = str.length - suffix.length;
  462. return ind >= 0 && str.indexOf(suffix, ind) === ind;
  463. },
  464. now: Date.now || function () {
  465. return +new Date();
  466. },
  467. each: each,
  468. keys: keys,
  469. isArray: isArray,
  470. indexOf: function (item, arr) {
  471. for (var i = 0, l = arr.length; i < l; i++) {
  472. if (arr[i] === item) {
  473. return i;
  474. }
  475. }
  476. return -1;
  477. },
  478. normalizeSlash: function (str) {
  479. return str.replace(/\\/g, '/');
  480. },
  481. normalizePath: function (parentPath, subPath) {
  482. var firstChar = subPath.charAt(0);
  483. if (firstChar !== '.') {
  484. return subPath;
  485. }
  486. var parts = splitSlash(parentPath);
  487. var subParts = splitSlash(subPath);
  488. parts.pop();
  489. for (var i = 0, l = subParts.length; i < l; i++) {
  490. var subPart = subParts[i];
  491. if (subPart === '.') {
  492. } else if (subPart === '..') {
  493. parts.pop();
  494. } else {
  495. parts.push(subPart);
  496. }
  497. }
  498. return parts.join('/').replace(/\/+/, '/');
  499. },
  500. isSameOriginAs: function (url1, url2) {
  501. var urlParts1 = url1.match(urlReg);
  502. var urlParts2 = url2.match(urlReg);
  503. return urlParts1[0] === urlParts2[0];
  504. },
  505. /**
  506. * get document head
  507. * @return {HTMLElement}
  508. */
  509. docHead: function () {
  510. return doc.getElementsByTagName('head')[0] || doc.documentElement;
  511. },
  512. /**
  513. * Returns hash code of a string djb2 algorithm
  514. * @param {String} str
  515. * @returns {String} hash code
  516. */
  517. getHash: function (str) {
  518. var hash = 5381,
  519. i;
  520. for (i = str.length; --i > -1;) {
  521. hash = ((hash << 5) + hash) + str.charCodeAt(i);
  522. /* hash * 33 + char */
  523. }
  524. return hash + '';
  525. },
  526. // ---------------------------------- for modules
  527. getRequiresFromFn: function (fn) {
  528. var requires = [];
  529. // Remove comments from the callback string,
  530. // look for require calls, and pull them into the dependencies,
  531. // but only if there are function args.
  532. fn.toString()
  533. .replace(commentRegExp, '')
  534. .replace(requireRegExp, function (match, _, dep) {
  535. requires.push(dep);
  536. });
  537. return requires;
  538. },
  539. // get a module from cache or create a module instance
  540. createModule: function (name, cfg) {
  541. var module = mods[name];
  542. if (!module) {
  543. name = normalizeName(name);
  544. module = mods[name];
  545. }
  546. if (module) {
  547. mix(module, cfg);
  548. // module definition changes requires
  549. if (cfg && cfg.requires) {
  550. module.setRequiresModules(cfg.requires);
  551. }
  552. return module;
  553. }
  554. // 防止 cfg 里有 tag,构建 fullpath 需要
  555. mods[name] = module = new Loader.Module(mix({
  556. name: name
  557. }, cfg));
  558. return module;
  559. },
  560. createModules: function (names) {
  561. return Utils.map(names, function (name) {
  562. return Utils.createModule(name);
  563. });
  564. },
  565. attachModules: function (mods) {
  566. var l = mods.length, i;
  567. for (i = 0; i < l; i++) {
  568. mods[i].attachRecursive();
  569. }
  570. },
  571. getModulesExports: function (mods) {
  572. var l = mods.length, i,
  573. ret = [];
  574. for (i = 0; i < l; i++) {
  575. ret.push(mods[i].getExports());
  576. }
  577. return ret;
  578. },
  579. addModule: function (name, factory, config) {
  580. var module = mods[name];
  581. if (module && module.factory !== undefined) {
  582. S.log(name + ' is defined more than once', 'warn');
  583. return;
  584. }
  585. Utils.createModule(name, mix({
  586. name: name,
  587. status: Loader.Status.LOADED,
  588. factory: factory
  589. }, config));
  590. }
  591. });
  592. })
  593. (KISSY);/**
  594. * @ignore
  595. * setup data structure for kissy loader
  596. * @author yiminghe@gmail.com
  597. */
  598. (function (S) {
  599. // --no-module-wrap--
  600. var Loader = S.Loader,
  601. Config = S.Config,
  602. Status = Loader.Status,
  603. ATTACHED = Status.ATTACHED,
  604. ATTACHING = Status.ATTACHING,
  605. Utils = Loader.Utils,
  606. startsWith = Utils.startsWith,
  607. createModule = Utils.createModule,
  608. mix = Utils.mix;
  609. function makeArray(arr) {
  610. var ret = [];
  611. for (var i = 0; i < arr.length; i++) {
  612. ret[i] = arr[i];
  613. }
  614. return ret;
  615. }
  616. function wrapUse(fn) {
  617. if (typeof fn === 'function') {
  618. return function () {
  619. fn.apply(this, makeArray(arguments).slice(1));
  620. };
  621. } else if (fn && fn.success) {
  622. var original = fn.success;
  623. fn.success = function () {
  624. original.apply(this, makeArray(arguments).slice(1));
  625. };
  626. return fn;
  627. }
  628. }
  629. function checkGlobalIfNotExist(self, property) {
  630. return property in self ? self[property] : Config[property];
  631. }
  632. /**
  633. * @class KISSY.Loader.Package
  634. * @private
  635. * This class should not be instantiated manually.
  636. */
  637. function Package(cfg) {
  638. mix(this, cfg);
  639. }
  640. Package.prototype = {
  641. constructor: Package,
  642. reset: function (cfg) {
  643. mix(this, cfg);
  644. },
  645. getFilter: function () {
  646. return checkGlobalIfNotExist(this, 'filter');
  647. },
  648. /**
  649. * Tag for package.
  650. * tag can not contain ".", eg: Math.random() !
  651. * @return {String}
  652. */
  653. getTag: function () {
  654. return checkGlobalIfNotExist(this, 'tag');
  655. },
  656. /**
  657. * get package url
  658. */
  659. getBase: function () {
  660. return this.base;
  661. },
  662. /**
  663. * Get charset for package.
  664. * @return {String}
  665. */
  666. getCharset: function () {
  667. return checkGlobalIfNotExist(this, 'charset');
  668. },
  669. /**
  670. * Whether modules are combined for this package.
  671. * @return {Boolean}
  672. */
  673. isCombine: function () {
  674. return checkGlobalIfNotExist(this, 'combine');
  675. },
  676. /**
  677. * Get package group (for combo).
  678. * @returns {String}
  679. */
  680. getGroup: function () {
  681. return checkGlobalIfNotExist(this, 'group');
  682. }
  683. };
  684. Loader.Package = Package;
  685. /**
  686. * @class KISSY.Loader.Module
  687. * @private
  688. * This class should not be instantiated manually.
  689. */
  690. function Module(cfg) {
  691. var self = this;
  692. /**
  693. * exports of this module
  694. */
  695. self.exports = undefined;
  696. /**
  697. * status of current modules
  698. */
  699. self.status = Status.INIT;
  700. /**
  701. * name of this module
  702. */
  703. self.name = undefined;
  704. /**
  705. * factory of this module
  706. */
  707. self.factory = undefined;
  708. // lazy initialize and commonjs module format
  709. self.cjs = 1;
  710. mix(self, cfg);
  711. self.waits = {};
  712. var require = self._require = function (moduleName) {
  713. if (typeof moduleName === 'string') {
  714. var requiresModule = createModule(self.resolve(moduleName));
  715. Utils.attachModules(requiresModule.getNormalizedModules());
  716. return requiresModule.getExports();
  717. } else {
  718. require.async.apply(require, arguments);
  719. }
  720. };
  721. require.async = function (mods) {
  722. for (var i = 0; i < mods.length; i++) {
  723. mods[i] = self.resolve(mods[i]);
  724. }
  725. var args = makeArray(arguments);
  726. args[0] = mods;
  727. args[1] = wrapUse(args[1]);
  728. S.use.apply(S, args);
  729. };
  730. require.resolve = function (relativeName) {
  731. return self.resolve(relativeName);
  732. };
  733. require.toUrl = function (path) {
  734. var url = self.getUrl();
  735. var pathIndex = url.indexOf('//');
  736. if (pathIndex === -1) {
  737. pathIndex = 0;
  738. } else {
  739. pathIndex = url.indexOf('/', pathIndex + 2);
  740. if (pathIndex === -1) {
  741. pathIndex = 0;
  742. }
  743. }
  744. var rest = url.substring(pathIndex);
  745. path = Utils.normalizePath(rest, path);
  746. return url.substring(0, pathIndex) + path;
  747. };
  748. require.load = S.getScript;
  749. // relative name resolve cache
  750. // self.resolveCache = {};
  751. }
  752. Module.prototype = {
  753. kissy: 1,
  754. constructor: Module,
  755. require: function (moduleName) {
  756. return S.require(this.resolve(moduleName));
  757. },
  758. resolve: function (relativeName) {
  759. return Utils.normalizePath(this.name, relativeName);
  760. // var resolveCache = this.resolveCache;
  761. // if (resolveCache[relativeName]) {
  762. // return resolveCache[relativeName];
  763. // }
  764. // resolveCache[relativeName] = Utils.normalizePath(this.name, relativeName);
  765. // return resolveCache[relativeName];
  766. },
  767. add: function (loader) {
  768. this.waits[loader.id] = loader;
  769. },
  770. remove: function (loader) {
  771. delete this.waits[loader.id];
  772. },
  773. contains: function (loader) {
  774. return this.waits[loader.id];
  775. },
  776. flush: function () {
  777. Utils.each(this.waits, function (loader) {
  778. loader.flush();
  779. });
  780. this.waits = {};
  781. },
  782. /**
  783. * Get the type if current Module
  784. * @return {String} css or js
  785. */
  786. getType: function () {
  787. var self = this,
  788. v = self.type;
  789. if (!v) {
  790. if (Utils.endsWith(self.name, '.css')) {
  791. v = 'css';
  792. } else {
  793. v = 'js';
  794. }
  795. self.type = v;
  796. }
  797. return v;
  798. },
  799. getExports: function () {
  800. return this.getNormalizedModules()[0].exports;
  801. },
  802. getAlias: function () {
  803. var self = this,
  804. name = self.name;
  805. if (self.normalizedAlias) {
  806. return self.normalizedAlias;
  807. }
  808. var alias = getShallowAlias(self);
  809. var ret = [];
  810. if (alias[0] === name) {
  811. ret = alias;
  812. } else {
  813. for (var i = 0, l = alias.length; i < l; i++) {
  814. var aliasItem = alias[i];
  815. if (aliasItem && aliasItem !== name) {
  816. var mod = createModule(aliasItem);
  817. var normalAlias = mod.getAlias();
  818. if (normalAlias) {
  819. ret.push.apply(ret, normalAlias);
  820. } else {
  821. ret.push(aliasItem);
  822. }
  823. }
  824. }
  825. }
  826. self.normalizedAlias = ret;
  827. return ret;
  828. },
  829. getNormalizedModules: function () {
  830. var self = this;
  831. if (self.normalizedModules) {
  832. return self.normalizedModules;
  833. }
  834. self.normalizedModules = Utils.map(self.getAlias(), function (alias) {
  835. return createModule(alias);
  836. });
  837. return self.normalizedModules;
  838. },
  839. /**
  840. * Get the path url of current module if load dynamically
  841. * @return {String}
  842. */
  843. getUrl: function () {
  844. var self = this;
  845. if (!self.url) {
  846. self.url = Utils.normalizeSlash(S.Config.resolveModFn(self));
  847. }
  848. return self.url;
  849. },
  850. /**
  851. * Get the package which current module belongs to.
  852. * @return {KISSY.Loader.Package}
  853. */
  854. getPackage: function () {
  855. var self = this;
  856. if (!('packageInfo' in self)) {
  857. var name = self.name;
  858. // absolute path
  859. if (startsWith(name, '/') ||
  860. startsWith(name, 'http://') ||
  861. startsWith(name, 'https://') ||
  862. startsWith(name, 'file://')) {
  863. self.packageInfo = null;
  864. return;
  865. }
  866. var packages = Config.packages,
  867. modNameSlash = self.name + '/',
  868. pName = '',
  869. p;
  870. for (p in packages) {
  871. if (startsWith(modNameSlash, p + '/') && p.length > pName.length) {
  872. pName = p;
  873. }
  874. }
  875. self.packageInfo = packages[pName] || packages.core;
  876. }
  877. return self.packageInfo;
  878. },
  879. /**
  880. * Get the tag of current module.
  881. * tag can not contain ".", eg: Math.random() !
  882. * @return {String}
  883. */
  884. getTag: function () {
  885. var self = this;
  886. return self.tag || self.getPackage() && self.getPackage().getTag();
  887. },
  888. /**
  889. * Get the charset of current module
  890. * @return {String}
  891. */
  892. getCharset: function () {
  893. var self = this;
  894. return self.charset || self.getPackage() && self.getPackage().getCharset();
  895. },
  896. setRequiresModules: function (requires) {
  897. var self = this;
  898. var requiredModules = self.requiredModules = Utils.map(normalizeRequires(requires, self), function (m) {
  899. return createModule(m);
  900. });
  901. var normalizedRequiredModules = [];
  902. Utils.each(requiredModules, function (mod) {
  903. normalizedRequiredModules.push.apply(normalizedRequiredModules, mod.getNormalizedModules());
  904. });
  905. self.normalizedRequiredModules = normalizedRequiredModules;
  906. },
  907. getNormalizedRequiredModules: function () {
  908. var self = this;
  909. if (self.normalizedRequiredModules) {
  910. return self.normalizedRequiredModules;
  911. }
  912. self.setRequiresModules(self.requires);
  913. return self.normalizedRequiredModules;
  914. },
  915. getRequiredModules: function () {
  916. var self = this;
  917. if (self.requiredModules) {
  918. return self.requiredModules;
  919. }
  920. self.setRequiresModules(self.requires);
  921. return self.requiredModules;
  922. },
  923. attachSelf: function () {
  924. var self = this,
  925. status = self.status,
  926. factory = self.factory,
  927. exports;
  928. if (status === Status.ATTACHED || status < Status.LOADED) {
  929. return true;
  930. }
  931. if (typeof factory === 'function') {
  932. self.exports = {};
  933. // compatible and efficiency
  934. // KISSY.add(function(S,undefined){})
  935. // 需要解开 index,相对路径
  936. // 但是需要保留 alias,防止值不对应
  937. //noinspection JSUnresolvedFunction
  938. exports = factory.apply(self,
  939. // KISSY.add(function(S){module.require}) lazy initialize
  940. (
  941. self.cjs ?
  942. [S, self._require, self.exports, self] :
  943. [S].concat(Utils.map(self.getRequiredModules(), function (m) {
  944. return m.getExports();
  945. }))
  946. )
  947. );
  948. if (exports !== undefined) {
  949. // noinspection JSUndefinedPropertyAssignment
  950. self.exports = exports;
  951. }
  952. } else {
  953. //noinspection JSUndefinedPropertyAssignment
  954. self.exports = factory;
  955. }
  956. self.status = ATTACHED;
  957. if (self.afterAttach) {
  958. self.afterAttach(self.exports);
  959. }
  960. },
  961. attachRecursive: function () {
  962. var self = this,
  963. status;
  964. status = self.status;
  965. // attached or circular dependency
  966. if (status >= ATTACHING || status < Status.LOADED) {
  967. return self;
  968. }
  969. self.status = ATTACHING;
  970. if (self.cjs) {
  971. // commonjs format will call require in module code again
  972. self.attachSelf();
  973. } else {
  974. Utils.each(self.getNormalizedRequiredModules(), function (m) {
  975. m.attachRecursive();
  976. });
  977. self.attachSelf();
  978. }
  979. return self;
  980. },
  981. undef: function () {
  982. this.status = Status.INIT;
  983. delete this.factory;
  984. delete this.exports;
  985. }
  986. };
  987. function pluginAlias(name) {
  988. var index = name.indexOf('!');
  989. if (index !== -1) {
  990. var pluginName = name.substring(0, index);
  991. name = name.substring(index + 1);
  992. var Plugin = createModule(pluginName).attachRecursive().exports || {};
  993. if (Plugin.alias) {
  994. name = Plugin.alias(S, name, pluginName);
  995. }
  996. }
  997. return name;
  998. }
  999. function normalizeRequires(requires, self) {
  1000. requires = requires || [];
  1001. var l = requires.length;
  1002. for (var i = 0; i < l; i++) {
  1003. requires[i] = self.resolve(requires[i]);
  1004. }
  1005. return requires;
  1006. }
  1007. function getShallowAlias(mod) {
  1008. var name = mod.name,
  1009. packageInfo,
  1010. alias = mod.alias;
  1011. if (typeof alias === 'string') {
  1012. mod.alias = alias = [alias];
  1013. }
  1014. if (alias) {
  1015. return alias;
  1016. }
  1017. packageInfo = mod.getPackage();
  1018. if (packageInfo && packageInfo.alias) {
  1019. alias = packageInfo.alias(name);
  1020. }
  1021. alias = mod.alias = alias || [
  1022. pluginAlias(name)
  1023. ];
  1024. return alias;
  1025. }
  1026. Loader.Module = Module;
  1027. })(KISSY);/**
  1028. * @ignore
  1029. * script/css load across browser
  1030. * @author yiminghe@gmail.com
  1031. */
  1032. (function (S) {
  1033. // --no-module-wrap--
  1034. var logger = S.getLogger('s/loader/getScript');
  1035. var CSS_POLL_INTERVAL = 30,
  1036. Utils = S.Loader.Utils,
  1037. // central poll for link node
  1038. timer = 0,
  1039. // node.id:{callback:callback,node:node}
  1040. monitors = {};
  1041. function startCssTimer() {
  1042. if (!timer) {
  1043. logger.debug('start css poll timer');
  1044. cssPoll();
  1045. }
  1046. }
  1047. function isCssLoaded(node, url) {
  1048. var loaded = 0;
  1049. if (Utils.webkit) {
  1050. // http://www.w3.org/TR/Dom-Level-2-Style/stylesheets.html
  1051. if (node.sheet) {
  1052. logger.debug('webkit css poll loaded: ' + url);
  1053. loaded = 1;
  1054. }
  1055. } else if (node.sheet) {
  1056. try {
  1057. var cssRules = node.sheet.cssRules;
  1058. if (cssRules) {
  1059. logger.debug('same domain css poll loaded: ' + url);
  1060. loaded = 1;
  1061. }
  1062. } catch (ex) {
  1063. var exName = ex.name;
  1064. logger.debug('css poll exception: ' + exName + ' ' + ex.code + ' ' + url);
  1065. // http://www.w3.org/TR/dom/#dom-domexception-code
  1066. if (// exName == 'SecurityError' ||
  1067. // for old firefox
  1068. exName === 'NS_ERROR_DOM_SECURITY_ERR') {
  1069. logger.debug('css poll exception: ' + exName + 'loaded : ' + url);
  1070. loaded = 1;
  1071. }
  1072. }
  1073. }
  1074. return loaded;
  1075. }
  1076. // single thread is ok
  1077. function cssPoll() {
  1078. for (var url in monitors) {
  1079. var callbackObj = monitors[url],
  1080. node = callbackObj.node;
  1081. if (isCssLoaded(node, url)) {
  1082. if (callbackObj.callback) {
  1083. callbackObj.callback.call(node);
  1084. }
  1085. delete monitors[url];
  1086. }
  1087. }
  1088. if (Utils.isEmptyObject(monitors)) {
  1089. logger.debug('clear css poll timer');
  1090. timer = 0;
  1091. } else {
  1092. timer = setTimeout(cssPoll, CSS_POLL_INTERVAL);
  1093. }
  1094. }
  1095. // refer : http://lifesinger.org/lab/2011/load-js-css/css-preload.html
  1096. // 暂时不考虑如何判断失败,如 404 等
  1097. Utils.pollCss = function (node, callback) {
  1098. var href = node.href,
  1099. arr;
  1100. arr = monitors[href] = {};
  1101. arr.node = node;
  1102. arr.callback = callback;
  1103. startCssTimer();
  1104. };
  1105. Utils.isCssLoaded = isCssLoaded;
  1106. })(KISSY);
  1107. /*
  1108. References:
  1109. - http://unixpapa.com/js/dyna.html
  1110. - http://www.blaze.io/technical/ies-premature-execution-problem/
  1111. `onload` event is supported in WebKit since 535.23
  1112. - https://bugs.webkit.org/show_activity.cgi?id=38995
  1113. `onload/onerror` event is supported since Firefox 9.0
  1114. - https://bugzilla.mozilla.org/show_bug.cgi?id=185236
  1115. - https://developer.mozilla.org/en/HTML/Element/link#Stylesheet_load_events
  1116. monitor css onload across browsers.issue about 404 failure.
  1117. - firefox not ok(4 is wrong):
  1118. - http://yearofmoo.com/2011/03/cross-browser-stylesheet-preloading/
  1119. - all is ok
  1120. - http://lifesinger.org/lab/2011/load-js-css/css-preload.html
  1121. - others
  1122. - http://www.zachleat.com/web/load-css-dynamically/
  1123. *//**
  1124. * @ignore
  1125. * getScript support for css and js callback after load
  1126. * @author yiminghe@gmail.com
  1127. */
  1128. (function (S) {
  1129. // --no-module-wrap--
  1130. var MILLISECONDS_OF_SECOND = 1000,
  1131. win = S.Env.host,
  1132. doc = win.document,
  1133. Utils = S.Loader.Utils,
  1134. // solve concurrent requesting same script file
  1135. jsCssCallbacks = {},
  1136. webkit = Utils.webkit,
  1137. headNode;
  1138. /**
  1139. * Load a javascript/css file from the server using a GET HTTP request,
  1140. * then execute it.
  1141. *
  1142. * for example:
  1143. * @example
  1144. * getScript(url, success, charset);
  1145. * // or
  1146. * getScript(url, {
  1147. * charset: string
  1148. * success: fn,
  1149. * error: fn,
  1150. * timeout: number
  1151. * });
  1152. *
  1153. * Note 404/500 status in ie<9 will trigger success callback.
  1154. * If you want a jsonp operation, please use {@link KISSY.IO} instead.
  1155. *
  1156. * @param {String} url resource's url
  1157. * @param {Function|Object} [success] success callback or config
  1158. * @param {Function} [success.success] success callback
  1159. * @param {Function} [success.error] error callback
  1160. * @param {Number} [success.timeout] timeout (s)
  1161. * @param {String} [success.charset] charset of current resource
  1162. * @param {String} [charset] charset of current resource
  1163. * @return {HTMLElement} script/style node
  1164. * @member KISSY
  1165. */
  1166. S.getScript = function (url, success, charset) {
  1167. // can not use KISSY.Uri, url can not be encoded for some url
  1168. // eg: /??dom.js,event.js , ? , should not be encoded
  1169. var config = success,
  1170. css = Utils.endsWith(url, '.css'),
  1171. error, timeout, attrs, callbacks, timer;
  1172. if (typeof config === 'object') {
  1173. success = config.success;
  1174. error = config.error;
  1175. timeout = config.timeout;
  1176. charset = config.charset;
  1177. attrs = config.attrs;
  1178. }
  1179. if (css && Utils.ieMode < 10) {
  1180. if (doc.getElementsByTagName('style').length + doc.getElementsByTagName('link').length >= 31) {
  1181. if (win.console) {
  1182. win.console.error('style and link\'s number is more than 31.' +
  1183. 'ie < 10 can not insert link: ' + url);
  1184. }
  1185. if (error) {
  1186. error();
  1187. }
  1188. return;
  1189. }
  1190. }
  1191. callbacks = jsCssCallbacks[url] = jsCssCallbacks[url] || [];
  1192. callbacks.push([success, error]);
  1193. if (callbacks.length > 1) {
  1194. return callbacks.node;
  1195. }
  1196. var node = doc.createElement(css ? 'link' : 'script'),
  1197. clearTimer = function () {
  1198. if (timer) {
  1199. clearTimeout(timer);
  1200. timer = undefined;
  1201. }
  1202. };
  1203. if (attrs) {
  1204. Utils.each(attrs, function (v, n) {
  1205. node.setAttribute(n, v);
  1206. });
  1207. }
  1208. if (charset) {
  1209. node.charset = charset;
  1210. }
  1211. if (css) {
  1212. node.href = url;
  1213. node.rel = 'stylesheet';
  1214. // set media to something non-matching to ensure it'll fetch without blocking render
  1215. node.media = 'async';
  1216. } else {
  1217. node.src = url;
  1218. node.async = true;
  1219. }
  1220. callbacks.node = node;
  1221. var end = function (error) {
  1222. var index = error,
  1223. fn;
  1224. clearTimer();
  1225. // set media back to `all` so that the stylesheet applies once it loads
  1226. // https://github.com/filamentgroup/loadCSS
  1227. if (css) {
  1228. node.media = 'all';
  1229. }
  1230. Utils.each(jsCssCallbacks[url], function (callback) {
  1231. if ((fn = callback[index])) {
  1232. fn.call(node);
  1233. }
  1234. });
  1235. delete jsCssCallbacks[url];
  1236. };
  1237. var useNative = 'onload' in node;
  1238. // onload for webkit 535.23 Firefox 9.0
  1239. // https://bugs.webkit.org/show_activity.cgi?id=38995
  1240. // https://bugzilla.mozilla.org/show_bug.cgi?id=185236
  1241. // https://developer.mozilla.org/en/HTML/Element/link#Stylesheet_load_events
  1242. // phantomjs 1.7 == webkit 534.34
  1243. var forceCssPoll = S.Config.forceCssPoll ||
  1244. (webkit && webkit < 536) ||
  1245. // unknown browser defaults to css poll
  1246. // https://github.com/kissyteam/kissy/issues/607
  1247. (!webkit && !Utils.trident && !Utils.gecko);
  1248. if (css && forceCssPoll && useNative) {
  1249. useNative = false;
  1250. }
  1251. function onload() {
  1252. var readyState = node.readyState;
  1253. if (!readyState ||
  1254. readyState === 'loaded' ||
  1255. readyState === 'complete') {
  1256. node.onreadystatechange = node.onload = null;
  1257. end(0);
  1258. }
  1259. }
  1260. //标准浏览器 css and all script
  1261. if (useNative) {
  1262. node.onload = onload;
  1263. node.onerror = function () {
  1264. node.onerror = null;
  1265. end(1);
  1266. };
  1267. } else if (css) {
  1268. // old chrome/firefox for css
  1269. Utils.pollCss(node, function () {
  1270. end(0);
  1271. });
  1272. } else {
  1273. node.onreadystatechange = onload;
  1274. }
  1275. if (timeout) {
  1276. timer = setTimeout(function () {
  1277. end(1);
  1278. }, timeout * MILLISECONDS_OF_SECOND);
  1279. }
  1280. if (!headNode) {
  1281. headNode = Utils.docHead();
  1282. }
  1283. if (css) {
  1284. // css order matters
  1285. // so can not use css in head
  1286. headNode.appendChild(node);
  1287. } else {
  1288. // can use js in head
  1289. headNode.insertBefore(node, headNode.firstChild);
  1290. }
  1291. return node;
  1292. };
  1293. })(KISSY);
  1294. /*
  1295. yiminghe@gmail.com refactor@2012-03-29
  1296. - 考虑连续重复请求单个 script 的情况,内部排队
  1297. yiminghe@gmail.com 2012-03-13
  1298. - getScript
  1299. - 404 in ie<9 trigger success , others trigger error
  1300. - syntax error in all trigger success
  1301. *//**
  1302. * @ignore
  1303. * Declare config info for KISSY.
  1304. * @author yiminghe@gmail.com
  1305. */
  1306. (function (S) {
  1307. // --no-module-wrap--
  1308. var Loader = S.Loader,
  1309. Package = Loader.Package,
  1310. Utils = Loader.Utils,
  1311. host = S.Env.host,
  1312. Config = S.Config,
  1313. location = host.location,
  1314. configFns = Config.fns;
  1315. // how to load mods by path
  1316. Config.loadModsFn = function (rs, config) {
  1317. S.getScript(rs.url, config);
  1318. };
  1319. // how to get mod url
  1320. Config.resolveModFn = function (mod) {
  1321. var name = mod.name,
  1322. filter, t, url,
  1323. // deprecated! do not use path config
  1324. subPath = mod.path;
  1325. var packageInfo = mod.getPackage();
  1326. if (!packageInfo) {
  1327. return name;
  1328. }
  1329. var packageBase = packageInfo.getBase();
  1330. var packageName = packageInfo.name;
  1331. var extname = mod.getType();
  1332. var suffix = '.' + extname;
  1333. if (!subPath) {
  1334. // special for css module
  1335. name = name.replace(/\.css$/, '');
  1336. filter = packageInfo.getFilter() || '';
  1337. if (typeof filter === 'function') {
  1338. subPath = filter(name, extname);
  1339. } else if (typeof filter === 'string') {
  1340. if (filter) {
  1341. filter = '-' + filter;
  1342. }
  1343. subPath = name + filter + suffix;
  1344. }
  1345. }
  1346. // core package
  1347. if (packageName === 'core') {
  1348. url = packageBase + subPath;
  1349. } else if (name === packageName) {
  1350. // packageName: a/y use('a/y');
  1351. // do not use this on production, can not be combo ed with other modules from same package
  1352. url = packageBase.substring(0, packageBase.length - 1) + filter + suffix;
  1353. } else {
  1354. subPath = subPath.substring(packageName.length + 1);
  1355. url = packageBase + subPath;
  1356. }
  1357. if ((t = mod.getTag())) {
  1358. t += suffix;
  1359. url += '?t=' + t;
  1360. }
  1361. return url;
  1362. };
  1363. configFns.requires = shortcut('requires');
  1364. configFns.alias = shortcut('alias');
  1365. configFns.packages = function (config) {
  1366. var Config = this.Config,
  1367. packages = Config.packages;
  1368. if (config) {
  1369. Utils.each(config, function (cfg, key) {
  1370. // object type
  1371. var name = cfg.name = cfg.name || key;
  1372. var base = cfg.base || cfg.path;
  1373. if (base) {
  1374. cfg.base = normalizePath(base, true);
  1375. }
  1376. if (packages[name]) {
  1377. packages[name].reset(cfg);
  1378. } else {
  1379. packages[name] = new Package(cfg);
  1380. }
  1381. });
  1382. return undefined;
  1383. } else if (config === false) {
  1384. Config.packages = {
  1385. core: packages.core
  1386. };
  1387. return undefined;
  1388. } else {
  1389. return packages;
  1390. }
  1391. };
  1392. configFns.modules = function (modules) {
  1393. if (modules) {
  1394. Utils.each(modules, function (modCfg, modName) {
  1395. var url = modCfg.url;
  1396. if (url) {
  1397. modCfg.url = normalizePath(url);
  1398. }
  1399. var mod = Utils.createModule(modName, modCfg);
  1400. // #485, invalid after add
  1401. if (mod.status === Loader.Status.INIT) {
  1402. Utils.mix(mod, modCfg);
  1403. }
  1404. });
  1405. }
  1406. };
  1407. configFns.base = function (base) {
  1408. var self = this,
  1409. corePackage = Config.packages.core;
  1410. if (!base) {
  1411. return corePackage && corePackage.getBase();
  1412. }
  1413. self.config('packages', {
  1414. core: {
  1415. base: base
  1416. }
  1417. });
  1418. return undefined;
  1419. };
  1420. function shortcut(attr) {
  1421. return function (config) {
  1422. var newCfg = {};
  1423. for (var name in config) {
  1424. newCfg[name] = {};
  1425. newCfg[name][attr] = config[name];
  1426. }
  1427. S.config('modules', newCfg);
  1428. };
  1429. }
  1430. function normalizePath(base, isDirectory) {
  1431. base = Utils.normalizeSlash(base);
  1432. if (isDirectory && base.charAt(base.length - 1) !== '/') {
  1433. base += '/';
  1434. }
  1435. if (location) {
  1436. if (Utils.startsWith(base, 'http:') ||
  1437. Utils.startsWith(base, 'https:') ||
  1438. Utils.startsWith(base, 'file:')) {
  1439. return base;
  1440. }
  1441. base = location.protocol + '//' + location.host + Utils.normalizePath(location.pathname, base);
  1442. }
  1443. return base;
  1444. }
  1445. })(KISSY);
  1446. /**
  1447. * combo loader for KISSY. using combo to load module files.
  1448. * @ignore
  1449. * @author yiminghe@gmail.com
  1450. */
  1451. (function (S, undefined) {
  1452. // --no-module-wrap--
  1453. var logger = S.getLogger('s/loader');
  1454. var Loader = S.Loader,
  1455. Config = S.Config,
  1456. Status = Loader.Status,
  1457. Utils = Loader.Utils,
  1458. addModule = Utils.addModule,
  1459. each = Utils.each,
  1460. getHash = Utils.getHash,
  1461. LOADING = Status.LOADING,
  1462. LOADED = Status.LOADED,
  1463. ERROR = Status.ERROR,
  1464. oldIE = Utils.ieMode && Utils.ieMode < 10;
  1465. function loadScripts(rss, callback, timeout) {
  1466. var count = rss && rss.length,
  1467. errorList = [],
  1468. successList = [];
  1469. function complete() {
  1470. if (!(--count)) {
  1471. callback(successList, errorList);
  1472. }
  1473. }
  1474. each(rss, function (rs) {
  1475. var mod;
  1476. var config = {
  1477. timeout: timeout,
  1478. success: function () {
  1479. successList.push(rs);
  1480. if (mod && currentMod) {
  1481. // standard browser(except ie9) fire load after KISSY.add immediately
  1482. logger.debug('standard browser get mod name after load: ' + mod.name);
  1483. addModule(mod.name, currentMod.factory, currentMod.config);
  1484. currentMod = undefined;
  1485. }
  1486. complete();
  1487. },
  1488. error: function () {
  1489. errorList.push(rs);
  1490. complete();
  1491. },
  1492. charset: rs.charset
  1493. };
  1494. if (!rs.combine) {
  1495. mod = rs.mods[0];
  1496. if (mod.getType() === 'css') {
  1497. mod = undefined;
  1498. } else if (oldIE) {
  1499. startLoadModName = mod.name;
  1500. if ('@DEBUG@') {
  1501. startLoadModTime = +new Date();
  1502. }
  1503. config.attrs = {
  1504. 'data-mod-name': mod.name
  1505. };
  1506. }
  1507. }
  1508. Config.loadModsFn(rs, config);
  1509. });
  1510. }
  1511. var loaderId = 0;
  1512. /**
  1513. * @class KISSY.Loader.ComboLoader
  1514. * using combo to load module files
  1515. * @param callback
  1516. * @private
  1517. */
  1518. function ComboLoader(callback) {
  1519. this.callback = callback;
  1520. this.head = this.tail = undefined;
  1521. this.id = 'loader' + (++loaderId);
  1522. }
  1523. var currentMod;
  1524. var startLoadModName;
  1525. var startLoadModTime;
  1526. function checkKISSYRequire(config, factory) {
  1527. // use require primitive statement
  1528. // function(S, require){ require('node') }
  1529. if (!config && typeof factory === 'function' && factory.length > 1) {
  1530. var requires = Utils.getRequiresFromFn(factory);
  1531. if (requires.length) {
  1532. config = config || {};
  1533. config.requires = requires;
  1534. }
  1535. } else {
  1536. // KISSY.add(function(){},{requires:[]})
  1537. if (config && config.requires && !config.cjs) {
  1538. config.cjs = 0;
  1539. }
  1540. }
  1541. return config;
  1542. }
  1543. ComboLoader.add = function (name, factory, config, argsLen) {
  1544. // KISSY.add('xx',[],function(){});
  1545. if (argsLen === 3 && Utils.isArray(factory)) {
  1546. var tmp = factory;
  1547. factory = config;
  1548. config = {
  1549. requires: tmp,
  1550. cjs: 1
  1551. };
  1552. }
  1553. // KISSY.add(function(){}), KISSY.add('a'), KISSY.add(function(){},{requires:[]})
  1554. if (typeof name === 'function' || argsLen === 1) {
  1555. config = factory;
  1556. factory = name;
  1557. config = checkKISSYRequire(config, factory);
  1558. if (oldIE) {
  1559. // http://groups.google.com/group/commonjs/browse_thread/thread/5a3358ece35e688e/43145ceccfb1dc02#43145ceccfb1dc02
  1560. name = findModuleNameByInteractive();
  1561. // S.log('oldIE get modName by interactive: ' + name);
  1562. addModule(name, factory, config);
  1563. startLoadModName = null;
  1564. startLoadModTime = 0;
  1565. } else {
  1566. // standard browser associates name with definition when onload
  1567. currentMod = {
  1568. factory: factory,
  1569. config: config
  1570. };
  1571. }
  1572. } else {
  1573. // KISSY.add('x',function(){},{requires:[]})
  1574. if (oldIE) {
  1575. startLoadModName = null;
  1576. startLoadModTime = 0;
  1577. } else {
  1578. currentMod = undefined;
  1579. }
  1580. config = checkKISSYRequire(config, factory);
  1581. addModule(name, factory, config);
  1582. }
  1583. };
  1584. function findModuleNameByInteractive() {
  1585. var scripts = document.getElementsByTagName('script'),
  1586. re, i, name, script;
  1587. for (i = scripts.length - 1; i >= 0; i--) {
  1588. script = scripts[i];
  1589. if (script.readyState === 'interactive') {
  1590. re = script;
  1591. break;
  1592. }
  1593. }
  1594. if (re) {
  1595. name = re.getAttribute('data-mod-name');
  1596. } else {
  1597. // sometimes when read module file from cache,
  1598. // interactive status is not triggered
  1599. // module code is executed right after inserting into dom
  1600. // i has to preserve module name before insert module script into dom,
  1601. // then get it back here
  1602. logger.debug('can not find interactive script,time diff : ' + (+new Date() - startLoadModTime));
  1603. logger.debug('old_ie get mod name from cache : ' + startLoadModName);
  1604. name = startLoadModName;
  1605. }
  1606. return name;
  1607. }
  1608. var debugRemoteModules;
  1609. if ('@DEBUG@') {
  1610. debugRemoteModules = function (rss) {
  1611. each(rss, function (rs) {
  1612. var ms = [];
  1613. each(rs.mods, function (m) {
  1614. if (m.status === LOADED) {
  1615. ms.push(m.name);
  1616. }
  1617. });
  1618. if (ms.length) {
  1619. logger.info('load remote modules: "' + ms.join(', ') + '" from: "' + rs.url + '"');
  1620. }
  1621. });
  1622. };
  1623. }
  1624. function getCommonPathPrefix(str1, str2) {
  1625. // ie bug
  1626. // 'a//b'.split(/\//) => [a,b]
  1627. var protocolIndex = str1.indexOf('//');
  1628. var prefix = '';
  1629. if (protocolIndex !== -1) {
  1630. prefix = str1.substring(0, str1.indexOf('//') + 2);
  1631. }
  1632. str1 = str1.substring(prefix.length).split(/\//);
  1633. str2 = str2.substring(prefix.length).split(/\//);
  1634. var l = Math.min(str1.length, str2.length);
  1635. for (var i = 0; i < l; i++) {
  1636. if (str1[i] !== str2[i]) {
  1637. break;
  1638. }
  1639. }
  1640. return prefix + str1.slice(0, i).join('/') + '/';
  1641. }
  1642. // ??editor/plugin/x,editor/plugin/b
  1643. // =>
  1644. // editor/plugin/??x,b
  1645. function getUrlConsiderCommonPrefix(commonPrefix, currentComboUrls, basePrefix, comboPrefix, comboSep, suffix) {
  1646. if (commonPrefix && currentComboUrls.length > 1) {
  1647. var commonPrefixLen = commonPrefix.length;
  1648. var currentUrls = [];
  1649. for (var i = 0; i < currentComboUrls.length; i++) {
  1650. currentUrls[i] = currentComboUrls[i].substring(commonPrefixLen);
  1651. }
  1652. return basePrefix + commonPrefix + comboPrefix + currentUrls.join(comboSep) + suffix;
  1653. } else {
  1654. return basePrefix + comboPrefix + currentComboUrls.join(comboSep) + suffix;
  1655. }
  1656. }
  1657. Utils.mix(ComboLoader.prototype, {
  1658. /**
  1659. * load modules asynchronously
  1660. */
  1661. use: function (allMods) {
  1662. var self = this,
  1663. comboUrls,
  1664. timeout = Config.timeout;
  1665. comboUrls = self.getComboUrls(allMods);
  1666. // load css first to avoid page blink
  1667. if (comboUrls.css) {
  1668. loadScripts(comboUrls.css, function (success, error) {
  1669. if ('@DEBUG@') {
  1670. debugRemoteModules(success);
  1671. }
  1672. each(success, function (one) {
  1673. each(one.mods, function (mod) {
  1674. addModule(mod.name, Utils.noop);
  1675. // notify all loader instance
  1676. mod.flush();
  1677. });
  1678. });
  1679. each(error, function (one) {
  1680. each(one.mods, function (mod) {
  1681. var msg = mod.name + ' is not loaded! can not find module in url: ' + one.url;
  1682. S.log(msg, 'error');
  1683. mod.status = ERROR;
  1684. // notify all loader instance
  1685. mod.flush();
  1686. });
  1687. });
  1688. }, timeout);
  1689. }
  1690. // jss css download in parallel
  1691. if (comboUrls.js) {
  1692. loadScripts(comboUrls.js, function (success) {
  1693. if ('@DEBUG@') {
  1694. debugRemoteModules(success);
  1695. }
  1696. each(comboUrls.js, function (one) {
  1697. each(one.mods, function (mod) {
  1698. // fix #111
  1699. // https://github.com/kissyteam/kissy/issues/111
  1700. if (!mod.factory) {
  1701. var msg = mod.name +
  1702. ' is not loaded! can not find module in url: ' +
  1703. one.url;
  1704. S.log(msg, 'error');
  1705. mod.status = ERROR;
  1706. }
  1707. // notify all loader instance
  1708. mod.flush();
  1709. });
  1710. });
  1711. }, timeout);
  1712. }
  1713. },
  1714. /**
  1715. * calculate dependency
  1716. */
  1717. calculate: function (unloadedMods, errorList, stack, cache, ret) {
  1718. var i, m, mod, modStatus,
  1719. stackDepth,
  1720. self = this;
  1721. if ('@DEBUG@') {
  1722. stack = stack || [];
  1723. }
  1724. ret = ret || [];
  1725. // 提高性能,不用每个模块都再次全部依赖计算
  1726. // 做个缓存,每个模块对应的待动态加载模块
  1727. cache = cache || {};
  1728. for (i = 0; i < unloadedMods.length; i++) {
  1729. mod = unloadedMods[i];
  1730. m = mod.name;
  1731. if (cache[m]) {
  1732. continue;
  1733. }
  1734. if ('@DEBUG@') {
  1735. stackDepth = stack.length;
  1736. }
  1737. modStatus = mod.status;
  1738. if (modStatus === ERROR) {
  1739. errorList.push(mod);
  1740. cache[m] = 1;
  1741. continue;
  1742. }
  1743. if (modStatus > LOADED) {
  1744. cache[m] = 1;
  1745. continue;
  1746. } else if (modStatus !== LOADED && !mod.contains(self)) {
  1747. if (modStatus !== LOADING) {
  1748. mod.status = LOADING;
  1749. ret.push(mod);
  1750. }
  1751. mod.add(self);
  1752. self.wait(mod);
  1753. }
  1754. if ('@DEBUG@') {
  1755. // do not use indexOf, poor performance in ie8
  1756. if (stack[m]) {
  1757. S.log('find cyclic dependency between mods: ' + stack, 'warn');
  1758. cache[m] = 1;
  1759. continue;
  1760. } else {
  1761. stack[m] = 1;
  1762. stack.push(m);
  1763. }
  1764. }
  1765. self.calculate(mod.getNormalizedRequiredModules(), errorList, stack, cache, ret);
  1766. cache[m] = 1;
  1767. if ('@DEBUG@') {
  1768. for (var si = stackDepth; si < stack.length; si++) {
  1769. stack[stack[si]] = 0;
  1770. }
  1771. stack.length = stackDepth;
  1772. }
  1773. }
  1774. return ret;
  1775. },
  1776. /**
  1777. * get combo mods for modNames
  1778. */
  1779. getComboMods: function (mods) {
  1780. var i, l = mods.length,
  1781. tmpMods, mod, packageInfo, type,
  1782. tag, charset, packageBase,
  1783. packageName, group, modUrl;
  1784. var groups = {
  1785. /*
  1786. js: {
  1787. 'groupA-gbk':{
  1788. 'http://x.com':[m1,m2]
  1789. }
  1790. }
  1791. */
  1792. };
  1793. var normals = {
  1794. /*
  1795. js:{
  1796. 'http://x.com':[m1,m2]
  1797. }
  1798. */
  1799. };
  1800. for (i = 0; i < l; ++i) {
  1801. mod = mods[i];
  1802. type = mod.getType();
  1803. modUrl = mod.getUrl();
  1804. packageInfo = mod.getPackage();
  1805. if (packageInfo) {
  1806. packageBase = packageInfo.getBase();
  1807. packageName = packageInfo.name;
  1808. charset = packageInfo.getCharset();
  1809. tag = packageInfo.getTag();
  1810. group = packageInfo.getGroup();
  1811. } else {
  1812. packageBase = mod.name;
  1813. }
  1814. if (packageInfo && packageInfo.isCombine() && group) {
  1815. var typeGroups = groups[type] || (groups[type] = {});
  1816. group = group + '-' + charset;
  1817. var typeGroup = typeGroups[group] || (typeGroups[group] = {});
  1818. var find = 0;
  1819. /*jshint loopfunc:true*/
  1820. Utils.each(typeGroup, function (tmpMods, prefix) {
  1821. if (Utils.isSameOriginAs(prefix, packageBase)) {
  1822. var newPrefix = getCommonPathPrefix(prefix, packageBase);
  1823. tmpMods.push(mod);
  1824. if (tag && tag !== tmpMods.tag) {
  1825. tmpMods.tag = getHash(tmpMods.tag + tag);
  1826. }
  1827. delete typeGroup[prefix];
  1828. typeGroup[newPrefix] = tmpMods;
  1829. find = 1;
  1830. }
  1831. });
  1832. if (!find) {
  1833. tmpMods = typeGroup[packageBase] = [mod];
  1834. tmpMods.charset = charset;
  1835. tmpMods.tag = tag || '';
  1836. }
  1837. } else {
  1838. var normalTypes = normals[type] || (normals[type] = {});
  1839. if (!(tmpMods = normalTypes[packageBase])) {
  1840. tmpMods = normalTypes[packageBase] = [];
  1841. tmpMods.charset = charset;
  1842. tmpMods.tag = tag || '';
  1843. } else {
  1844. if (tag && tag !== tmpMods.tag) {
  1845. tmpMods.tag = getHash(tmpMods.tag + tag);
  1846. }
  1847. }
  1848. tmpMods.push(mod);
  1849. }
  1850. }
  1851. return {
  1852. groups: groups,
  1853. normals: normals
  1854. };
  1855. },
  1856. /**
  1857. * Get combo urls
  1858. */
  1859. getComboUrls: function (mods) {
  1860. var comboPrefix = Config.comboPrefix,
  1861. comboSep = Config.comboSep,
  1862. comboRes = {},
  1863. maxFileNum = Config.comboMaxFileNum,
  1864. maxUrlLength = Config.comboMaxUrlLength;
  1865. var comboMods = this.getComboMods(mods);
  1866. function processSamePrefixUrlMods(type, basePrefix, sendMods) {
  1867. var currentComboUrls = [];
  1868. var currentComboMods = [];
  1869. var tag = sendMods.tag;
  1870. var charset = sendMods.charset;
  1871. var suffix = (tag ? '?t=' + encodeURIComponent(tag) + '.' + type : '');
  1872. var baseLen = basePrefix.length,
  1873. commonPrefix,
  1874. res = [];
  1875. /*jshint loopfunc:true*/
  1876. function pushComboUrl(sentUrl) {
  1877. //noinspection JSReferencingMutableVariableFromClosure
  1878. res.push({
  1879. combine: 1,
  1880. url: sentUrl,
  1881. charset: charset,
  1882. mods: currentComboMods
  1883. });
  1884. }
  1885. function getSentUrl() {
  1886. return getUrlConsiderCommonPrefix(commonPrefix, currentComboUrls,
  1887. basePrefix, comboPrefix, comboSep, suffix);
  1888. }
  1889. for (var i = 0; i < sendMods.length; i++) {
  1890. var currentMod = sendMods[i];
  1891. var url = currentMod.getUrl();
  1892. if (!currentMod.getPackage() || !currentMod.getPackage().isCombine() ||
  1893. // use(x/y) packageName: x/y ...
  1894. !Utils.startsWith(url, basePrefix)) {
  1895. res.push({
  1896. combine: 0,
  1897. url: url,
  1898. charset: charset,
  1899. mods: [currentMod]
  1900. });
  1901. continue;
  1902. }
  1903. // ignore query parameter
  1904. var subPath = url.slice(baseLen).replace(/\?.*$/, '');
  1905. currentComboUrls.push(subPath);
  1906. currentComboMods.push(currentMod);
  1907. if (commonPrefix === undefined) {
  1908. commonPrefix = subPath.indexOf('/') !== -1 ? subPath : '';
  1909. } else if (commonPrefix !== '') {
  1910. commonPrefix = getCommonPathPrefix(commonPrefix, subPath);
  1911. if (commonPrefix === '/') {
  1912. commonPrefix = '';
  1913. }
  1914. }
  1915. if (currentComboUrls.length > maxFileNum || getSentUrl().length > maxUrlLength) {
  1916. currentComboUrls.pop();
  1917. currentComboMods.pop();
  1918. pushComboUrl(getSentUrl());
  1919. currentComboUrls = [];
  1920. currentComboMods = [];
  1921. commonPrefix = undefined;
  1922. i--;
  1923. }
  1924. }
  1925. if (currentComboUrls.length) {
  1926. pushComboUrl(getSentUrl());
  1927. }
  1928. comboRes[type].push.apply(comboRes[type], res);
  1929. }
  1930. var type, prefix;
  1931. var normals = comboMods.normals;
  1932. var groups = comboMods.groups;
  1933. var group;
  1934. // generate combo urls
  1935. for (type in normals) {
  1936. comboRes[type] = comboRes[type] || [];
  1937. for (prefix in normals[type]) {
  1938. processSamePrefixUrlMods(type, prefix, normals[type][prefix]);
  1939. }
  1940. }
  1941. for (type in groups) {
  1942. comboRes[type] = comboRes[type] || [];
  1943. for (group in groups[type]) {
  1944. for (prefix in groups[type][group]) {
  1945. processSamePrefixUrlMods(type, prefix, groups[type][group][prefix]);
  1946. }
  1947. }
  1948. }
  1949. return comboRes;
  1950. },
  1951. flush: function () {
  1952. if (!this.callback) {
  1953. return;
  1954. }
  1955. var self = this,
  1956. head = self.head,
  1957. callback = self.callback;
  1958. while (head) {
  1959. var node = head.node,
  1960. status = node.status;
  1961. if (status >= LOADED || status === ERROR) {
  1962. node.remove(self);
  1963. head = self.head = head.next;
  1964. } else {
  1965. return;
  1966. }
  1967. }
  1968. self.callback = null;
  1969. callback();
  1970. },
  1971. isCompleteLoading: function () {
  1972. return !this.head;
  1973. },
  1974. wait: function (mod) {
  1975. var self = this;
  1976. if (!self.head) {
  1977. self.tail = self.head = {
  1978. node: mod
  1979. };
  1980. } else {
  1981. var newNode = {
  1982. node: mod
  1983. };
  1984. self.tail.next = newNode;
  1985. self.tail = newNode;
  1986. }
  1987. }
  1988. });
  1989. Loader.ComboLoader = ComboLoader;
  1990. })(KISSY);
  1991. /*
  1992. 2014-03-24 yiminghe@gmail.com
  1993. - refactor group combo logic
  1994. 2014-01-14 yiminghe@gmail.com
  1995. - support System.ondemand from es6
  1996. 2013-09-11 yiminghe@gmail.com
  1997. - unify simple loader and combo loader
  1998. 2013-07-25 阿古, yiminghe@gmail.com
  1999. - support group combo for packages
  2000. 2013-06-04 yiminghe@gmail.com
  2001. - refactor merge combo loader and simple loader
  2002. - support error callback
  2003. 2012-02-20 yiminghe@gmail.com
  2004. - three status
  2005. 0: initialized
  2006. LOADED: load into page
  2007. ATTACHED: factory executed
  2008. *//**
  2009. * @ignore
  2010. * mix loader into KISSY and infer KISSY baseUrl if not set
  2011. * @author yiminghe@gmail.com
  2012. */
  2013. (function (S) {
  2014. // --no-module-wrap--
  2015. var Loader = S.Loader,
  2016. Utils = Loader.Utils,
  2017. createModule = Utils.createModule,
  2018. ComboLoader = Loader.ComboLoader;
  2019. var logger = S.getLogger('s/loader');
  2020. Utils.mix(S, {
  2021. // internal usage
  2022. getModule: function (modName) {
  2023. return createModule(modName);
  2024. },
  2025. // internal usage
  2026. getPackage: function (packageName) {
  2027. return S.Config.packages[packageName];
  2028. },
  2029. /**
  2030. * Registers a module with the KISSY global.
  2031. * @param {String} name module name.
  2032. * it must be set if combine is true in {@link KISSY#config}
  2033. * @param {Function} factory module definition function that is used to return
  2034. * exports of this module
  2035. * @param {KISSY} factory.S KISSY global instance
  2036. * @param {Object} [cfg] module optional config data
  2037. * @param {String[]} cfg.requires this module's required module name list
  2038. * @member KISSY
  2039. *
  2040. *
  2041. * // dom module's definition
  2042. * KISSY.add('dom', function(S, xx){
  2043. * return {css: function(el, name, val){}};
  2044. * },{
  2045. * requires:['xx']
  2046. * });
  2047. */
  2048. add: function (name, factory, cfg) {
  2049. ComboLoader.add(name, factory, cfg, arguments.length);
  2050. },
  2051. /**
  2052. * Attached one or more modules to global KISSY instance.
  2053. * @param {String|String[]} modNames moduleNames. 1-n modules to bind(use comma to separate)
  2054. * @param {Function} success callback function executed
  2055. * when KISSY has the required functionality.
  2056. * @param {KISSY} success.S KISSY instance
  2057. * @param success.x... modules exports
  2058. * @member KISSY
  2059. *
  2060. *
  2061. * // loads and attached overlay,dd and its dependencies
  2062. * KISSY.use('overlay,dd', function(S, Overlay){});
  2063. */
  2064. use: function (modNames, success) {
  2065. var loader,
  2066. error,
  2067. tryCount = 0;
  2068. if (typeof modNames === 'string') {
  2069. S.log('KISSY.use\'s first argument should be Array, but now: ' + modNames, 'warning');
  2070. modNames = modNames.replace(/\s+/g, '').split(',');
  2071. }
  2072. if (typeof success === 'object') {
  2073. //noinspection JSUnresolvedVariable
  2074. error = success.error;
  2075. //noinspection JSUnresolvedVariable
  2076. success = success.success;
  2077. }
  2078. var mods = Utils.createModules(modNames);
  2079. var unloadedMods = [];
  2080. Utils.each(mods, function (mod) {
  2081. unloadedMods.push.apply(unloadedMods, mod.getNormalizedModules());
  2082. });
  2083. var normalizedMods = unloadedMods;
  2084. function loadReady() {
  2085. ++tryCount;
  2086. var errorList = [],
  2087. start;
  2088. if ('@DEBUG@') {
  2089. start = +new Date();
  2090. }
  2091. unloadedMods = loader.calculate(unloadedMods, errorList);
  2092. var unloadModsLen = unloadedMods.length;
  2093. logger.debug(tryCount + ' check duration ' + (+new Date() - start));
  2094. if (errorList.length) {
  2095. if (error) {
  2096. try {
  2097. error.apply(S, errorList);
  2098. } catch (e) {
  2099. S.log(e.stack || e, 'error');
  2100. /*jshint loopfunc:true*/
  2101. setTimeout(function () {
  2102. throw e;
  2103. }, 0);
  2104. }
  2105. }
  2106. S.log(errorList, 'error');
  2107. S.log('loader: load above modules error', 'error');
  2108. } else if (loader.isCompleteLoading()) {
  2109. Utils.attachModules(normalizedMods);
  2110. if (success) {
  2111. if ('@DEBUG@') {
  2112. success.apply(S, [S].concat(Utils.getModulesExports(mods)));
  2113. } else {
  2114. try {
  2115. success.apply(S, [S].concat(Utils.getModulesExports(mods)));
  2116. } catch (e) {
  2117. /*jshint loopfunc:true*/
  2118. setTimeout(function () {
  2119. throw e;
  2120. }, 0);
  2121. }
  2122. }
  2123. }
  2124. } else {
  2125. // in case all of its required mods is loading by other loaders
  2126. loader.callback = loadReady;
  2127. if (unloadModsLen) {
  2128. logger.debug(tryCount + ' reload ');
  2129. loader.use(unloadedMods);
  2130. }
  2131. }
  2132. }
  2133. loader = new ComboLoader(loadReady);
  2134. // in case modules is loaded statically
  2135. // synchronous check
  2136. // but always async for loader
  2137. loadReady();
  2138. return S;
  2139. },
  2140. /**
  2141. * get module exports from KISSY module cache
  2142. * @param {String} moduleName module name
  2143. * @member KISSY
  2144. * @return {*} exports of specified module
  2145. */
  2146. require: function (moduleName) {
  2147. var requiresModule = createModule(moduleName);
  2148. return requiresModule.getExports();
  2149. },
  2150. /**
  2151. * undefine a module
  2152. * @param {String} moduleName module name
  2153. * @member KISSY
  2154. */
  2155. undef: function (moduleName) {
  2156. var requiresModule = createModule(moduleName);
  2157. var mods = requiresModule.getNormalizedModules();
  2158. Utils.each(mods, function (m) {
  2159. m.undef();
  2160. });
  2161. }
  2162. });
  2163. })(KISSY);
  2164. /*
  2165. 2013-06-04 yiminghe@gmail.com
  2166. - refactor merge combo loader and simple loader
  2167. - support error callback
  2168. *//**
  2169. * @ignore
  2170. * i18n plugin for kissy loader
  2171. * @author yiminghe@gmail.com
  2172. */
  2173. KISSY.add('i18n', {
  2174. alias: function (S, name) {
  2175. return name + '/i18n/' + S.Config.lang;
  2176. }
  2177. });/**
  2178. * @ignore
  2179. * init loader, set config
  2180. * @author yiminghe@gmail.com
  2181. */
  2182. (function (S) {
  2183. // --no-module-wrap--
  2184. var doc = S.Env.host && S.Env.host.document;
  2185. // var logger = S.getLogger('s/loader');
  2186. var Utils = S.Loader.Utils;
  2187. var TIMESTAMP = '20140701225543';
  2188. var defaultComboPrefix = '??';
  2189. var defaultComboSep = ',';
  2190. function returnJson(s) {
  2191. /*jshint evil:true*/
  2192. return (new Function('return ' + s))();
  2193. }
  2194. var baseReg = /^(.*)(seed|loader)(?:-debug|-coverage)?\.js[^/]*/i,
  2195. baseTestReg = /(seed|loader)(?:-debug|-coverage)?\.js/i;
  2196. function getBaseInfoFromOneScript(script) {
  2197. // can not use KISSY.Uri
  2198. // /??x.js,dom.js for tbcdn
  2199. var src = script.src || '';
  2200. if (!src.match(baseTestReg)) {
  2201. return 0;
  2202. }
  2203. var baseInfo = script.getAttribute('data-config');
  2204. if (baseInfo) {
  2205. baseInfo = returnJson(baseInfo);
  2206. } else {
  2207. baseInfo = {};
  2208. }
  2209. var comboPrefix = baseInfo.comboPrefix || defaultComboPrefix;
  2210. var comboSep = baseInfo.comboSep || defaultComboSep;
  2211. var parts,
  2212. base,
  2213. index = src.indexOf(comboPrefix);
  2214. // no combo
  2215. if (index === -1) {
  2216. base = src.replace(baseReg, '$1');
  2217. } else {
  2218. base = src.substring(0, index);
  2219. // a.tbcdn.cn??y.js, ie does not insert / after host
  2220. // a.tbcdn.cn/combo? comboPrefix=/combo?
  2221. if (base.charAt(base.length - 1) !== '/') {
  2222. base += '/';
  2223. }
  2224. parts = src.substring(index + comboPrefix.length).split(comboSep);
  2225. Utils.each(parts, function (part) {
  2226. if (part.match(baseTestReg)) {
  2227. base += part.replace(baseReg, '$1');
  2228. return false;
  2229. }
  2230. return undefined;
  2231. });
  2232. }
  2233. if (!('tag' in baseInfo)) {
  2234. var queryIndex = src.lastIndexOf('?t=');
  2235. if (queryIndex !== -1) {
  2236. var query = src.substring(queryIndex + 1);
  2237. // kissy 's tag will be determined by build time and user specified tag
  2238. baseInfo.tag = Utils.getHash(TIMESTAMP + query);
  2239. }
  2240. }
  2241. baseInfo.base = baseInfo.base || base;
  2242. return baseInfo;
  2243. }
  2244. /**
  2245. * get base from seed-debug.js
  2246. * @return {Object} base for kissy
  2247. * @ignore
  2248. *
  2249. * for example:
  2250. * @example
  2251. * http://a.tbcdn.cn/??s/kissy/x.y.z/seed-min.js,p/global/global.js
  2252. * note about custom combo rules, such as yui3:
  2253. * combo-prefix='combo?' combo-sep='&'
  2254. */
  2255. function getBaseInfo() {
  2256. // get base from current script file path
  2257. // notice: timestamp
  2258. var scripts = doc.getElementsByTagName('script'),
  2259. i,
  2260. info;
  2261. for (i = scripts.length - 1; i >= 0; i--) {
  2262. if ((info = getBaseInfoFromOneScript(scripts[i]))) {
  2263. return info;
  2264. }
  2265. }
  2266. var msg = 'must load kissy by file name in browser environment: ' +
  2267. 'seed-debug.js or seed.js loader.js or loader-debug.js';
  2268. S.log(msg, 'error');
  2269. return null;
  2270. }
  2271. S.config({
  2272. comboPrefix: defaultComboPrefix,
  2273. comboSep: defaultComboSep,
  2274. charset: 'utf-8',
  2275. filter: '',
  2276. lang: 'zh-cn'
  2277. });
  2278. S.config('packages', {
  2279. core: {
  2280. filter: S.Config.debug ? 'debug' : ''
  2281. }
  2282. });
  2283. // ejecta
  2284. if (doc && doc.getElementsByTagName) {
  2285. // will transform base to absolute path
  2286. S.config(Utils.mix({
  2287. // 2k(2048) url length
  2288. comboMaxUrlLength: 2000,
  2289. // file limit number for a single combo url
  2290. comboMaxFileNum: 40
  2291. }, getBaseInfo()));
  2292. }
  2293. S.add('logger-manager', function () {
  2294. return S.LoggerMangaer;
  2295. });
  2296. })(KISSY);
  2297. /*
  2298. Copyright 2014, KISSY v5.0.0
  2299. MIT Licensed
  2300. build time: Jul 1 23:09
  2301. */
  2302. /*
  2303. combined modules:
  2304. ua
  2305. */
  2306. KISSY.add('ua', [], function (S, require, exports, module) {
  2307. /**
  2308. * @ignore
  2309. * ua
  2310. */
  2311. /*global process*/
  2312. var win = typeof window !== 'undefined' ? window : {}, undef, doc = win.document, ua = win.navigator && win.navigator.userAgent || '';
  2313. function numberify(s) {
  2314. var c = 0; // convert '1.2.3.4' to 1.234
  2315. // convert '1.2.3.4' to 1.234
  2316. return parseFloat(s.replace(/\./g, function () {
  2317. return c++ === 0 ? '.' : '';
  2318. }));
  2319. }
  2320. function setTridentVersion(ua, UA) {
  2321. var core, m;
  2322. UA[core = 'trident'] = 0.1; // Trident detected, look for revision
  2323. // Get the Trident's accurate version
  2324. // Trident detected, look for revision
  2325. // Get the Trident's accurate version
  2326. if ((m = ua.match(/Trident\/([\d.]*)/)) && m[1]) {
  2327. UA[core] = numberify(m[1]);
  2328. }
  2329. UA.core = core;
  2330. }
  2331. function getIEVersion(ua) {
  2332. var m, v;
  2333. if ((m = ua.match(/MSIE ([^;]*)|Trident.*; rv(?:\s|:)?([0-9.]+)/)) && (v = m[1] || m[2])) {
  2334. return numberify(v);
  2335. }
  2336. return 0;
  2337. }
  2338. function getDescriptorFromUserAgent(ua) {
  2339. var EMPTY = '', os, core = EMPTY, shell = EMPTY, m, IE_DETECT_RANGE = [
  2340. 6,
  2341. 9
  2342. ], ieVersion, v, end, VERSION_PLACEHOLDER = '{{version}}', IE_DETECT_TPL = '<!--[if IE ' + VERSION_PLACEHOLDER + ']><' + 's></s><![endif]-->', div = doc && doc.createElement('div'), s = []; /**
  2343. * KISSY UA
  2344. * @class KISSY.UA
  2345. * @singleton
  2346. */
  2347. /**
  2348. * KISSY UA
  2349. * @class KISSY.UA
  2350. * @singleton
  2351. */
  2352. var UA = {
  2353. /**
  2354. * webkit version
  2355. * @type undef|Number
  2356. * @member KISSY.UA
  2357. */
  2358. webkit: undef,
  2359. /**
  2360. * trident version
  2361. * @type undef|Number
  2362. * @member KISSY.UA
  2363. */
  2364. trident: undef,
  2365. /**
  2366. * gecko version
  2367. * @type undef|Number
  2368. * @member KISSY.UA
  2369. */
  2370. gecko: undef,
  2371. /**
  2372. * presto version
  2373. * @type undef|Number
  2374. * @member KISSY.UA
  2375. */
  2376. presto: undef,
  2377. /**
  2378. * chrome version
  2379. * @type undef|Number
  2380. * @member KISSY.UA
  2381. */
  2382. chrome: undef,
  2383. /**
  2384. * safari version
  2385. * @type undef|Number
  2386. * @member KISSY.UA
  2387. */
  2388. safari: undef,
  2389. /**
  2390. * firefox version
  2391. * @type undef|Number
  2392. * @member KISSY.UA
  2393. */
  2394. firefox: undef,
  2395. /**
  2396. * ie version
  2397. * @type undef|Number
  2398. * @member KISSY.UA
  2399. */
  2400. ie: undef,
  2401. /**
  2402. * ie document mode
  2403. * @type undef|Number
  2404. * @member KISSY.UA
  2405. */
  2406. ieMode: undef,
  2407. /**
  2408. * opera version
  2409. * @type undef|Number
  2410. * @member KISSY.UA
  2411. */
  2412. opera: undef,
  2413. /**
  2414. * mobile browser. apple, android.
  2415. * @type String
  2416. * @member KISSY.UA
  2417. */
  2418. mobile: undef,
  2419. /**
  2420. * browser render engine name. webkit, trident
  2421. * @type String
  2422. * @member KISSY.UA
  2423. */
  2424. core: undef,
  2425. /**
  2426. * browser shell name. ie, chrome, firefox
  2427. * @type String
  2428. * @member KISSY.UA
  2429. */
  2430. shell: undef,
  2431. /**
  2432. * PhantomJS version number
  2433. * @type undef|Number
  2434. * @member KISSY.UA
  2435. */
  2436. phantomjs: undef,
  2437. /**
  2438. * operating system. android, ios, linux, windows
  2439. * @type string
  2440. * @member KISSY.UA
  2441. */
  2442. os: undef,
  2443. /**
  2444. * ipad ios version
  2445. * @type Number
  2446. * @member KISSY.UA
  2447. */
  2448. ipad: undef,
  2449. /**
  2450. * iphone ios version
  2451. * @type Number
  2452. * @member KISSY.UA
  2453. */
  2454. iphone: undef,
  2455. /**
  2456. * ipod ios
  2457. * @type Number
  2458. * @member KISSY.UA
  2459. */
  2460. ipod: undef,
  2461. /**
  2462. * ios version
  2463. * @type Number
  2464. * @member KISSY.UA
  2465. */
  2466. ios: undef,
  2467. /**
  2468. * android version
  2469. * @type Number
  2470. * @member KISSY.UA
  2471. */
  2472. android: undef,
  2473. /**
  2474. * nodejs version
  2475. * @type Number
  2476. * @member KISSY.UA
  2477. */
  2478. nodejs: undef
  2479. }; // ejecta
  2480. // ejecta
  2481. if (div && div.getElementsByTagName) {
  2482. // try to use IE-Conditional-Comment detect IE more accurately
  2483. // IE10 doesn't support this method, @ref: http://blogs.msdn.com/b/ie/archive/2011/07/06/html5-parsing-in-ie10.aspx
  2484. div.innerHTML = IE_DETECT_TPL.replace(VERSION_PLACEHOLDER, '');
  2485. s = div.getElementsByTagName('s');
  2486. }
  2487. if (s.length > 0) {
  2488. setTridentVersion(ua, UA); // Detect the accurate version
  2489. // 注意:
  2490. // UA.shell = ie, 表示外壳是 ie
  2491. // 但 UA.ie = 7, 并不代表外壳是 ie7, 还有可能是 ie8 的兼容模式
  2492. // 对于 ie8 的兼容模式,还要通过 documentMode 去判断。但此处不能让 UA.ie = 8, 否则
  2493. // 很多脚本判断会失误。因为 ie8 的兼容模式表现行为和 ie7 相同,而不是和 ie8 相同
  2494. // Detect the accurate version
  2495. // 注意:
  2496. // UA.shell = ie, 表示外壳是 ie
  2497. // 但 UA.ie = 7, 并不代表外壳是 ie7, 还有可能是 ie8 的兼容模式
  2498. // 对于 ie8 的兼容模式,还要通过 documentMode 去判断。但此处不能让 UA.ie = 8, 否则
  2499. // 很多脚本判断会失误。因为 ie8 的兼容模式表现行为和 ie7 相同,而不是和 ie8 相同
  2500. for (v = IE_DETECT_RANGE[0], end = IE_DETECT_RANGE[1]; v <= end; v++) {
  2501. div.innerHTML = IE_DETECT_TPL.replace(VERSION_PLACEHOLDER, v);
  2502. if (s.length > 0) {
  2503. UA[shell = 'ie'] = v;
  2504. break;
  2505. }
  2506. } // https://github.com/kissyteam/kissy/issues/321
  2507. // win8 embed app
  2508. // https://github.com/kissyteam/kissy/issues/321
  2509. // win8 embed app
  2510. if (!UA.ie && (ieVersion = getIEVersion(ua))) {
  2511. UA[shell = 'ie'] = ieVersion;
  2512. }
  2513. } else {
  2514. // WebKit
  2515. // https://github.com/kissyteam/kissy/issues/545
  2516. if (((m = ua.match(/AppleWebKit\/([\d.]*)/)) || (m = ua.match(/Safari\/([\d.]*)/))) && m[1]) {
  2517. UA[core = 'webkit'] = numberify(m[1]);
  2518. if ((m = ua.match(/OPR\/(\d+\.\d+)/)) && m[1]) {
  2519. UA[shell = 'opera'] = numberify(m[1]);
  2520. } else if ((m = ua.match(/Chrome\/([\d.]*)/)) && m[1]) {
  2521. UA[shell = 'chrome'] = numberify(m[1]);
  2522. } else if ((m = ua.match(/\/([\d.]*) Safari/)) && m[1]) {
  2523. UA[shell = 'safari'] = numberify(m[1]);
  2524. } else {
  2525. // default to mobile safari
  2526. UA.safari = UA.webkit;
  2527. } // Apple Mobile
  2528. // Apple Mobile
  2529. if (/ Mobile\//.test(ua) && ua.match(/iPad|iPod|iPhone/)) {
  2530. UA.mobile = 'apple'; // iPad, iPhone or iPod Touch
  2531. // iPad, iPhone or iPod Touch
  2532. m = ua.match(/OS ([^\s]*)/);
  2533. if (m && m[1]) {
  2534. UA.ios = numberify(m[1].replace('_', '.'));
  2535. }
  2536. os = 'ios';
  2537. m = ua.match(/iPad|iPod|iPhone/);
  2538. if (m && m[0]) {
  2539. UA[m[0].toLowerCase()] = UA.ios;
  2540. }
  2541. } else if (/ Android/i.test(ua)) {
  2542. if (/Mobile/.test(ua)) {
  2543. os = UA.mobile = 'android';
  2544. }
  2545. m = ua.match(/Android ([^\s]*);/);
  2546. if (m && m[1]) {
  2547. UA.android = numberify(m[1]);
  2548. }
  2549. } else if (m = ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/)) {
  2550. UA.mobile = m[0].toLowerCase(); // Nokia N-series, Android, webOS, ex: NokiaN95
  2551. }
  2552. // Nokia N-series, Android, webOS, ex: NokiaN95
  2553. if ((m = ua.match(/PhantomJS\/([^\s]*)/)) && m[1]) {
  2554. UA.phantomjs = numberify(m[1]);
  2555. }
  2556. } else {
  2557. // Presto
  2558. // ref: http://www.useragentstring.com/pages/useragentstring.php
  2559. if ((m = ua.match(/Presto\/([\d.]*)/)) && m[1]) {
  2560. UA[core = 'presto'] = numberify(m[1]); // Opera
  2561. // Opera
  2562. if ((m = ua.match(/Opera\/([\d.]*)/)) && m[1]) {
  2563. UA[shell = 'opera'] = numberify(m[1]); // Opera detected, look for revision
  2564. // Opera detected, look for revision
  2565. if ((m = ua.match(/Opera\/.* Version\/([\d.]*)/)) && m[1]) {
  2566. UA[shell] = numberify(m[1]);
  2567. } // Opera Mini
  2568. // Opera Mini
  2569. if ((m = ua.match(/Opera Mini[^;]*/)) && m) {
  2570. UA.mobile = m[0].toLowerCase(); // ex: Opera Mini/2.0.4509/1316
  2571. } else // ex: Opera Mini/2.0.4509/1316
  2572. if ((m = ua.match(/Opera Mobi[^;]*/)) && m) {
  2573. // Opera Mobile
  2574. // ex: Opera/9.80 (Windows NT 6.1; Opera Mobi/49; U; en) Presto/2.4.18 Version/10.00
  2575. // issue: 由于 Opera Mobile 有 Version/ 字段,可能会与 Opera 混淆,同时对于 Opera Mobile 的版本号也比较混乱
  2576. UA.mobile = m[0];
  2577. }
  2578. } // NOT WebKit or Presto
  2579. } else
  2580. // NOT WebKit or Presto
  2581. {
  2582. // MSIE
  2583. // 由于最开始已经使用了 IE 条件注释判断,因此落到这里的唯一可能性只有 IE10+
  2584. // and analysis tools in nodejs
  2585. if (ieVersion = getIEVersion(ua)) {
  2586. UA[shell = 'ie'] = ieVersion;
  2587. setTridentVersion(ua, UA); // NOT WebKit, Presto or IE
  2588. } else
  2589. // NOT WebKit, Presto or IE
  2590. {
  2591. // Gecko
  2592. if (m = ua.match(/Gecko/)) {
  2593. UA[core = 'gecko'] = 0.1; // Gecko detected, look for revision
  2594. // Gecko detected, look for revision
  2595. if ((m = ua.match(/rv:([\d.]*)/)) && m[1]) {
  2596. UA[core] = numberify(m[1]);
  2597. if (/Mobile|Tablet/.test(ua)) {
  2598. UA.mobile = 'firefox';
  2599. }
  2600. } // Firefox
  2601. // Firefox
  2602. if ((m = ua.match(/Firefox\/([\d.]*)/)) && m[1]) {
  2603. UA[shell = 'firefox'] = numberify(m[1]);
  2604. }
  2605. }
  2606. }
  2607. }
  2608. }
  2609. }
  2610. if (!os) {
  2611. if (/windows|win32/i.test(ua)) {
  2612. os = 'windows';
  2613. } else if (/macintosh|mac_powerpc/i.test(ua)) {
  2614. os = 'macintosh';
  2615. } else if (/linux/i.test(ua)) {
  2616. os = 'linux';
  2617. } else if (/rhino/i.test(ua)) {
  2618. os = 'rhino';
  2619. }
  2620. }
  2621. UA.os = os;
  2622. UA.core = UA.core || core;
  2623. UA.shell = shell;
  2624. UA.ieMode = UA.ie && doc.documentMode || UA.ie;
  2625. return UA;
  2626. }
  2627. var UA = module.exports = getDescriptorFromUserAgent(ua); // nodejs
  2628. // nodejs
  2629. if (typeof process === 'object') {
  2630. var versions, nodeVersion;
  2631. if ((versions = process.versions) && (nodeVersion = versions.node)) {
  2632. UA.os = process.platform;
  2633. UA.nodejs = numberify(nodeVersion);
  2634. }
  2635. } // use by analysis tools in nodejs
  2636. // use by analysis tools in nodejs
  2637. UA.getDescriptorFromUserAgent = getDescriptorFromUserAgent;
  2638. var browsers = [
  2639. // browser core type
  2640. 'webkit',
  2641. 'trident',
  2642. 'gecko',
  2643. 'presto',
  2644. // browser type
  2645. 'chrome',
  2646. 'safari',
  2647. 'firefox',
  2648. 'ie',
  2649. 'opera'
  2650. ], documentElement = doc && doc.documentElement, className = '';
  2651. if (documentElement) {
  2652. for (var i = 0; i < browsers.length; i++) {
  2653. var key = browsers[i];
  2654. var v = UA[key];
  2655. if (v) {
  2656. className += ' ks-' + key + (parseInt(v, 10) + '');
  2657. className += ' ks-' + key;
  2658. }
  2659. }
  2660. if (className) {
  2661. documentElement.className = (documentElement.className + className).replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
  2662. }
  2663. } /*
  2664. NOTES:
  2665. 2013.07.08 yiminghe@gmail.com
  2666. - support ie11 and opera(using blink)
  2667. 2013.01.17 yiminghe@gmail.com
  2668. - expose getDescriptorFromUserAgent for analysis tool in nodejs
  2669. 2012.11.27 yiminghe@gmail.com
  2670. - moved to seed for conditional loading and better code share
  2671. 2012.11.21 yiminghe@gmail.com
  2672. - touch and os support
  2673. 2011.11.08 gonghaocn@gmail.com
  2674. - ie < 10 使用条件注释判断内核,更精确
  2675. 2010.03
  2676. - jQuery, YUI 等类库都推荐用特性探测替代浏览器嗅探。特性探测的好处是能自动适应未来设备和未知设备,比如
  2677. if(document.addEventListener) 假设 IE9 支持标准事件,则代码不用修改,就自适应了“未来浏览器”。
  2678. 对于未知浏览器也是如此。但是,这并不意味着浏览器嗅探就得彻底抛弃。当代码很明确就是针对已知特定浏览器的,
  2679. 同时并非是某个特性探测可以解决时,用浏览器嗅探反而能带来代码的简洁,同时也也不会有什么后患。总之,一切
  2680. 皆权衡。
  2681. - UA.ie && UA.ie < 8 并不意味着浏览器就不是 IE8, 有可能是 IE8 的兼容模式。进一步的判断需要使用 documentMode.
  2682. */
  2683. });
  2684. /*
  2685. Copyright 2014, KISSY v5.0.0
  2686. MIT Licensed
  2687. build time: Jul 1 23:06
  2688. */
  2689. /*
  2690. combined modules:
  2691. feature
  2692. */
  2693. KISSY.add('feature', ['ua'], function (S, require, exports, module) {
  2694. /**
  2695. * @ignore
  2696. * detect if current browser supports various features.
  2697. * @author yiminghe@gmail.com
  2698. */
  2699. var win = window, UA = require('ua'), propertyPrefixes = [
  2700. 'Webkit',
  2701. 'Moz',
  2702. 'O',
  2703. // ms is special .... !
  2704. 'ms'
  2705. ], propertyPrefixesLength = propertyPrefixes.length,
  2706. // for nodejs
  2707. doc = win.document || {}, isMsPointerSupported,
  2708. // ie11
  2709. isPointerSupported, isTransform3dSupported,
  2710. // nodejs
  2711. documentElement = doc && doc.documentElement, documentElementStyle, isClassListSupportedState = true, isQuerySelectorSupportedState = false,
  2712. // phantomjs issue: http://code.google.com/p/phantomjs/issues/detail?id=375
  2713. isTouchEventSupportedState = 'ontouchstart' in doc && !UA.phantomjs, vendorInfos = {}, ie = UA.ieMode;
  2714. if (documentElement) {
  2715. // broken ie8
  2716. if (documentElement.querySelector && ie !== 8) {
  2717. isQuerySelectorSupportedState = true;
  2718. }
  2719. documentElementStyle = documentElement.style;
  2720. isClassListSupportedState = 'classList' in documentElement;
  2721. isMsPointerSupported = 'msPointerEnabled' in navigator;
  2722. isPointerSupported = 'pointerEnabled' in navigator;
  2723. }
  2724. var RE_DASH = /-([a-z])/gi;
  2725. function upperCase() {
  2726. return arguments[1].toUpperCase();
  2727. } // return prefixed css prefix name
  2728. // return prefixed css prefix name
  2729. function getVendorInfo(name) {
  2730. if (name.indexOf('-') !== -1) {
  2731. name = name.replace(RE_DASH, upperCase);
  2732. }
  2733. if (name in vendorInfos) {
  2734. return vendorInfos[name];
  2735. } // if already prefixed or need not to prefix
  2736. // if already prefixed or need not to prefix
  2737. if (!documentElementStyle || name in documentElementStyle) {
  2738. vendorInfos[name] = {
  2739. propertyName: name,
  2740. propertyNamePrefix: ''
  2741. };
  2742. } else {
  2743. var upperFirstName = name.charAt(0).toUpperCase() + name.slice(1), vendorName;
  2744. for (var i = 0; i < propertyPrefixesLength; i++) {
  2745. var propertyNamePrefix = propertyPrefixes[i];
  2746. vendorName = propertyNamePrefix + upperFirstName;
  2747. if (vendorName in documentElementStyle) {
  2748. vendorInfos[name] = {
  2749. propertyName: vendorName,
  2750. propertyNamePrefix: propertyNamePrefix
  2751. };
  2752. }
  2753. }
  2754. vendorInfos[name] = vendorInfos[name] || null;
  2755. }
  2756. return vendorInfos[name];
  2757. } /**
  2758. * browser features detection
  2759. * @class KISSY.Feature
  2760. * @private
  2761. * @singleton
  2762. */
  2763. /**
  2764. * browser features detection
  2765. * @class KISSY.Feature
  2766. * @private
  2767. * @singleton
  2768. */
  2769. module.exports = {
  2770. // http://blogs.msdn.com/b/ie/archive/2011/09/20/touch-input-for-ie10-and-metro-style-apps.aspx
  2771. /**
  2772. * whether support microsoft pointer event.
  2773. * @type {Boolean}
  2774. */
  2775. isMsPointerSupported: function () {
  2776. // ie11 onMSPointerDown but e.type==pointerdown
  2777. return isMsPointerSupported;
  2778. },
  2779. /**
  2780. * whether support microsoft pointer event (ie11).
  2781. * @type {Boolean}
  2782. */
  2783. isPointerSupported: function () {
  2784. // ie11
  2785. return isPointerSupported;
  2786. },
  2787. /**
  2788. * whether support touch event.
  2789. * @return {Boolean}
  2790. */
  2791. isTouchEventSupported: function () {
  2792. return isTouchEventSupportedState;
  2793. },
  2794. isTouchGestureSupported: function () {
  2795. return isTouchEventSupportedState || isPointerSupported || isMsPointerSupported;
  2796. },
  2797. /**
  2798. * whether support device motion event
  2799. * @returns {boolean}
  2800. */
  2801. isDeviceMotionSupported: function () {
  2802. return !!win.DeviceMotionEvent;
  2803. },
  2804. /**
  2805. * whether support hashchange event
  2806. * @returns {boolean}
  2807. */
  2808. isHashChangeSupported: function () {
  2809. // ie8 支持 hashchange
  2810. // 但 ie8 以上切换浏览器模式到 ie7(兼容模式),
  2811. // 会导致 'onhashchange' in window === true,但是不触发事件
  2812. return 'onhashchange' in win && (!ie || ie > 7);
  2813. },
  2814. isInputEventSupported: function () {
  2815. return 'oninput' in win && (!ie || ie > 9);
  2816. },
  2817. /**
  2818. * whether support css transform 3d
  2819. * @returns {boolean}
  2820. */
  2821. isTransform3dSupported: function () {
  2822. if (isTransform3dSupported !== undefined) {
  2823. return isTransform3dSupported;
  2824. }
  2825. if (!documentElement || !getVendorInfo('transform')) {
  2826. isTransform3dSupported = false;
  2827. } else {
  2828. // https://gist.github.com/lorenzopolidori/3794226
  2829. // ie9 does not support 3d transform
  2830. // http://msdn.microsoft.com/en-us/ie/ff468705
  2831. try {
  2832. var el = doc.createElement('p');
  2833. var transformProperty = getVendorInfo('transform').propertyName;
  2834. documentElement.insertBefore(el, documentElement.firstChild);
  2835. el.style[transformProperty] = 'translate3d(1px,1px,1px)';
  2836. var computedStyle = win.getComputedStyle(el);
  2837. var has3d = computedStyle.getPropertyValue(transformProperty) || computedStyle[transformProperty];
  2838. documentElement.removeChild(el);
  2839. isTransform3dSupported = has3d !== undefined && has3d.length > 0 && has3d !== 'none';
  2840. } catch (e) {
  2841. // https://github.com/kissyteam/kissy/issues/563
  2842. isTransform3dSupported = true;
  2843. }
  2844. }
  2845. return isTransform3dSupported;
  2846. },
  2847. /**
  2848. * whether support class list api
  2849. * @returns {boolean}
  2850. */
  2851. isClassListSupported: function () {
  2852. return isClassListSupportedState;
  2853. },
  2854. /**
  2855. * whether support querySelectorAll
  2856. * @returns {boolean}
  2857. */
  2858. isQuerySelectorSupported: function () {
  2859. // force to use js selector engine
  2860. return isQuerySelectorSupportedState;
  2861. },
  2862. getCssVendorInfo: function (name) {
  2863. return getVendorInfo(name);
  2864. }
  2865. };
  2866. });
  2867. /*
  2868. Copyright 2014, KISSY v5.0.0
  2869. MIT Licensed
  2870. build time: Jul 1 23:09
  2871. */
  2872. /**
  2873. * @ignore
  2874. * Default KISSY Gallery and core alias.
  2875. * @author yiminghe@gmail.com
  2876. */
  2877. // --no-module-wrap--
  2878. KISSY.config({
  2879. packages: {
  2880. gallery: {
  2881. base: location.protocol === 'https' ?
  2882. 'https://s.tbcdn.cn/s/kissy/gallery' : 'http://a.tbcdn.cn/s/kissy/gallery'
  2883. }
  2884. }
  2885. });/*jshint indent:false, quotmark:false*/
  2886. KISSY.use(['ua', 'feature'], function(S, UA, Feature){
  2887. S.config("requires",{
  2888. "anim/base": [
  2889. "dom",
  2890. "querystring",
  2891. "promise"
  2892. ],
  2893. "anim/timer": [
  2894. "anim/base",
  2895. "feature"
  2896. ],
  2897. "anim/transition": [
  2898. "anim/base",
  2899. "feature"
  2900. ],
  2901. "attribute": [
  2902. "event/custom"
  2903. ],
  2904. "base": [
  2905. "attribute"
  2906. ],
  2907. "button": [
  2908. "component/control"
  2909. ],
  2910. "color": [
  2911. "attribute"
  2912. ],
  2913. "combobox": [
  2914. "menu",
  2915. "io"
  2916. ],
  2917. "combobox/multi-word": [
  2918. "combobox"
  2919. ],
  2920. "component/container": [
  2921. "component/control"
  2922. ],
  2923. "component/control": [
  2924. "node",
  2925. "event/gesture/basic",
  2926. "event/gesture/tap",
  2927. "base",
  2928. "xtemplate/runtime"
  2929. ],
  2930. "component/extension/align": [
  2931. "node",
  2932. "ua"
  2933. ],
  2934. "component/extension/delegate-children": [
  2935. "component/control"
  2936. ],
  2937. "component/extension/shim": [
  2938. "ua"
  2939. ],
  2940. "component/plugin/drag": [
  2941. "dd"
  2942. ],
  2943. "component/plugin/resize": [
  2944. "resizable"
  2945. ],
  2946. "cookie": [
  2947. "util"
  2948. ],
  2949. "date/format": [
  2950. "date/gregorian"
  2951. ],
  2952. "date/gregorian": [
  2953. "util",
  2954. "i18n!date"
  2955. ],
  2956. "date/picker": [
  2957. "i18n!date/picker",
  2958. "component/control",
  2959. "date/format",
  2960. "date/picker-xtpl"
  2961. ],
  2962. "date/popup-picker": [
  2963. "date/picker",
  2964. "component/extension/shim",
  2965. "component/extension/align"
  2966. ],
  2967. "dd": [
  2968. "base",
  2969. "node",
  2970. "event/gesture/basic",
  2971. "event/gesture/pan"
  2972. ],
  2973. "dd/plugin/constrain": [
  2974. "base",
  2975. "node"
  2976. ],
  2977. "dd/plugin/proxy": [
  2978. "dd"
  2979. ],
  2980. "dd/plugin/scroll": [
  2981. "dd"
  2982. ],
  2983. "dom/base": [
  2984. "util",
  2985. "feature"
  2986. ],
  2987. "dom/class-list": [
  2988. "dom/base"
  2989. ],
  2990. "dom/ie": [
  2991. "dom/base"
  2992. ],
  2993. "dom/selector": [
  2994. "util",
  2995. "dom/basic"
  2996. ],
  2997. "event": [
  2998. "event/dom",
  2999. "event/custom"
  3000. ],
  3001. "event/base": [
  3002. "util"
  3003. ],
  3004. "event/custom": [
  3005. "event/base"
  3006. ],
  3007. "event/dom/base": [
  3008. "event/base",
  3009. "dom",
  3010. "ua"
  3011. ],
  3012. "event/dom/focusin": [
  3013. "event/dom/base"
  3014. ],
  3015. "event/dom/hashchange": [
  3016. "event/dom/base"
  3017. ],
  3018. "event/dom/ie": [
  3019. "event/dom/base"
  3020. ],
  3021. "event/dom/input": [
  3022. "event/dom/base"
  3023. ],
  3024. "event/gesture/basic": [
  3025. "event/gesture/util"
  3026. ],
  3027. "event/gesture/edge-pan": [
  3028. "event/gesture/util"
  3029. ],
  3030. "event/gesture/pan": [
  3031. "event/gesture/util"
  3032. ],
  3033. "event/gesture/pinch": [
  3034. "event/gesture/util"
  3035. ],
  3036. "event/gesture/rotate": [
  3037. "event/gesture/util"
  3038. ],
  3039. "event/gesture/shake": [
  3040. "event/dom/base"
  3041. ],
  3042. "event/gesture/swipe": [
  3043. "event/gesture/util"
  3044. ],
  3045. "event/gesture/tap": [
  3046. "event/gesture/util"
  3047. ],
  3048. "event/gesture/util": [
  3049. "event/dom/base",
  3050. "feature"
  3051. ],
  3052. "feature": [
  3053. "ua"
  3054. ],
  3055. "filter-menu": [
  3056. "menu"
  3057. ],
  3058. "html-parser": [
  3059. "util"
  3060. ],
  3061. "io": [
  3062. "dom",
  3063. "event/custom",
  3064. "promise",
  3065. "url",
  3066. "ua",
  3067. "event/dom"
  3068. ],
  3069. "json": [
  3070. "util"
  3071. ],
  3072. "menu": [
  3073. "component/container",
  3074. "component/extension/delegate-children",
  3075. "component/extension/content-box",
  3076. "component/extension/align",
  3077. "component/extension/shim"
  3078. ],
  3079. "menubutton": [
  3080. "button",
  3081. "menu"
  3082. ],
  3083. "navigation-view": [
  3084. "component/container",
  3085. "component/extension/content-box"
  3086. ],
  3087. "navigation-view/bar": [
  3088. "button"
  3089. ],
  3090. "node": [
  3091. "util",
  3092. "dom",
  3093. "event/dom",
  3094. "anim"
  3095. ],
  3096. "overlay": [
  3097. "component/container",
  3098. "component/extension/shim",
  3099. "component/extension/align",
  3100. "component/extension/content-box"
  3101. ],
  3102. "promise": [
  3103. "util"
  3104. ],
  3105. "querystring": [
  3106. "logger-manager"
  3107. ],
  3108. "resizable": [
  3109. "dd"
  3110. ],
  3111. "resizable/plugin/proxy": [
  3112. "base",
  3113. "node"
  3114. ],
  3115. "router": [
  3116. "url",
  3117. "event/dom",
  3118. "event/custom",
  3119. "feature"
  3120. ],
  3121. "scroll-view/base": [
  3122. "anim/timer",
  3123. "component/container",
  3124. "component/extension/content-box"
  3125. ],
  3126. "scroll-view/plugin/pull-to-refresh": [
  3127. "base",
  3128. "node",
  3129. "feature"
  3130. ],
  3131. "scroll-view/plugin/scrollbar": [
  3132. "component/control",
  3133. "event/gesture/pan"
  3134. ],
  3135. "scroll-view/touch": [
  3136. "scroll-view/base",
  3137. "event/gesture/pan"
  3138. ],
  3139. "separator": [
  3140. "component/control"
  3141. ],
  3142. "split-button": [
  3143. "menubutton"
  3144. ],
  3145. "stylesheet": [
  3146. "dom"
  3147. ],
  3148. "swf": [
  3149. "dom",
  3150. "json",
  3151. "attribute"
  3152. ],
  3153. "tabs": [
  3154. "toolbar",
  3155. "button",
  3156. "component/extension/content-box"
  3157. ],
  3158. "toolbar": [
  3159. "component/container",
  3160. "component/extension/delegate-children"
  3161. ],
  3162. "tree": [
  3163. "component/container",
  3164. "component/extension/content-box",
  3165. "component/extension/delegate-children"
  3166. ],
  3167. "url": [
  3168. "querystring",
  3169. "path"
  3170. ],
  3171. "util": [
  3172. "logger-manager"
  3173. ],
  3174. "xtemplate": [
  3175. "xtemplate/runtime"
  3176. ],
  3177. "xtemplate/runtime": [
  3178. "util"
  3179. ]
  3180. });
  3181. var win = window,
  3182. isTouchGestureSupported = Feature.isTouchGestureSupported(),
  3183. add = S.add,
  3184. emptyObject = {};
  3185. function alias(name, aliasName) {
  3186. var cfg;
  3187. if(typeof name ==="string") {
  3188. cfg = {};
  3189. cfg[name] = aliasName;
  3190. } else {
  3191. cfg = name;
  3192. }
  3193. S.config("alias", cfg);
  3194. }
  3195. alias('anim', Feature.getCssVendorInfo('transition') ? 'anim/transition' : 'anim/timer');
  3196. alias({
  3197. 'dom/basic': [
  3198. 'dom/base',
  3199. UA.ieMode < 9 ? 'dom/ie' : '',
  3200. Feature.isClassListSupported() ? '' : 'dom/class-list'
  3201. ],
  3202. dom: [
  3203. 'dom/basic',
  3204. Feature.isQuerySelectorSupported() ? '' : 'dom/selector'
  3205. ]
  3206. });
  3207. alias('event/dom', [
  3208. 'event/dom/base',
  3209. Feature.isHashChangeSupported() ? '' : 'event/dom/hashchange',
  3210. UA.ieMode < 9 ? 'event/dom/ie' : '',
  3211. Feature.isInputEventSupported() ? '' : 'event/dom/input',
  3212. UA.ie ? '' : 'event/dom/focusin'
  3213. ]);
  3214. if (!isTouchGestureSupported) {
  3215. add('event/gesture/edge-pan', emptyObject);
  3216. }
  3217. if (!isTouchGestureSupported) {
  3218. add('event/gesture/pinch', emptyObject);
  3219. }
  3220. if (!isTouchGestureSupported) {
  3221. add('event/gesture/rotate', emptyObject);
  3222. }
  3223. if (!win.DeviceMotionEvent) {
  3224. add('event/gesture/shake', emptyObject);
  3225. }
  3226. if (!isTouchGestureSupported) {
  3227. add('event/gesture/swipe', emptyObject);
  3228. }
  3229. alias('ajax','io');
  3230. alias('scroll-view', Feature.isTouchGestureSupported() ? 'scroll-view/touch' : 'scroll-view/base');
  3231. });