[adapters] 增加小游戏适配部分源码

This commit is contained in:
SmallMain 2024-10-16 17:12:08 +08:00
parent 887d4a96c9
commit 07bf3b7a96
No known key found for this signature in database
345 changed files with 38447 additions and 0 deletions

5
adapters/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.DS_Store
*.log
node_modules
_bak
package-lock.json

1
adapters/README.md Normal file
View File

@ -0,0 +1 @@
# adapters

View File

@ -0,0 +1,288 @@
/****************************************************************************
Copyright (c) 2019 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of cache-manager software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in cache-manager License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
const { getUserDataPath, readJsonSync, makeDirSync, writeFileSync, copyFile, downloadFile, writeFile, deleteFile, rmdirSync, unzip, isOutOfStorage } = window.fsUtils;
var checkNextPeriod = false;
var writeCacheFileList = null;
var startWrite = false;
var nextCallbacks = [];
var callbacks = [];
var cleaning = false;
var suffix = 0;
const REGEX = /^https?:\/\/.*/;
var cacheManager = {
cacheDir: 'gamecaches',
cachedFileName: 'cacheList.json',
// whether or not cache asset into user's storage space
cacheEnabled: true,
// whether or not auto clear cache when storage ran out
autoClear: true,
// cache one per cycle
cacheInterval: 500,
deleteInterval: 500,
writeFileInterval: 2000,
// whether or not storage space has run out
outOfStorage: false,
tempFiles: null,
cachedFiles: null,
cacheQueue: {},
version: '1.0',
getCache (url) {
return this.cachedFiles.has(url) ? this.cachedFiles.get(url).url : '';
},
getTemp (url) {
return this.tempFiles.has(url) ? this.tempFiles.get(url) : '';
},
init () {
this.cacheDir = getUserDataPath() + '/' + this.cacheDir;
var cacheFilePath = this.cacheDir + '/' + this.cachedFileName;
var result = readJsonSync(cacheFilePath);
if (result instanceof Error || !result.version) {
if (!(result instanceof Error)) rmdirSync(this.cacheDir, true);
this.cachedFiles = new cc.AssetManager.Cache();
makeDirSync(this.cacheDir, true);
writeFileSync(cacheFilePath, JSON.stringify({ files: this.cachedFiles._map, version: this.version }), 'utf8');
}
else {
this.cachedFiles = new cc.AssetManager.Cache(result.files);
}
this.tempFiles = new cc.AssetManager.Cache();
},
updateLastTime (url) {
if (this.cachedFiles.has(url)) {
var cache = this.cachedFiles.get(url);
cache.lastTime = Date.now();
}
},
_write () {
writeCacheFileList = null;
startWrite = true;
writeFile(this.cacheDir + '/' + this.cachedFileName, JSON.stringify({ files: this.cachedFiles._map, version: this.version }), 'utf8', function () {
startWrite = false;
for (let i = 0, j = callbacks.length; i < j; i++) {
callbacks[i]();
}
callbacks.length = 0;
callbacks.push.apply(callbacks, nextCallbacks);
nextCallbacks.length = 0;
});
},
writeCacheFile (cb) {
if (!writeCacheFileList) {
writeCacheFileList = setTimeout(this._write.bind(this), this.writeFileInterval);
if (startWrite === true) {
cb && nextCallbacks.push(cb);
}
else {
cb && callbacks.push(cb);
}
} else {
cb && callbacks.push(cb);
}
},
_cache () {
var self = this;
for (var id in this.cacheQueue) {
var { srcUrl, isCopy, cacheBundleRoot } = this.cacheQueue[id];
var time = Date.now().toString();
var localPath = '';
if (cacheBundleRoot) {
localPath = `${this.cacheDir}/${cacheBundleRoot}/${time}${suffix++}${cc.path.extname(id)}`;
}
else {
localPath = `${this.cacheDir}/${time}${suffix++}${cc.path.extname(id)}`;
}
function callback (err) {
checkNextPeriod = false;
if (err) {
if (isOutOfStorage(err.message)) {
self.outOfStorage = true;
self.autoClear && self.clearLRU();
return;
}
} else {
self.cachedFiles.add(id, { bundle: cacheBundleRoot, url: localPath, lastTime: time });
delete self.cacheQueue[id];
self.writeCacheFile();
}
if (!cc.js.isEmptyObject(self.cacheQueue)) {
checkNextPeriod = true;
setTimeout(self._cache.bind(self), self.cacheInterval);
}
}
if (!isCopy) {
downloadFile(srcUrl, localPath, null, callback);
}
else {
copyFile(srcUrl, localPath, callback);
}
return;
}
checkNextPeriod = false;
},
cacheFile (id, srcUrl, cacheEnabled, cacheBundleRoot, isCopy) {
cacheEnabled = cacheEnabled !== undefined ? cacheEnabled : this.cacheEnabled;
if (!cacheEnabled || this.cacheQueue[id] || this.cachedFiles.has(id)) return;
this.cacheQueue[id] = { srcUrl, cacheBundleRoot, isCopy };
if (!checkNextPeriod) {
checkNextPeriod = true;
if (!this.outOfStorage) {
setTimeout(this._cache.bind(this), this.cacheInterval);
}
else {
checkNextPeriod = false;
}
}
},
clearCache () {
rmdirSync(this.cacheDir, true);
this.cachedFiles = new cc.AssetManager.Cache();
makeDirSync(this.cacheDir, true);
var cacheFilePath = this.cacheDir + '/' + this.cachedFileName;
this.outOfStorage = false;
writeFileSync(cacheFilePath, JSON.stringify({ files: this.cachedFiles._map, version: this.version }), 'utf8');
cc.assetManager.bundles.forEach(bundle => {
if (REGEX.test(bundle.base)) this.makeBundleFolder(bundle.name);
});
},
clearLRU () {
if (cleaning) return;
cleaning = true;
var caches = [];
var self = this;
this.cachedFiles.forEach(function (val, key) {
if (val.bundle === 'internal') return;
if (self._isZipFile(key) && cc.assetManager.bundles.find(bundle => bundle.base.indexOf(val.url) !== -1)) return;
caches.push({ originUrl: key, url: val.url, lastTime: val.lastTime });
});
caches.sort(function (a, b) {
return a.lastTime - b.lastTime;
});
caches.length = Math.floor(caches.length / 3);
if (caches.length === 0) return;
for (var i = 0, l = caches.length; i < l; i++) {
this.cachedFiles.remove(caches[i].originUrl);
}
this.writeCacheFile(function () {
function deferredDelete () {
var item = caches.pop();
if (self._isZipFile(item.originUrl)) {
rmdirSync(item.url, true);
self._deleteFileCB();
}
else {
deleteFile(item.url, self._deleteFileCB.bind(self));
}
if (caches.length > 0) {
setTimeout(deferredDelete, self.deleteInterval);
}
else {
cleaning = false;
}
}
setTimeout(deferredDelete, self.deleteInterval);
});
},
removeCache (url) {
if (this.cachedFiles.has(url)) {
var self = this;
var path = this.cachedFiles.remove(url).url;
this.writeCacheFile(function () {
if (self._isZipFile(url)) {
rmdirSync(path, true);
self._deleteFileCB();
}
else {
deleteFile(path, self._deleteFileCB.bind(self));
}
});
}
},
_deleteFileCB (err) {
if (!err) this.outOfStorage = false;
},
makeBundleFolder (bundleName) {
makeDirSync(this.cacheDir + '/' + bundleName, true);
},
unzipAndCacheBundle (id, zipFilePath, cacheBundleRoot, onComplete) {
let time = Date.now().toString();
let targetPath = `${this.cacheDir}/${cacheBundleRoot}/${time}${suffix++}`;
let self = this;
makeDirSync(targetPath, true);
unzip(zipFilePath, targetPath, function (err) {
if (err) {
rmdirSync(targetPath, true);
if (isOutOfStorage(err.message)) {
self.outOfStorage = true;
self.autoClear && self.clearLRU();
}
onComplete && onComplete(err);
return;
}
self.cachedFiles.add(id, { bundle: cacheBundleRoot, url: targetPath, lastTime: time });
self.writeCacheFile();
onComplete && onComplete(null, targetPath);
});
},
_isZipFile (url) {
return url.slice(-4) === '.zip';
},
};
cc.assetManager.cacheManager = module.exports = cacheManager;

View File

@ -0,0 +1,471 @@
const cacheManager = require('../cache-manager');
const { fs, downloadFile, readText, readArrayBuffer, readJson, loadSubpackage, getUserDataPath, exists } = window.fsUtils;
const REGEX = /^https?:\/\/.*/;
const cachedSubpackageList = {};
const downloader = cc.assetManager.downloader;
const parser = cc.assetManager.parser;
const presets = cc.assetManager.presets;
const isSubDomain = __globalAdapter.isSubContext;
downloader.maxConcurrency = 8;
downloader.maxRequestsPerFrame = 64;
presets['scene'].maxConcurrency = 10;
presets['scene'].maxRequestsPerFrame = 64;
let SUBCONTEXT_ROOT, REMOTE_SERVER_ROOT;
let subpackages = {}, remoteBundles = {};
function downloadScript (url, options, onComplete) {
if (typeof options === 'function') {
onComplete = options;
options = null;
}
if (REGEX.test(url)) {
onComplete && onComplete(new Error('Can not load remote scripts'));
}
else {
__cocos_require__(url);
onComplete && onComplete(null);
}
}
function handleZip (url, options, onComplete) {
let cachedUnzip = cacheManager.cachedFiles.get(url);
if (cachedUnzip) {
cacheManager.updateLastTime(url);
onComplete && onComplete(null, cachedUnzip.url);
}
else if (REGEX.test(url)) {
downloadFile(url, null, options.header, options.onFileProgress, function (err, downloadedZipPath) {
if (err) {
onComplete && onComplete(err);
return;
}
cacheManager.unzipAndCacheBundle(url, downloadedZipPath, options.__cacheBundleRoot__, onComplete);
});
}
else {
cacheManager.unzipAndCacheBundle(url, url, options.__cacheBundleRoot__, onComplete);
}
}
function downloadDomAudio (url, options, onComplete) {
if (typeof options === 'function') {
onComplete = options;
options = null;
}
let dom;
let sys = cc.sys;
if (sys.platform === sys.TAOBAO || sys.platform === sys.TAOBAO_MINIGAME) {
dom = window.document.createElement('audio');
} else {
dom = document.createElement('audio');
}
dom.src = url;
// HACK: wechat does not callback when load large number of assets
onComplete && onComplete(null, dom);
}
function download (url, func, options, onFileProgress, onComplete) {
var result = transformUrl(url, options);
if (result.inLocal) {
func(result.url, options, onComplete);
}
else if (result.inCache) {
cacheManager.updateLastTime(url);
func(result.url, options, function (err, data) {
if (err) {
cacheManager.removeCache(url);
}
onComplete(err, data);
});
}
else {
downloadFile(url, null, options.header, onFileProgress, function (err, path) {
if (err) {
onComplete(err, null);
return;
}
func(path, options, function (err, data) {
if (!err) {
cacheManager.tempFiles.add(url, path);
cacheManager.cacheFile(url, path, options.cacheEnabled, options.__cacheBundleRoot__, true);
}
onComplete(err, data);
});
});
}
}
function parseArrayBuffer (url, options, onComplete) {
readArrayBuffer(url, onComplete);
}
function parseText (url, options, onComplete) {
readText(url, onComplete);
}
function parseJson (url, options, onComplete) {
readJson(url, onComplete);
}
function downloadText (url, options, onComplete) {
download(url, parseText, options, options.onFileProgress, onComplete);
}
var downloadJson = !isSubDomain ? function (url, options, onComplete) {
download(url, parseJson, options, options.onFileProgress, onComplete);
} : function (url, options, onComplete) {
var { url } = transformUrl(url, options);
url = url.slice(SUBCONTEXT_ROOT.length + 1); // remove subcontext root in url
var content = __cocos_require__(cc.path.changeExtname(url, '.js'));
onComplete && onComplete(null, content);
}
var loadFont = !isSubDomain ? function (url, options, onComplete) {
var fontFamily = __globalAdapter.loadFont(url);
onComplete(null, fontFamily || 'Arial');
} : function (url, options, onComplete) {
onComplete(null, 'Arial');
}
function doNothing (content, options, onComplete) {
exists(content, (existence) => {
if (existence) {
onComplete(null, content);
} else {
onComplete(new Error(`file ${content} does not exist!`));
}
});
}
function downloadAsset (url, options, onComplete) {
download(url, doNothing, options, options.onFileProgress, onComplete);
}
function subdomainTransformUrl (url, options, onComplete) {
var { url } = transformUrl(url, options);
onComplete(null, url);
}
function downloadBundle (nameOrUrl, options, onComplete) {
let bundleName = cc.path.basename(nameOrUrl);
var version = options.version || cc.assetManager.downloader.bundleVers[bundleName];
const suffix = version ? `${version}.` : '';
function getConfigPathForSubPackage () {
let sys = cc.sys;
if (sys.platform === sys.TAOBAO_MINIGAME) {
return `${bundleName}/config.${suffix}json`;
}
return `subpackages/${bundleName}/config.${suffix}json`;
}
function appendBaseToJsonData (data) {
if (!data) return;
let sys = cc.sys;
if (sys.platform === sys.TAOBAO_MINIGAME) {
data.base = `${bundleName}/`;
} else {
data.base = `subpackages/${bundleName}/`;
}
}
if (subpackages[bundleName]) {
var config = getConfigPathForSubPackage();
let loadedCb = function () {
downloadJson(config, options, function (err, data) {
appendBaseToJsonData(data);
onComplete(err, data);
});
};
if (cachedSubpackageList[bundleName]) {
return loadedCb();
}
loadSubpackage(bundleName, options.onFileProgress, function (err) {
if (err) {
onComplete(err, null);
return;
}
cachedSubpackageList[bundleName] = true;
loadedCb();
});
}
else {
let js, url;
if (REGEX.test(nameOrUrl) || (!isSubDomain && nameOrUrl.startsWith(getUserDataPath()))) {
url = nameOrUrl;
js = `src/scripts/${bundleName}/index.js`;
cacheManager.makeBundleFolder(bundleName);
}
else {
if (remoteBundles[bundleName]) {
url = `${REMOTE_SERVER_ROOT}remote/${bundleName}`;
js = `src/scripts/${bundleName}/index.js`;
cacheManager.makeBundleFolder(bundleName);
}
else {
url = `assets/${bundleName}`;
js = `assets/${bundleName}/index.js`;
}
}
__cocos_require__(js);
options.__cacheBundleRoot__ = bundleName;
var config = `${url}/config.${version ? version + '.' : ''}json`;
downloadJson(config, options, function (err, data) {
if (err) {
onComplete && onComplete(err);
return;
}
if (data.isZip) {
let zipVersion = data.zipVersion;
let zipUrl = `${url}/res.${zipVersion ? zipVersion + '.' : ''}zip`;
handleZip(zipUrl, options, function (err, unzipPath) {
if (err) {
onComplete && onComplete(err);
return;
}
data.base = unzipPath + '/res/';
// PATCH: for android alipay version before v10.1.95 (v10.1.95 included)
// to remove in the future
let sys = cc.sys;
if (sys.platform === sys.ALIPAY_GAME && sys.os === sys.OS_ANDROID) {
let resPath = unzipPath + 'res/';
if (fs.accessSync({path: resPath}).success) {
data.base = resPath;
}
}
onComplete && onComplete(null, data);
});
}
else {
data.base = url + '/';
onComplete && onComplete(null, data);
}
});
}
};
const originParsePVRTex = parser.parsePVRTex;
let parsePVRTex = function (file, options, onComplete) {
readArrayBuffer(file, function (err, data) {
if (err) return onComplete(err);
originParsePVRTex(data, options, onComplete);
});
};
const originParseASTCTex = parser.parseASTCTex;
let parseASTCTex = function (file, options, onComplete) {
readArrayBuffer(file, function (err, data) {
if (err) return onComplete(err);
originParseASTCTex(data, options, onComplete);
});
};
const originParsePKMTex = parser.parsePKMTex;
let parsePKMTex = function (file, options, onComplete) {
readArrayBuffer(file, function (err, data) {
if (err) return onComplete(err);
originParsePKMTex(data, options, onComplete);
});
};
function parsePlist (url, options, onComplete) {
readText(url, function (err, file) {
var result = null;
if (!err) {
result = cc.plistParser.parse(file);
if (!result) err = new Error('parse failed');
}
onComplete && onComplete(err, result);
});
}
let downloadImage = isSubDomain ? subdomainTransformUrl : downloadAsset;
downloader.downloadDomAudio = downloadDomAudio;
downloader.downloadScript = downloadScript;
parser.parsePVRTex = parsePVRTex;
parser.parsePKMTex = parsePKMTex;
parser.parseASTCTex = parseASTCTex;
downloader.register({
'.js' : downloadScript,
// Audio
'.mp3' : downloadAsset,
'.ogg' : downloadAsset,
'.wav' : downloadAsset,
'.m4a' : downloadAsset,
// Image
'.png' : downloadImage,
'.jpg' : downloadImage,
'.bmp' : downloadImage,
'.jpeg' : downloadImage,
'.gif' : downloadImage,
'.ico' : downloadImage,
'.tiff' : downloadImage,
'.image' : downloadImage,
'.webp' : downloadImage,
'.pvr': downloadAsset,
'.pkm': downloadAsset,
'.astc': downloadAsset,
'.font': downloadAsset,
'.eot': downloadAsset,
'.ttf': downloadAsset,
'.woff': downloadAsset,
'.svg': downloadAsset,
'.ttc': downloadAsset,
// Txt
'.txt' : downloadAsset,
'.xml' : downloadAsset,
'.vsh' : downloadAsset,
'.fsh' : downloadAsset,
'.atlas' : downloadAsset,
'.tmx' : downloadAsset,
'.tsx' : downloadAsset,
'.plist' : downloadAsset,
'.fnt' : downloadAsset,
'.json' : downloadJson,
'.ExportJson' : downloadAsset,
'.binary' : downloadAsset,
'.bin': downloadAsset,
'.dbbin': downloadAsset,
'.skel': downloadAsset,
'.mp4': downloadAsset,
'.avi': downloadAsset,
'.mov': downloadAsset,
'.mpg': downloadAsset,
'.mpeg': downloadAsset,
'.rm': downloadAsset,
'.rmvb': downloadAsset,
'bundle': downloadBundle,
'default': downloadText,
});
parser.register({
'.png' : downloader.downloadDomImage,
'.jpg' : downloader.downloadDomImage,
'.bmp' : downloader.downloadDomImage,
'.jpeg' : downloader.downloadDomImage,
'.gif' : downloader.downloadDomImage,
'.ico' : downloader.downloadDomImage,
'.tiff' : downloader.downloadDomImage,
'.image' : downloader.downloadDomImage,
'.webp' : downloader.downloadDomImage,
'.pvr': parsePVRTex,
'.pkm': parsePKMTex,
'.astc': parseASTCTex,
'.font': loadFont,
'.eot': loadFont,
'.ttf': loadFont,
'.woff': loadFont,
'.svg': loadFont,
'.ttc': loadFont,
// Audio
'.mp3' : downloadDomAudio,
'.ogg' : downloadDomAudio,
'.wav' : downloadDomAudio,
'.m4a' : downloadDomAudio,
// Txt
'.txt' : parseText,
'.xml' : parseText,
'.vsh' : parseText,
'.fsh' : parseText,
'.atlas' : parseText,
'.tmx' : parseText,
'.tsx' : parseText,
'.fnt' : parseText,
'.plist' : parsePlist,
'.binary' : parseArrayBuffer,
'.bin': parseArrayBuffer,
'.dbbin': parseArrayBuffer,
'.skel': parseArrayBuffer,
'.ExportJson' : parseJson,
});
var transformUrl = !isSubDomain ? function (url, options) {
var inLocal = false;
var inCache = false;
var isInUserDataPath = url.startsWith(getUserDataPath());
if (isInUserDataPath) {
inLocal = true;
}
else if (REGEX.test(url)) {
if (!options.reload) {
var cache = cacheManager.cachedFiles.get(url);
if (cache) {
inCache = true;
url = cache.url;
}
else {
var tempUrl = cacheManager.tempFiles.get(url);
if (tempUrl) {
inLocal = true;
url = tempUrl;
}
}
}
}
else {
inLocal = true;
}
return { url, inLocal, inCache };
} : function (url, options) {
if (!REGEX.test(url)) {
url = SUBCONTEXT_ROOT + '/' + url;
}
return { url };
}
if (!isSubDomain) {
cc.assetManager.transformPipeline.append(function (task) {
var input = task.output = task.input;
for (var i = 0, l = input.length; i < l; i++) {
var item = input[i];
var options = item.options;
if (!item.config) {
if (item.ext === 'bundle') continue;
options.cacheEnabled = options.cacheEnabled !== undefined ? options.cacheEnabled : false;
}
else {
options.__cacheBundleRoot__ = item.config.name;
}
}
});
var originInit = cc.assetManager.init;
cc.assetManager.init = function (options) {
originInit.call(cc.assetManager, options);
options.subpackages && options.subpackages.forEach(x => subpackages[x] = 'subpackages/' + x);
options.remoteBundles && options.remoteBundles.forEach(x => remoteBundles[x] = true);
REMOTE_SERVER_ROOT = options.server || '';
if (REMOTE_SERVER_ROOT && !REMOTE_SERVER_ROOT.endsWith('/')) REMOTE_SERVER_ROOT += '/';
cacheManager.init();
};
}
else {
var originInit = cc.assetManager.init;
cc.assetManager.init = function (options) {
originInit.call(cc.assetManager, options);
SUBCONTEXT_ROOT = options.subContextRoot || '';
};
}

View File

@ -0,0 +1,69 @@
const Audio = cc._Audio;
if (Audio) {
let originGetDuration = Audio.prototype.getDuration;
Object.assign(Audio.prototype, {
_createElement () {
let elem = this._src._nativeAsset;
// Reuse dom audio element
if (!this._element) {
this._element = __globalAdapter.createInnerAudioContext();
}
this._element.src = elem.src;
},
destroy () {
if (this._element) {
this._element.destroy();
this._element = null;
}
},
setCurrentTime (num) {
let self = this;
this._src && this._src._ensureLoaded(function () {
self._element.seek(num);
});
},
stop () {
let self = this;
this._src && this._src._ensureLoaded(function () {
// HACK: some platforms won't set currentTime to 0 when stop audio
self._element.seek(0);
self._element.stop();
self._unbindEnded();
self.emit('stop');
self._state = Audio.State.STOPPED;
});
},
_bindEnded () {
let elem = this._element;
if (elem && elem.onEnded && !this._onended._binded) {
this._onended._binded = true;
elem.onEnded(this._onended);
}
},
_unbindEnded () {
let elem = this._element;
if (elem && elem.offEnded && this._onended._binded) {
this._onended._binded = false;
elem.offEnded && elem.offEnded(this._onended);
}
},
getDuration () {
let duration = originGetDuration.call(this);
// HACK: in mini game, if dynamicly load audio, can't get duration from audioClip
// because duration is not coming from audio deserialization
duration = duration || (this._element ? this._element.duration : 0);
return duration;
},
// adapt some special operations on web platform
_touchToPlay () { },
_forceUpdatingState () { },
});
}

View File

@ -0,0 +1,3 @@
if (cc && cc.audioEngine) {
cc.audioEngine._maxAudioInstance = 10;
}

View File

@ -0,0 +1,37 @@
const inputManager = cc.internal.inputManager;
const globalAdapter = window.__globalAdapter;
Object.assign(inputManager, {
setAccelerometerEnabled (isEnable) {
let scheduler = cc.director.getScheduler();
scheduler.enableForTarget(this);
if (isEnable) {
this._registerAccelerometerEvent();
scheduler.scheduleUpdate(this);
}
else {
this._unregisterAccelerometerEvent();
scheduler.unscheduleUpdate(this);
}
},
// No need to adapt
// setAccelerometerInterval (interval) { },
_registerAccelerometerEvent () {
this._accelCurTime = 0;
let self = this;
this._acceleration = new cc.Acceleration();
globalAdapter.startAccelerometer(function (res) {
self._acceleration.x = res.x;
self._acceleration.y = res.y;
self._acceleration.z = res.y;
});
},
_unregisterAccelerometerEvent () {
this._accelCurTime = 0;
globalAdapter.stopAccelerometer();
},
});

View File

@ -0,0 +1,177 @@
(function () {
if (!(cc && cc.EditBox)) {
return;
}
const EditBox = cc.EditBox;
const js = cc.js;
const KeyboardReturnType = EditBox.KeyboardReturnType;
const MAX_VALUE = 65535;
const KEYBOARD_HIDE_TIME = 600;
let _hideKeyboardTimeout = null;
let _currentEditBoxImpl = null;
function getKeyboardReturnType (type) {
switch (type) {
case KeyboardReturnType.DEFAULT:
case KeyboardReturnType.DONE:
return 'done';
case KeyboardReturnType.SEND:
return 'send';
case KeyboardReturnType.SEARCH:
return 'search';
case KeyboardReturnType.GO:
return 'go';
case KeyboardReturnType.NEXT:
return 'next';
}
return 'done';
}
const BaseClass = EditBox._ImplClass;
function MiniGameEditBoxImpl () {
BaseClass.call(this);
this._eventListeners = {
onKeyboardInput: null,
onKeyboardConfirm: null,
onKeyboardComplete: null,
};
}
js.extend(MiniGameEditBoxImpl, BaseClass);
EditBox._ImplClass = MiniGameEditBoxImpl;
Object.assign(MiniGameEditBoxImpl.prototype, {
init (delegate) {
if (!delegate) {
cc.error('EditBox init failed');
return;
}
this._delegate = delegate;
},
beginEditing () {
// In case multiply register events
if (this._editing) {
return;
}
this._ensureKeyboardHide(() => {
let delegate = this._delegate;
this._showKeyboard();
this._registerKeyboardEvent();
this._editing = true;
_currentEditBoxImpl = this;
delegate.editBoxEditingDidBegan();
});
},
endEditing () {
this._hideKeyboard();
let cbs = this._eventListeners;
cbs.onKeyboardComplete && cbs.onKeyboardComplete();
},
_registerKeyboardEvent () {
let self = this;
let delegate = this._delegate;
let cbs = this._eventListeners;
cbs.onKeyboardInput = function (res) {
if (delegate._string !== res.value) {
delegate.editBoxTextChanged(res.value);
}
}
cbs.onKeyboardConfirm = function (res) {
delegate.editBoxEditingReturn();
let cbs = self._eventListeners;
cbs.onKeyboardComplete && cbs.onKeyboardComplete(res);
}
cbs.onKeyboardComplete = function (res) {
self._editing = false;
_currentEditBoxImpl = null;
self._unregisterKeyboardEvent();
if (res && res.value && delegate._string !== res.value) {
delegate.editBoxTextChanged(res.value);
}
delegate.editBoxEditingDidEnded();
}
__globalAdapter.onKeyboardInput(cbs.onKeyboardInput);
__globalAdapter.onKeyboardConfirm(cbs.onKeyboardConfirm);
__globalAdapter.onKeyboardComplete(cbs.onKeyboardComplete);
},
_unregisterKeyboardEvent () {
let cbs = this._eventListeners;
if (cbs.onKeyboardInput) {
__globalAdapter.offKeyboardInput(cbs.onKeyboardInput);
cbs.onKeyboardInput = null;
}
if (cbs.onKeyboardConfirm) {
__globalAdapter.offKeyboardConfirm(cbs.onKeyboardConfirm);
cbs.onKeyboardConfirm = null;
}
if (cbs.onKeyboardComplete) {
__globalAdapter.offKeyboardComplete(cbs.onKeyboardComplete);
cbs.onKeyboardComplete = null;
}
},
_otherEditing () {
return !!_currentEditBoxImpl && _currentEditBoxImpl !== this && _currentEditBoxImpl._editing;
},
_ensureKeyboardHide (cb) {
let otherEditing = this._otherEditing();
if (!otherEditing && !_hideKeyboardTimeout) {
return cb();
}
if (_hideKeyboardTimeout) {
clearTimeout(_hideKeyboardTimeout);
}
if (otherEditing) {
_currentEditBoxImpl.endEditing();
}
_hideKeyboardTimeout = setTimeout(() => {
_hideKeyboardTimeout = null;
cb();
}, KEYBOARD_HIDE_TIME);
},
_showKeyboard () {
let delegate = this._delegate;
let multiline = (delegate.inputMode === EditBox.InputMode.ANY);
let maxLength = (delegate.maxLength < 0 ? MAX_VALUE : delegate.maxLength);
__globalAdapter.showKeyboard({
defaultValue: delegate._string,
maxLength: maxLength,
multiple: multiline,
confirmHold: false,
confirmType: getKeyboardReturnType(delegate.returnType),
success (res) {
},
fail (res) {
cc.warn(res.errMsg);
}
});
},
_hideKeyboard () {
__globalAdapter.hideKeyboard({
success (res) {
},
fail (res) {
cc.warn(res.errMsg);
},
});
},
});
})();

View File

@ -0,0 +1,165 @@
const inputManager = cc.internal.inputManager;
const renderer = cc.renderer;
const game = cc.game;
const dynamicAtlasManager = cc.dynamicAtlasManager;
let originRun = game.run;
Object.assign(game, {
_banRunningMainLoop: __globalAdapter.isSubContext,
_firstSceneLaunched: false,
run () {
cc.director.once(cc.Director.EVENT_AFTER_SCENE_LAUNCH, () => {
this._firstSceneLaunched = true;
});
originRun.apply(this, arguments);
},
setFrameRate (frameRate) {
this.config.frameRate = frameRate;
if (__globalAdapter.setPreferredFramesPerSecond) {
__globalAdapter.setPreferredFramesPerSecond(frameRate);
}
else {
if (this._intervalId) {
window.cancelAnimFrame(this._intervalId);
}
this._intervalId = 0;
this._paused = true;
this._setAnimFrame();
this._runMainLoop();
}
},
_runMainLoop () {
if (this._banRunningMainLoop) {
return;
}
var self = this, callback, config = self.config,
director = cc.director,
skip = true, frameRate = config.frameRate;
cc.debug.setDisplayStats(config.showFPS);
callback = function () {
if (!self._paused) {
self._intervalId = window.requestAnimFrame(callback);
if (frameRate === 30 && !__globalAdapter.setPreferredFramesPerSecond) {
skip = !skip;
if (skip) {
return;
}
}
director.mainLoop();
}
};
self._intervalId = window.requestAnimFrame(callback);
self._paused = false;
},
_initRenderer () {
// Avoid setup to be called twice.
if (this._rendererInitialized) return;
// frame and container are useless on minigame platform
let sys = cc.sys;
if (sys.platform === sys.TAOBAO || sys.platform === sys.TAOBAO_MINIGAME) {
this.frame = this.container = window.document.createElement("DIV");
} else {
this.frame = this.container = document.createElement("DIV");
}
let localCanvas;
if (__globalAdapter.isSubContext) {
localCanvas = window.sharedCanvas || __globalAdapter.getSharedCanvas();
}
else if (sys.platform === sys.TAOBAO || sys.platform === sys.TAOBAO_MINIGAME) {
localCanvas = window.canvas;
}
else {
localCanvas = canvas;
}
this.canvas = localCanvas;
this._determineRenderType();
// WebGL context created successfully
if (this.renderType === this.RENDER_TYPE_WEBGL) {
var opts = {
'stencil': true,
// MSAA is causing serious performance dropdown on some browsers.
'antialias': cc.macro.ENABLE_WEBGL_ANTIALIAS,
'alpha': cc.macro.ENABLE_TRANSPARENT_CANVAS,
'preserveDrawingBuffer': false,
};
renderer.initWebGL(localCanvas, opts);
this._renderContext = renderer.device._gl;
// Enable dynamic atlas manager by default
if (!cc.macro.CLEANUP_IMAGE_CACHE && dynamicAtlasManager) {
dynamicAtlasManager.enabled = true;
}
}
if (!this._renderContext) {
this.renderType = this.RENDER_TYPE_CANVAS;
// Could be ignored by module settings
renderer.initCanvas(localCanvas);
this._renderContext = renderer.device._ctx;
}
this._rendererInitialized = true;
},
_initEvents () {
let sys = cc.sys;
// register system events
if (this.config.registerSystemEvent) {
inputManager.registerSystemEvent(this.canvas);
}
var hidden = false;
function onHidden() {
if (!hidden) {
hidden = true;
game.emit(game.EVENT_HIDE);
}
}
function onShown(res) {
if (hidden) {
hidden = false;
if (game.renderType === game.RENDER_TYPE_WEBGL) {
game._renderContext.finish();
}
game.emit(game.EVENT_SHOW, res);
}
}
// NOTE: onAudioInterruptionEnd and onAudioInterruptionBegin on ByteDance platform is not designed to behave the same as the ones on WeChat platform,
// the callback is invoked on game show or hide on ByteDance platform, while is not invoked on WeChat platform.
// See the docs on WeChat: https://developers.weixin.qq.com/minigame/dev/api/base/app/app-event/wx.onAudioInterruptionBegin.html
if (sys.platform !== sys.BYTEDANCE_GAME) {
__globalAdapter.onAudioInterruptionEnd && __globalAdapter.onAudioInterruptionEnd(function () {
if (cc.audioEngine) cc.audioEngine._restore();
});
__globalAdapter.onAudioInterruptionBegin && __globalAdapter.onAudioInterruptionBegin(function () {
if (cc.audioEngine) cc.audioEngine._break();
});
}
// Maybe not support in open data context
__globalAdapter.onShow && __globalAdapter.onShow(onShown);
__globalAdapter.onHide && __globalAdapter.onHide(onHidden);
this.on(game.EVENT_HIDE, function () {
game.pause();
});
this.on(game.EVENT_SHOW, function () {
game.resume();
});
},
end () { }, // mini game platform not support this api
});

View File

@ -0,0 +1,42 @@
const mgr = cc.internal.inputManager;
const canvasPosition = {
left: 0,
top: 0,
width: window.innerWidth,
height: window.innerHeight
};
if (mgr) {
Object.assign(mgr, {
_updateCanvasBoundingRect () {},
registerSystemEvent (element) {
if(this._isRegisterEvent) return;
this._glView = cc.view;
let self = this;
//register touch event
let _touchEventsMap = {
onTouchStart: this.handleTouchesBegin,
onTouchMove: this.handleTouchesMove,
onTouchEnd: this.handleTouchesEnd,
onTouchCancel: this.handleTouchesCancel,
};
let registerTouchEvent = function (eventName) {
let handler = _touchEventsMap[eventName];
__globalAdapter[eventName](function (event) {
if (!event.changedTouches) return;
handler.call(self, self.getTouchesByEvent(event, canvasPosition));
});
};
for (let eventName in _touchEventsMap) {
registerTouchEvent(eventName);
}
this._isRegisterEvent = true;
},
});
}

View File

@ -0,0 +1,5 @@
Object.assign(cc.screen, {
autoFullScreen: function (element, onFullScreenChange) {
// Not support on mini game
}
});

View File

@ -0,0 +1,12 @@
const Texture2D = cc.Texture2D;
if (Texture2D) {
Object.assign(Texture2D.prototype, {
initWithElement (element) {
if (!element)
return;
this._image = element;
this.handleLoadedTexture();
},
});
}

View File

@ -0,0 +1,67 @@
function adaptSys (sys, env) {
if (!env) {
env = __globalAdapter.getSystemInfoSync();
}
var language = env.language || '';
var system = env.system || 'iOS';
var platform = env.platform || 'iOS';
sys.isNative = false;
sys.isBrowser = false;
sys.isMobile = true;
sys.language = language.substr(0, 2);
sys.languageCode = language.toLowerCase();
platform = platform.toLowerCase();
if (platform === "android") {
sys.os = sys.OS_ANDROID;
}
else if (platform === "ios") {
sys.os = sys.OS_IOS;
}
system = system.toLowerCase();
// Adaptation to Android P
if (system === 'android p') {
system = 'android p 9.0';
}
var version = /[\d\.]+/.exec(system);
sys.osVersion = version ? version[0] : system;
sys.osMainVersion = parseInt(sys.osVersion);
sys.browserType = null;
sys.browserVersion = null;
var w = env.windowWidth;
var h = env.windowHeight;
var ratio = env.pixelRatio || 1;
sys.windowPixelResolution = {
width: ratio * w,
height: ratio * h
};
sys.localStorage = window.localStorage;
var _supportWebGL = __globalAdapter.isSubContext ? false : true;;
var _supportWebp = false;
try {
var _canvas = document.createElement("canvas");
_supportWebp = _canvas.toDataURL('image/webp').startsWith('data:image/webp');
}
catch (err) { }
sys.capabilities = {
"canvas": true,
"opengl": !!_supportWebGL,
"webp": _supportWebp
};
sys.__audioSupport = {
ONLY_ONE: false,
WEB_AUDIO: false,
DELAY_CREATE_CTX: false,
format: ['.mp3']
};
}
module.exports = adaptSys;

View File

@ -0,0 +1,25 @@
function adaptContainerStrategy (containerStrategyProto) {
containerStrategyProto._setupContainer = function (view, width, height) {
// Setup pixel ratio for retina display
var devicePixelRatio = view._devicePixelRatio = 1;
if (view.isRetinaEnabled()) {
devicePixelRatio = view._devicePixelRatio = Math.min(view._maxPixelRatio, window.devicePixelRatio || 1);
}
// size of sharedCanvas is readonly in subContext
if (__globalAdapter.isSubContext) {
return;
}
let locCanvas = cc.game.canvas;
// Setup canvas
width *= devicePixelRatio;
height *= devicePixelRatio;
// FIX: black screen on Baidu platform
// reset canvas size may call gl.clear(), especially when you call cc.director.loadScene()
if (locCanvas.width !== width || locCanvas.height !== height) {
locCanvas.width = width;
locCanvas.height = height;
}
};
}
module.exports = adaptContainerStrategy;

View File

@ -0,0 +1,43 @@
function adaptView (viewProto) {
Object.assign(viewProto, {
_adjustViewportMeta () {
// minigame not support
},
setRealPixelResolution (width, height, resolutionPolicy) {
// Reset the resolution size and policy
this.setDesignResolutionSize(width, height, resolutionPolicy);
},
enableAutoFullScreen (enabled) {
cc.warn('cc.view.enableAutoFullScreen() is not supported on minigame platform.');
},
isAutoFullScreenEnabled () {
return false;
},
setCanvasSize () {
cc.warn('cc.view.setCanvasSize() is not supported on minigame platform.');
},
setFrameSize () {
cc.warn('frame size is readonly on minigame platform.');
},
_initFrameSize () {
let locFrameSize = this._frameSize;
if (__globalAdapter.isSubContext) {
let sharedCanvas = window.sharedCanvas || __globalAdapter.getSharedCanvas();
locFrameSize.width = sharedCanvas.width;
locFrameSize.height = sharedCanvas.height;
}
else {
locFrameSize.width = window.innerWidth;
locFrameSize.height = window.innerHeight;
}
},
});
}
module.exports = adaptView;

View File

@ -0,0 +1,9 @@
const adapter = window.__globalAdapter;
Object.assign(adapter, {
adaptSys: require('./BaseSystemInfo'),
adaptView: require('./View'),
adaptContainerStrategy: require('./ContainerStrategy'),
});

View File

@ -0,0 +1,10 @@
require('./Audio');
require('./AudioEngine');
require('./DeviceMotionEvent');
require('./Editbox');
require('./Game');
require('./InputManager');
require('./AssetManager');
require('./Screen');
require('./Texture2D');
require('./misc');

View File

@ -0,0 +1 @@
cc.macro.DOWNLOAD_MAX_CONCURRENT = 10;

111
adapters/common/utils.js Normal file
View File

@ -0,0 +1,111 @@
const utils = {
/**
* @param {Object} target
* @param {Object} origin
* @param {String} methodName
* @param {String} targetMethodName
*/
cloneMethod (target, origin, methodName, targetMethodName) {
if (origin[methodName]) {
targetMethodName = targetMethodName || methodName;
target[targetMethodName] = origin[methodName].bind(origin);
}
},
/**
*
* @param {String} str
* @returns
*/
encode (str) {
let encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
const string = String(str);
let result = '';
let currentIndex = 0;
let sum = void 0;
while (string.charAt(0 | currentIndex) || (encodings = '=', currentIndex % 1)) {
currentIndex += 0.75;
const currentCode = string.charCodeAt(currentIndex);
if (currentCode > 255) {
// Cannot handle when it is greater than 255
throw new Error('"btoa" failed');
}
sum = sum << 8 | currentCode;
const encodeIndex = 63 & sum >> 8 - currentIndex % 1 * 8;
result += encodings.charAt(encodeIndex);
}
return result;
},
/**
*
* @param {String} str
*/
decode (str) {
const encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
let res = '';
const string = String(str).replace(/[=]+$/, '');
let o;
let r;
let i = 0;
let currentIndex = 0;
while (r = string.charAt(currentIndex)) {
currentIndex += 1;
r = encodings.indexOf(r);
if (~r) {
o = i % 4 ? 64 * o + r : r;
if (i++ % 4) {
res += String.fromCharCode(255 & o >> (-2 * i & 6));
}
}
}
return res;
},
/**
*
* @param {ArrayBuffer} buffer
*/
arrayBufferToBase64 (buffer) {
return utils.encode(utils.arrayBufferToString(buffer));
},
/**
*
* @param {String} base64
*/
base64ToArrayBuffer (base64) {
return utils.stringToArrayBuffer(utils.decode(base64));
},
/**
*
* @param {ArrayBuffer} buffer
*/
arrayBufferToString (buffer) {
let result = '';
const uintArray = new Uint8Array(buffer);
const byteLength = uintArray.byteLength;
for (let i = 0; i < byteLength; i++) {
result += String.fromCharCode(uintArray[i]);
}
return result;
},
/**
*
* @param {String} string
*/
stringToArrayBuffer (string) {
const length = string.length;
const uintArray = new Uint8Array(length);
for (let i = 0; i < length; i++) {
uintArray[i] = string.charCodeAt(i);
}
return uintArray.buffer;
},
};
module.exports = utils;

View File

@ -0,0 +1,252 @@
function DOMParser(options){
this.options = options ||{locator:{}};
}
DOMParser.prototype.parseFromString = function(source,mimeType){
var options = this.options;
var sax = new XMLReader();
var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
var errorHandler = options.errorHandler;
var locator = options.locator;
var defaultNSMap = options.xmlns||{};
var isHTML = /\/x?html?$/.test(mimeType);//mimeType.toLowerCase().indexOf('html') > -1;
var entityMap = isHTML?htmlEntity.entityMap:{'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"};
if(locator){
domBuilder.setDocumentLocator(locator)
}
sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
sax.domBuilder = options.domBuilder || domBuilder;
if(isHTML){
defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
}
defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
if(source){
sax.parse(source,defaultNSMap,entityMap);
}else{
sax.errorHandler.error("invalid doc source");
}
return domBuilder.doc;
}
function buildErrorHandler(errorImpl,domBuilder,locator){
if(!errorImpl){
if(domBuilder instanceof DOMHandler){
return domBuilder;
}
errorImpl = domBuilder ;
}
var errorHandler = {}
var isCallback = errorImpl instanceof Function;
locator = locator||{}
function build(key){
var fn = errorImpl[key];
if(!fn && isCallback){
fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl;
}
errorHandler[key] = fn && function(msg){
fn('[xmldom '+key+']\t'+msg+_locator(locator));
}||function(){};
}
build('warning');
build('error');
build('fatalError');
return errorHandler;
}
//console.log('#\n\n\n\n\n\n\n####')
/**
* +ContentHandler+ErrorHandler
* +LexicalHandler+EntityResolver2
* -DeclHandler-DTDHandler
*
* DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
* DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
* @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
*/
function DOMHandler() {
this.cdata = false;
}
function position(locator,node){
node.lineNumber = locator.lineNumber;
node.columnNumber = locator.columnNumber;
}
/**
* @see org.xml.sax.ContentHandler#startDocument
* @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
*/
DOMHandler.prototype = {
startDocument : function() {
this.doc = new DOMImplementation().createDocument(null, null, null);
if (this.locator) {
this.doc.documentURI = this.locator.systemId;
}
},
startElement:function(namespaceURI, localName, qName, attrs) {
var doc = this.doc;
var el = doc.createElementNS(namespaceURI, qName||localName);
var len = attrs.length;
appendElement(this, el);
this.currentElement = el;
this.locator && position(this.locator,el)
for (var i = 0 ; i < len; i++) {
var namespaceURI = attrs.getURI(i);
var value = attrs.getValue(i);
var qName = attrs.getQName(i);
var attr = doc.createAttributeNS(namespaceURI, qName);
this.locator &&position(attrs.getLocator(i),attr);
attr.value = attr.nodeValue = value;
el.setAttributeNode(attr)
}
},
endElement:function(namespaceURI, localName, qName) {
var current = this.currentElement
var tagName = current.tagName;
this.currentElement = current.parentNode;
},
startPrefixMapping:function(prefix, uri) {
},
endPrefixMapping:function(prefix) {
},
processingInstruction:function(target, data) {
var ins = this.doc.createProcessingInstruction(target, data);
this.locator && position(this.locator,ins)
appendElement(this, ins);
},
ignorableWhitespace:function(ch, start, length) {
},
characters:function(chars, start, length) {
chars = _toString.apply(this,arguments)
//console.log(chars)
if(chars){
if (this.cdata) {
var charNode = this.doc.createCDATASection(chars);
} else {
var charNode = this.doc.createTextNode(chars);
}
if(this.currentElement){
this.currentElement.appendChild(charNode);
}else if(/^\s*$/.test(chars)){
this.doc.appendChild(charNode);
//process xml
}
this.locator && position(this.locator,charNode)
}
},
skippedEntity:function(name) {
},
endDocument:function() {
this.doc.normalize();
},
setDocumentLocator:function (locator) {
if(this.locator = locator){// && !('lineNumber' in locator)){
locator.lineNumber = 0;
}
},
//LexicalHandler
comment:function(chars, start, length) {
chars = _toString.apply(this,arguments)
var comm = this.doc.createComment(chars);
this.locator && position(this.locator,comm)
appendElement(this, comm);
},
startCDATA:function() {
//used in characters() methods
this.cdata = true;
},
endCDATA:function() {
this.cdata = false;
},
startDTD:function(name, publicId, systemId) {
var impl = this.doc.implementation;
if (impl && impl.createDocumentType) {
var dt = impl.createDocumentType(name, publicId, systemId);
this.locator && position(this.locator,dt)
appendElement(this, dt);
}
},
/**
* @see org.xml.sax.ErrorHandler
* @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
*/
warning:function(error) {
console.warn('[xmldom warning]\t'+error,_locator(this.locator));
},
error:function(error) {
console.error('[xmldom error]\t'+error,_locator(this.locator));
},
fatalError:function(error) {
console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
throw error;
}
}
function _locator(l){
if(l){
return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
}
}
function _toString(chars,start,length){
if(typeof chars == 'string'){
return chars.substr(start,length)
}else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
if(chars.length >= start+length || start){
return new java.lang.String(chars,start,length)+'';
}
return chars;
}
}
/*
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
* used method of org.xml.sax.ext.LexicalHandler:
* #comment(chars, start, length)
* #startCDATA()
* #endCDATA()
* #startDTD(name, publicId, systemId)
*
*
* IGNORED method of org.xml.sax.ext.LexicalHandler:
* #endDTD()
* #startEntity(name)
* #endEntity(name)
*
*
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
* IGNORED method of org.xml.sax.ext.DeclHandler
* #attributeDecl(eName, aName, type, mode, value)
* #elementDecl(name, model)
* #externalEntityDecl(name, publicId, systemId)
* #internalEntityDecl(name, value)
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
* IGNORED method of org.xml.sax.EntityResolver2
* #resolveEntity(String name,String publicId,String baseURI,String systemId)
* #resolveEntity(publicId, systemId)
* #getExternalSubset(name, baseURI)
* @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
* IGNORED method of org.xml.sax.DTDHandler
* #notationDecl(name, publicId, systemId) {};
* #unparsedEntityDecl(name, publicId, systemId, notationName) {};
*/
"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
DOMHandler.prototype[key] = function(){return null}
})
/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
function appendElement (hander,node) {
if (!hander.currentElement) {
hander.doc.appendChild(node);
} else {
hander.currentElement.appendChild(node);
}
}//appendChild and setAttributeNS are preformance key
//if(typeof require == 'function'){
var htmlEntity = require('./entities');
var XMLReader = require('./sax').XMLReader;
var DOMImplementation = exports.DOMImplementation = require('./dom').DOMImplementation;
exports.XMLSerializer = require('./dom').XMLSerializer ;
exports.DOMParser = DOMParser;
//}

1246
adapters/common/xmldom/dom.js Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,244 @@
exports.entityMap = {
lt: '<',
gt: '>',
amp: '&',
quot: '"',
apos: "'",
Agrave: "À",
Aacute: "Á",
Acirc: "Â",
Atilde: "Ã",
Auml: "Ä",
Aring: "Å",
AElig: "Æ",
Ccedil: "Ç",
Egrave: "È",
Eacute: "É",
Ecirc: "Ê",
Euml: "Ë",
Igrave: "Ì",
Iacute: "Í",
Icirc: "Î",
Iuml: "Ï",
ETH: "Ð",
Ntilde: "Ñ",
Ograve: "Ò",
Oacute: "Ó",
Ocirc: "Ô",
Otilde: "Õ",
Ouml: "Ö",
Oslash: "Ø",
Ugrave: "Ù",
Uacute: "Ú",
Ucirc: "Û",
Uuml: "Ü",
Yacute: "Ý",
THORN: "Þ",
szlig: "ß",
agrave: "à",
aacute: "á",
acirc: "â",
atilde: "ã",
auml: "ä",
aring: "å",
aelig: "æ",
ccedil: "ç",
egrave: "è",
eacute: "é",
ecirc: "ê",
euml: "ë",
igrave: "ì",
iacute: "í",
icirc: "î",
iuml: "ï",
eth: "ð",
ntilde: "ñ",
ograve: "ò",
oacute: "ó",
ocirc: "ô",
otilde: "õ",
ouml: "ö",
oslash: "ø",
ugrave: "ù",
uacute: "ú",
ucirc: "û",
uuml: "ü",
yacute: "ý",
thorn: "þ",
yuml: "ÿ",
nbsp: " ",
iexcl: "¡",
cent: "¢",
pound: "£",
curren: "¤",
yen: "¥",
brvbar: "¦",
sect: "§",
uml: "¨",
copy: "©",
ordf: "ª",
laquo: "«",
not: "¬",
shy: "­­",
reg: "®",
macr: "¯",
deg: "°",
plusmn: "±",
sup2: "²",
sup3: "³",
acute: "´",
micro: "µ",
para: "¶",
middot: "·",
cedil: "¸",
sup1: "¹",
ordm: "º",
raquo: "»",
frac14: "¼",
frac12: "½",
frac34: "¾",
iquest: "¿",
times: "×",
divide: "÷",
forall: "∀",
part: "∂",
exist: "∃",
empty: "∅",
nabla: "∇",
isin: "∈",
notin: "∉",
ni: "∋",
prod: "∏",
sum: "∑",
minus: "",
lowast: "",
radic: "√",
prop: "∝",
infin: "∞",
ang: "∠",
and: "∧",
or: "",
cap: "∩",
cup: "",
'int': "∫",
there4: "∴",
sim: "",
cong: "≅",
asymp: "≈",
ne: "≠",
equiv: "≡",
le: "≤",
ge: "≥",
sub: "⊂",
sup: "⊃",
nsub: "⊄",
sube: "⊆",
supe: "⊇",
oplus: "⊕",
otimes: "⊗",
perp: "⊥",
sdot: "⋅",
Alpha: "Α",
Beta: "Β",
Gamma: "Γ",
Delta: "Δ",
Epsilon: "Ε",
Zeta: "Ζ",
Eta: "Η",
Theta: "Θ",
Iota: "Ι",
Kappa: "Κ",
Lambda: "Λ",
Mu: "Μ",
Nu: "Ν",
Xi: "Ξ",
Omicron: "Ο",
Pi: "Π",
Rho: "Ρ",
Sigma: "Σ",
Tau: "Τ",
Upsilon: "Υ",
Phi: "Φ",
Chi: "Χ",
Psi: "Ψ",
Omega: "Ω",
alpha: "α",
beta: "β",
gamma: "γ",
delta: "δ",
epsilon: "ε",
zeta: "ζ",
eta: "η",
theta: "θ",
iota: "ι",
kappa: "κ",
lambda: "λ",
mu: "μ",
nu: "ν",
xi: "ξ",
omicron: "ο",
pi: "π",
rho: "ρ",
sigmaf: "ς",
sigma: "σ",
tau: "τ",
upsilon: "υ",
phi: "φ",
chi: "χ",
psi: "ψ",
omega: "ω",
thetasym: "ϑ",
upsih: "ϒ",
piv: "ϖ",
OElig: "Œ",
oelig: "œ",
Scaron: "Š",
scaron: "š",
Yuml: "Ÿ",
fnof: "ƒ",
circ: "ˆ",
tilde: "˜",
ensp: "",
emsp: "",
thinsp: "",
zwnj: "",
zwj: "",
lrm: "",
rlm: "",
ndash: "",
mdash: "—",
lsquo: "",
rsquo: "",
sbquo: "",
ldquo: "“",
rdquo: "”",
bdquo: "„",
dagger: "†",
Dagger: "‡",
bull: "•",
hellip: "…",
permil: "‰",
prime: "",
Prime: "″",
lsaquo: "",
rsaquo: "",
oline: "‾",
euro: "€",
trade: "™",
larr: "←",
uarr: "↑",
rarr: "→",
darr: "↓",
harr: "↔",
crarr: "↵",
lceil: "⌈",
rceil: "⌉",
lfloor: "⌊",
rfloor: "⌋",
loz: "◊",
spades: "♠",
clubs: "♣",
hearts: "♥",
diams: "♦"
};
//for(var n in exports.entityMap){console.log(exports.entityMap[n].charCodeAt())}

View File

@ -0,0 +1,616 @@
//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
//[5] Name ::= NameStartChar (NameChar)*
var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF
var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
var S_TAG = 0;//tag name offerring
var S_ATTR = 1;//attr name offerring
var S_ATTR_SPACE=2;//attr name end and space offer
var S_EQ = 3;//=space?
var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only)
var S_ATTR_END = 5;//attr value end and no space(quot end)
var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer)
var S_TAG_CLOSE = 7;//closed el<el />
function XMLReader(){
}
XMLReader.prototype = {
parse:function(source,defaultNSMap,entityMap){
var domBuilder = this.domBuilder;
domBuilder.startDocument();
_copy(defaultNSMap ,defaultNSMap = {})
parse(source,defaultNSMap,entityMap,
domBuilder,this.errorHandler);
domBuilder.endDocument();
}
}
function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
function fixedFromCharCode(code) {
// String.prototype.fromCharCode does not supports
// > 2 bytes unicode chars directly
if (code > 0xffff) {
code -= 0x10000;
var surrogate1 = 0xd800 + (code >> 10)
, surrogate2 = 0xdc00 + (code & 0x3ff);
return String.fromCharCode(surrogate1, surrogate2);
} else {
return String.fromCharCode(code);
}
}
function entityReplacer(a){
var k = a.slice(1,-1);
if(k in entityMap){
return entityMap[k];
}else if(k.charAt(0) === '#'){
return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
}else{
errorHandler.error('entity not found:'+a);
return a;
}
}
function appendText(end){//has some bugs
if(end>start){
var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
locator&&position(start);
domBuilder.characters(xt,0,end-start);
start = end
}
}
function position(p,m){
while(p>=lineEnd && (m = linePattern.exec(source))){
lineStart = m.index;
lineEnd = lineStart + m[0].length;
locator.lineNumber++;
//console.log('line++:',locator,startPos,endPos)
}
locator.columnNumber = p-lineStart+1;
}
var lineStart = 0;
var lineEnd = 0;
var linePattern = /.*(?:\r\n?|\n)|.*$/g
var locator = domBuilder.locator;
var parseStack = [{currentNSMap:defaultNSMapCopy}]
var closeMap = {};
var start = 0;
while(true){
try{
var tagStart = source.indexOf('<',start);
if(tagStart<0){
if(!source.substr(start).match(/^\s*$/)){
var doc = domBuilder.doc;
var text = doc.createTextNode(source.substr(start));
doc.appendChild(text);
domBuilder.currentElement = text;
}
return;
}
if(tagStart>start){
appendText(tagStart);
}
switch(source.charAt(tagStart+1)){
case '/':
var end = source.indexOf('>',tagStart+3);
var tagName = source.substring(tagStart+2,end);
var config = parseStack.pop();
if(end<0){
tagName = source.substring(tagStart+2).replace(/[\s<].*/,'');
//console.error('#@@@@@@'+tagName)
errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName);
end = tagStart+1+tagName.length;
}else if(tagName.match(/\s</)){
tagName = tagName.replace(/[\s<].*/,'');
errorHandler.error("end tag name: "+tagName+' maybe not complete');
end = tagStart+1+tagName.length;
}
//console.error(parseStack.length,parseStack)
//console.error(config);
var localNSMap = config.localNSMap;
var endMatch = config.tagName == tagName;
var endIgnoreCaseMach = endMatch || config.tagName&&config.tagName.toLowerCase() == tagName.toLowerCase()
if(endIgnoreCaseMach){
domBuilder.endElement(config.uri,config.localName,tagName);
if(localNSMap){
for(var prefix in localNSMap){
domBuilder.endPrefixMapping(prefix) ;
}
}
if(!endMatch){
errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
}
}else{
parseStack.push(config)
}
end++;
break;
// end elment
case '?':// <?...?>
locator&&position(tagStart);
end = parseInstruction(source,tagStart,domBuilder);
break;
case '!':// <!doctype,<![CDATA,<!--
locator&&position(tagStart);
end = parseDCC(source,tagStart,domBuilder,errorHandler);
break;
default:
locator&&position(tagStart);
var el = new ElementAttributes();
var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
//elStartEnd
var end = parseElementStartPart(source,tagStart,el,currentNSMap,entityReplacer,errorHandler);
var len = el.length;
if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
el.closed = true;
if(!entityMap.nbsp){
errorHandler.warning('unclosed xml attribute');
}
}
if(locator && len){
var locator2 = copyLocator(locator,{});
//try{//attribute position fixed
for(var i = 0;i<len;i++){
var a = el[i];
position(a.offset);
a.locator = copyLocator(locator,{});
}
//}catch(e){console.error('@@@@@'+e)}
domBuilder.locator = locator2
if(appendElement(el,domBuilder,currentNSMap)){
parseStack.push(el)
}
domBuilder.locator = locator;
}else{
if(appendElement(el,domBuilder,currentNSMap)){
parseStack.push(el)
}
}
if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder)
}else{
end++;
}
}
}catch(e){
errorHandler.error('element parse error: '+e)
//errorHandler.error('element parse error: '+e);
end = -1;
//throw e;
}
if(end>start){
start = end;
}else{
//TODO: 这里有可能sax回退有位置错误风险
appendText(Math.max(tagStart,start)+1);
}
}
}
function copyLocator(f,t){
t.lineNumber = f.lineNumber;
t.columnNumber = f.columnNumber;
return t;
}
/**
* @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
* @return end of the elementStartPart(end of elementEndPart for selfClosed el)
*/
function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){
var attrName;
var value;
var p = ++start;
var s = S_TAG;//status
while(true){
var c = source.charAt(p);
switch(c){
case '=':
if(s === S_ATTR){//attrName
attrName = source.slice(start,p);
s = S_EQ;
}else if(s === S_ATTR_SPACE){
s = S_EQ;
}else{
//fatalError: equal must after attrName or space after attrName
throw new Error('attribute equal must after attrName');
}
break;
case '\'':
case '"':
if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE
){//equal
if(s === S_ATTR){
errorHandler.warning('attribute value must after "="')
attrName = source.slice(start,p)
}
start = p+1;
p = source.indexOf(c,start)
if(p>0){
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
el.add(attrName,value,start-1);
s = S_ATTR_END;
}else{
//fatalError: no end quot match
throw new Error('attribute value no end \''+c+'\' match');
}
}else if(s == S_ATTR_NOQUOT_VALUE){
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
//console.log(attrName,value,start,p)
el.add(attrName,value,start);
//console.dir(el)
errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
start = p+1;
s = S_ATTR_END
}else{
//fatalError: no equal before
throw new Error('attribute value must after "="');
}
break;
case '/':
switch(s){
case S_TAG:
el.setTagName(source.slice(start,p));
case S_ATTR_END:
case S_TAG_SPACE:
case S_TAG_CLOSE:
s =S_TAG_CLOSE;
el.closed = true;
case S_ATTR_NOQUOT_VALUE:
case S_ATTR:
case S_ATTR_SPACE:
break;
//case S_EQ:
default:
throw new Error("attribute invalid close char('/')")
}
break;
case ''://end document
//throw new Error('unexpected end of input')
errorHandler.error('unexpected end of input');
if(s == S_TAG){
el.setTagName(source.slice(start,p));
}
return p;
case '>':
switch(s){
case S_TAG:
el.setTagName(source.slice(start,p));
case S_ATTR_END:
case S_TAG_SPACE:
case S_TAG_CLOSE:
break;//normal
case S_ATTR_NOQUOT_VALUE://Compatible state
case S_ATTR:
value = source.slice(start,p);
if(value.slice(-1) === '/'){
el.closed = true;
value = value.slice(0,-1)
}
case S_ATTR_SPACE:
if(s === S_ATTR_SPACE){
value = attrName;
}
if(s == S_ATTR_NOQUOT_VALUE){
errorHandler.warning('attribute "'+value+'" missed quot(")!!');
el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start)
}else{
if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !value.match(/^(?:disabled|checked|selected)$/i)){
errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!')
}
el.add(value,value,start)
}
break;
case S_EQ:
throw new Error('attribute value missed!!');
}
// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
return p;
/*xml space '\x20' | #x9 | #xD | #xA; */
case '\u0080':
c = ' ';
default:
if(c<= ' '){//space
switch(s){
case S_TAG:
el.setTagName(source.slice(start,p));//tagName
s = S_TAG_SPACE;
break;
case S_ATTR:
attrName = source.slice(start,p)
s = S_ATTR_SPACE;
break;
case S_ATTR_NOQUOT_VALUE:
var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
errorHandler.warning('attribute "'+value+'" missed quot(")!!');
el.add(attrName,value,start)
case S_ATTR_END:
s = S_TAG_SPACE;
break;
//case S_TAG_SPACE:
//case S_EQ:
//case S_ATTR_SPACE:
// void();break;
//case S_TAG_CLOSE:
//ignore warning
}
}else{//not space
//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE
//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE
switch(s){
//case S_TAG:void();break;
//case S_ATTR:void();break;
//case S_ATTR_NOQUOT_VALUE:void();break;
case S_ATTR_SPACE:
var tagName = el.tagName;
if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !attrName.match(/^(?:disabled|checked|selected)$/i)){
errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!')
}
el.add(attrName,attrName,start);
start = p;
s = S_ATTR;
break;
case S_ATTR_END:
errorHandler.warning('attribute space is required"'+attrName+'"!!')
case S_TAG_SPACE:
s = S_ATTR;
start = p;
break;
case S_EQ:
s = S_ATTR_NOQUOT_VALUE;
start = p;
break;
case S_TAG_CLOSE:
throw new Error("elements closed character '/' and '>' must be connected to");
}
}
}//end outer switch
//console.log('p++',p)
p++;
}
}
/**
* @return true if has new namespace define
*/
function appendElement(el,domBuilder,currentNSMap){
var tagName = el.tagName;
var localNSMap = null;
//var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
var i = el.length;
while(i--){
var a = el[i];
var qName = a.qName;
var value = a.value;
var nsp = qName.indexOf(':');
if(nsp>0){
var prefix = a.prefix = qName.slice(0,nsp);
var localName = qName.slice(nsp+1);
var nsPrefix = prefix === 'xmlns' && localName
}else{
localName = qName;
prefix = null
nsPrefix = qName === 'xmlns' && ''
}
//can not set prefix,because prefix !== ''
a.localName = localName ;
//prefix == null for no ns prefix attribute
if(nsPrefix !== false){//hack!!
if(localNSMap == null){
localNSMap = {}
//console.log(currentNSMap,0)
_copy(currentNSMap,currentNSMap={})
//console.log(currentNSMap,1)
}
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
a.uri = 'http://www.w3.org/2000/xmlns/'
domBuilder.startPrefixMapping(nsPrefix, value)
}
}
var i = el.length;
while(i--){
a = el[i];
var prefix = a.prefix;
if(prefix){//no prefix attribute has no namespace
if(prefix === 'xml'){
a.uri = 'http://www.w3.org/XML/1998/namespace';
}if(prefix !== 'xmlns'){
a.uri = currentNSMap[prefix || '']
//{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
}
}
}
var nsp = tagName.indexOf(':');
if(nsp>0){
prefix = el.prefix = tagName.slice(0,nsp);
localName = el.localName = tagName.slice(nsp+1);
}else{
prefix = null;//important!!
localName = el.localName = tagName;
}
//no prefix element has default namespace
var ns = el.uri = currentNSMap[prefix || ''];
domBuilder.startElement(ns,localName,tagName,el);
//endPrefixMapping and startPrefixMapping have not any help for dom builder
//localNSMap = null
if(el.closed){
domBuilder.endElement(ns,localName,tagName);
if(localNSMap){
for(prefix in localNSMap){
domBuilder.endPrefixMapping(prefix)
}
}
}else{
el.currentNSMap = currentNSMap;
el.localNSMap = localNSMap;
//parseStack.push(el);
return true;
}
}
function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
if(/^(?:script|textarea)$/i.test(tagName)){
var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
var text = source.substring(elStartEnd+1,elEndStart);
if(/[&<]/.test(text)){
if(/^script$/i.test(tagName)){
//if(!/\]\]>/.test(text)){
//lexHandler.startCDATA();
domBuilder.characters(text,0,text.length);
//lexHandler.endCDATA();
return elEndStart;
//}
}//}else{//text area
text = text.replace(/&#?\w+;/g,entityReplacer);
domBuilder.characters(text,0,text.length);
return elEndStart;
//}
}
}
return elStartEnd+1;
}
function fixSelfClosed(source,elStartEnd,tagName,closeMap){
//if(tagName in closeMap){
var pos = closeMap[tagName];
if(pos == null){
//console.log(tagName)
pos = source.lastIndexOf('</'+tagName+'>')
if(pos<elStartEnd){//忘记闭合
pos = source.lastIndexOf('</'+tagName)
}
closeMap[tagName] =pos
}
return pos<elStartEnd;
//}
}
function _copy(source,target){
for(var n in source){target[n] = source[n]}
}
function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
var next= source.charAt(start+2)
switch(next){
case '-':
if(source.charAt(start + 3) === '-'){
var end = source.indexOf('-->',start+4);
//append comment source.substring(4,end)//<!--
if(end>start){
domBuilder.comment(source,start+4,end-start-4);
return end+3;
}else{
errorHandler.error("Unclosed comment");
return -1;
}
}else{
//error
return -1;
}
default:
if(source.substr(start+3,6) == 'CDATA['){
var end = source.indexOf(']]>',start+9);
domBuilder.startCDATA();
domBuilder.characters(source,start+9,end-start-9);
domBuilder.endCDATA()
return end+3;
}
//<!DOCTYPE
//startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
var matchs = split(source,start);
var len = matchs.length;
if(len>1 && /!doctype/i.test(matchs[0][0])){
var name = matchs[1][0];
var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0]
var sysid = len>4 && matchs[4][0];
var lastMatch = matchs[len-1]
domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
domBuilder.endDTD();
return lastMatch.index+lastMatch[0].length
}
}
return -1;
}
function parseInstruction(source,start,domBuilder){
var end = source.indexOf('?>',start);
if(end){
var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
if(match){
var len = match[0].length;
domBuilder.processingInstruction(match[1], match[2]) ;
return end+2;
}else{//error
return -1;
}
}
return -1;
}
/**
* @param source
*/
function ElementAttributes(source){
}
ElementAttributes.prototype = {
setTagName:function(tagName){
if(!tagNamePattern.test(tagName)){
throw new Error('invalid tagName:'+tagName)
}
this.tagName = tagName
},
add:function(qName,value,offset){
if(!tagNamePattern.test(qName)){
throw new Error('invalid attribute:'+qName)
}
this[this.length++] = {qName:qName,value:value,offset:offset}
},
length:0,
getLocalName:function(i){return this[i].localName},
getLocator:function(i){return this[i].locator},
getQName:function(i){return this[i].qName},
getURI:function(i){return this[i].uri},
getValue:function(i){return this[i].value}
// ,getIndex:function(uri, localName)){
// if(localName){
//
// }else{
// var qName = uri
// }
// },
// getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
// getType:function(uri,localName){}
// getType:function(i){},
}
function split(source,start){
var match;
var buf = [];
var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
reg.lastIndex = start;
reg.exec(source);//skip <
while(match = reg.exec(source)){
buf.push(match);
if(match[1])return buf;
}
}
exports.XMLReader = XMLReader;

59
adapters/modules.json Normal file
View File

@ -0,0 +1,59 @@
{
"Core": [],
"Canvas": [],
"Sprite": [],
"Label": [
"./platforms/alipay/wrapper/engine/Label.js"
],
"Audio": [
"./common/engine/Audio.js",
"./common/engine/AudioEngine.js",
"./platforms/alipay/wrapper/engine/AudioEngine.js"
],
"AudioSource": [],
"Action": [],
"Animation": [],
"Button": [],
"Canvas Renderer": [],
"Collider": [],
"Dynamic Atlas": [],
"DragonBones": [],
"EditBox": [
"./common/engine/Editbox.js"
],
"Graphics": [],
"Geom Utils": [],
"Intersection": [],
"Layout": [],
"Label Effect": [],
"Mask": [],
"Mesh": [],
"MotionStreak": [],
"NodePool": [],
"Native Socket": [],
"Physics": [],
"PageView": [],
"PageViewIndicator": [],
"ProgressBar": [],
"ParticleSystem": [],
"RichText": [],
"Renderer Texture": [],
"Slider": [],
"ScrollBar": [],
"ScrollView": [],
"Spine Skeleton": [],
"StudioComponent": [],
"Toggle": [],
"TiledMap": [],
"VideoPlayer": [
"./platforms/wechat/wrapper/engine/VideoPlayer.js"
],
"Widget": [],
"WebView": [],
"WebGL Renderer": [],
"3D": [],
"3D Primitive": [],
"WechatSubContext": [],
"SwanSubContext": [],
"TypeScript Polyfill": []
}

4
adapters/package.json Normal file
View File

@ -0,0 +1,4 @@
{
"name": "adapters",
"version": "1.0.0"
}

View File

@ -0,0 +1,18 @@
const _global = window;
const adapter = _global.__globalAdapter = {};
Object.assign(adapter, {
init () {
require('./wrapper/builtin');
_global.DOMParser = require('../../common/xmldom/dom-parser').DOMParser;
require('./wrapper/unify');
require('./wrapper/fs-utils');
require('../../common/engine/globalAdapter');
require('./wrapper/systemInfo');
},
adaptEngine () {
require('../../common/engine');
require('./wrapper/engine');
},
});

View File

@ -0,0 +1,11 @@
let moduleMap = {
// tail
};
window.__cocos_require__ = function (moduleName) {
let func = moduleMap[moduleName];
if (!func) {
throw new Error(`cannot find module ${moduleName}`);
}
return func();
};

View File

@ -0,0 +1,18 @@
require('adapter-js-path');
__globalAdapter.init();
require('cocos2d-js-path');
require('physics-js-path');
__globalAdapter.adaptEngine();
require('./ccRequire');
require('./src/settings');
// Introduce Cocos Service here
require('./main'); // TODO: move to common
// Adjust devicePixelRatio
cc.view._maxPixelRatio = 4;
// Release Image objects after uploaded gl texture
cc.macro.CLEANUP_IMAGE_CACHE = true;
window.boot();

View File

@ -0,0 +1,10 @@
{
"screenOrientation": "landscape",
"networkTimeout": {
"request": 5000,
"connectSocket": 5000,
"upload": 5000,
"download": 5000
},
"showStatusBar": false
}

View File

@ -0,0 +1,64 @@
window.boot = function () {
var settings = window._CCSettings;
window._CCSettings = undefined;
var onStart = function () {
cc.view.enableRetina(true);
cc.view.resizeWithBrowserSize(true);
var launchScene = settings.launchScene;
// load scene
cc.director.loadScene(launchScene, null,
function () {
console.log('Success to load scene: ' + launchScene);
}
);
};
var option = {
id: 'GameCanvas',
debugMode: settings.debug ? cc.debug.DebugMode.INFO : cc.debug.DebugMode.ERROR,
showFPS: settings.debug,
frameRate: 60,
groupList: settings.groupList,
collisionMatrix: settings.collisionMatrix,
}
cc.assetManager.init({
bundleVers: settings.bundleVers,
subpackages: settings.subpackages,
remoteBundles: settings.remoteBundles,
server: settings.server
});
var RESOURCES = cc.AssetManager.BuiltinBundleName.RESOURCES;
var INTERNAL = cc.AssetManager.BuiltinBundleName.INTERNAL;
var MAIN = cc.AssetManager.BuiltinBundleName.MAIN;
var START_SCENE = cc.AssetManager.BuiltinBundleName.START_SCENE;
var bundleRoot = [INTERNAL];
settings.hasResourcesBundle && bundleRoot.push(RESOURCES);
settings.hasStartSceneBundle && bundleRoot.push(MAIN);
var count = 0;
function cb (err) {
if (err) return console.error(err.message, err.stack);
count++;
if (count === bundleRoot.length + 1) {
// if there is start-scene bundle. should load start-scene bundle in the last stage.
// Otherwise the main bundle should be the last
cc.assetManager.loadBundle(settings.hasStartSceneBundle ? START_SCENE : MAIN, function (err) {
if (!err) cc.game.run(option, onStart);
});
}
}
// load plugins
cc.assetManager.loadScript(settings.jsList.map(function (x) { return 'src/' + x;}), cb);
// load bundles
for (var i = 0; i < bundleRoot.length; i++) {
cc.assetManager.loadBundle(bundleRoot[i], cb);
}
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
if (cc && cc.audioEngine) {
cc.audioEngine._maxAudioInstance = 6;
}

View File

@ -0,0 +1,55 @@
if (cc && cc.Label) {
const gfx = cc.gfx;
const Label = cc.Label;
// shared label canvas
let _sharedLabelCanvas = document.createElement('canvas');
let _sharedLabelCanvasCtx = _sharedLabelCanvas.getContext('2d');
let canvasData = {
canvas: _sharedLabelCanvas,
context: _sharedLabelCanvasCtx,
};
cc.game.on(cc.game.EVENT_ENGINE_INITED, function () {
Object.assign(Label._canvasPool, {
get() {
return canvasData;
},
put() {
// do nothing
}
});
});
let _originUpdateMaterial = Label.prototype._updateMaterialWebgl;
// fix ttf font black border
Object.assign(Label.prototype, {
_updateMaterialWebgl () {
_originUpdateMaterial.call(this);
// init blend factor
let material = this._materials[0];
if (!this._frame || !material) {
return;
}
let dstBlendFactor = cc.macro.BlendFactor.ONE_MINUS_SRC_ALPHA;
let srcBlendFactor;
if (!(__globalAdapter.isDevTool || this.font instanceof cc.BitmapFont)) {
// Premultiplied alpha on runtime
srcBlendFactor = cc.macro.BlendFactor.ONE;
}
else {
srcBlendFactor = cc.macro.BlendFactor.SRC_ALPHA;
}
// set blend func
material.effect.setBlend(
true,
gfx.BLEND_FUNC_ADD,
srcBlendFactor, dstBlendFactor,
gfx.BLEND_FUNC_ADD,
srcBlendFactor, dstBlendFactor,
);
},
});
}

View File

@ -0,0 +1,2 @@
require('./Label');
require('./AudioEngine');

View File

@ -0,0 +1,262 @@
/****************************************************************************
Copyright (c) 2017-2019 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
var fs = my.getFileSystemManager ? my.getFileSystemManager() : null;
var outOfStorageRegExp = /the maximum size of the file storage/; // not exactly right
var fsUtils = {
fs,
isOutOfStorage (errMsg) {
return outOfStorageRegExp.test(errMsg);
},
getUserDataPath () {
return my.env.USER_DATA_PATH;
},
checkFsValid () {
if (!fs) {
console.warn('Can not get the file system!');
return false;
}
return true;
},
deleteFile (filePath, onComplete) {
fs.unlink({
filePath: filePath,
success: function () {
onComplete && onComplete(null);
},
fail: function (res) {
console.warn(`Delete file failed: path: ${filePath} message: ${res.errorMessage}`);
onComplete && onComplete(new Error(res.errorMessage));
}
});
},
downloadFile (remoteUrl, filePath, header, onProgress, onComplete) {
var options = {
url: remoteUrl,
success: function (res) {
if (!filePath) {
onComplete && onComplete(null, res.apFilePath);
}
else {
fsUtils.copyFile(res.apFilePath, filePath, onComplete);
}
},
fail: function (res) {
console.warn(`Download file failed: path: ${remoteUrl} message: ${res.errorMessage}`);
onComplete && onComplete(new Error(res.errorMessage), null);
}
}
if (header) options.header = header;
var task = my.downloadFile(options);
onProgress && task.onProgressUpdate(onProgress);
},
saveFile (srcPath, destPath, onComplete) {
// Hack, seems like my.saveFile dose not work
fsUtils.copyFile(srcPath, destPath, onComplete);
},
copyFile (srcPath, destPath, onComplete) {
fs.copyFile({
srcPath: srcPath,
destPath: destPath,
success: function () {
onComplete && onComplete(null);
},
fail: function (res) {
console.warn(`Copy file failed: path: ${srcPath} message: ${res.errorMessage}`);
onComplete && onComplete(new Error(res.errorMessage));
}
});
},
writeFile (path, data, encoding, onComplete) {
fs.writeFile({
filePath: path,
encoding: encoding,
data: data,
success: function () {
onComplete && onComplete(null);
},
fail: function (res) {
console.warn(`Write file failed: path: ${path} message: ${res.errorMessage}`);
onComplete && onComplete(new Error(res.errorMessage));
}
});
},
writeFileSync (path, data, encoding) {
try {
fs.writeFileSync({
filePath: path,
data: data,
encoding: encoding,
});
return null;
}
catch (e) {
console.warn(`Write file failed: path: ${path} message: ${e.message}`);
return new Error(e.message);
}
},
readFile (filePath, encoding, onComplete) {
fs.readFile({
filePath: filePath,
encoding: encoding,
success: function (res) {
onComplete && onComplete(null, res.data);
},
fail: function (res) {
console.warn(`Read file failed: path: ${filePath} message: ${res.errorMessage}`);
onComplete && onComplete (new Error(res.errorMessage), null);
}
});
},
readDir (filePath, onComplete) {
fs.readdir({
dirPath: filePath,
success: function (res) {
onComplete && onComplete(null, res.files);
},
fail: function (res) {
console.warn(`Read directory failed: path: ${filePath} message: ${res.errorMessage}`);
onComplete && onComplete(new Error(res.errorMessage), null);
}
});
},
readText (filePath, onComplete) {
fsUtils.readFile(filePath, 'utf8', onComplete);
},
readArrayBuffer (filePath, onComplete) {
fsUtils.readFile(filePath, '', onComplete);
},
readJson (filePath, onComplete) {
fsUtils.readFile(filePath, 'utf8', function (err, text) {
var out = null;
if (!err) {
try {
out = JSON.parse(text);
}
catch (e) {
console.warn(`Read json failed: path: ${filePath} message: ${e.message}`);
err = new Error(e.message);
}
}
onComplete && onComplete(err, out);
});
},
readJsonSync (path) {
try {
var res = fs.readFileSync({
filePath: path,
encoding: 'utf8',
});
return JSON.parse(res.data);
}
catch (e) {
console.warn(`Read json failed: path: ${path} message: ${e.message}`);
return new Error(e.message);
}
},
makeDirSync (path, recursive) {
try {
fs.mkdirSync({
dirPath: path,
recursive: recursive,
});
return null;
}
catch (e) {
console.warn(`Make directory failed: path: ${path} message: ${e.message}`);
return new Error(e.message);
}
},
rmdirSync (dirPath, recursive) {
try {
fs.rmdirSync({ dirPath, recursive });
}
catch (e) {
console.warn(`rm directory failed: path: ${dirPath} message: ${e.message}`);
return new Error(e.message);
}
},
exists (filePath, onComplete) {
fs.access({
path: filePath,
success: function () {
onComplete && onComplete(true);
},
fail: function () {
onComplete && onComplete(false);
}
});
},
loadSubpackage(name, onProgress, onComplete) {
var task = my.loadSubpackage({
name,
success: (res) => {
onComplete && onComplete();
},
fail : (res)=>{
console.warn(`Load Subpackage failed: path: ${name} message: ${res.errMsg}`);
onComplete && onComplete(new Error(`Failed to load subpackage ${name}: ${res.errMsg}`));
}
});
onProgress && task.onProgressUpdate(onProgress);
return task;
},
unzip (zipFilePath, targetPath, onComplete) {
fs.unzip({
zipFilePath,
targetPath,
success () {
onComplete && onComplete(null);
},
fail (res) {
console.warn(`unzip failed: path: ${zipFilePath} message: ${res.errorMessage}`);
onComplete && onComplete(new Error('unzip failed: ' + res.errorMessage));
},
})
},
};
window.fsUtils = module.exports = fsUtils;

View File

@ -0,0 +1,10 @@
const adapter = window.__globalAdapter;
let adaptSysFunc = adapter.adaptSys;
Object.assign(adapter, {
// Extend adaptSys interface
adaptSys (sys) {
adaptSysFunc.call(this, sys);
sys.platform = sys.ALIPAY_GAME;
},
});

View File

@ -0,0 +1,102 @@
const utils = require('../../../common/utils');
if (window.__globalAdapter) {
let globalAdapter = window.__globalAdapter;
// SystemInfo
globalAdapter.isSubContext = false; // sub context not supported
globalAdapter.isDevTool = window.navigator && (/AlipayIDE/.test(window.navigator.userAgent));
utils.cloneMethod(globalAdapter, my, 'getSystemInfoSync');
// TouchEvent
// my.onTouchStart register touch event listner on body
// need to register on canvas
globalAdapter.onTouchStart = function (cb) {
window.canvas.addEventListener('touchstart', function (res) {
cb && cb(res);
});
};
globalAdapter.onTouchMove = function (cb) {
window.canvas.addEventListener('touchmove', function (res) {
cb && cb(res);
});
};
globalAdapter.onTouchEnd = function (cb) {
window.canvas.addEventListener('touchend', function (res) {
cb && cb(res);
});
};
globalAdapter.onTouchCancel = function (cb) {
window.canvas.addEventListener('touchcancel', function (res) {
cb && cb(res);
});
};
// Audio
globalAdapter.createInnerAudioContext = function() {
let audio = my.createInnerAudioContext();
audio.onCanplay = audio.onCanPlay.bind(audio);
return audio;
};
// FrameRate
utils.cloneMethod(globalAdapter, my, 'setPreferredFramesPerSecond');
// Keyboard
utils.cloneMethod(globalAdapter, my, 'showKeyboard');
utils.cloneMethod(globalAdapter, my, 'hideKeyboard');
utils.cloneMethod(globalAdapter, my, 'updateKeyboard');
utils.cloneMethod(globalAdapter, my, 'onKeyboardInput');
utils.cloneMethod(globalAdapter, my, 'onKeyboardConfirm');
utils.cloneMethod(globalAdapter, my, 'onKeyboardComplete');
utils.cloneMethod(globalAdapter, my, 'offKeyboardInput');
utils.cloneMethod(globalAdapter, my, 'offKeyboardConfirm');
utils.cloneMethod(globalAdapter, my, 'offKeyboardComplete');
// Message
utils.cloneMethod(globalAdapter, my, 'getOpenDataContext');
utils.cloneMethod(globalAdapter, my, 'onMessage');
// SharedCanvas
utils.cloneMethod(globalAdapter, my, 'getSharedCanvas');
// Font
utils.cloneMethod(globalAdapter, my, 'loadFont');
// hide show Event
utils.cloneMethod(globalAdapter, my, 'onShow');
utils.cloneMethod(globalAdapter, my, 'onHide');
// Accelerometer
let accelerometerCallback = null;
let systemInfo = my.getSystemInfoSync();
let windowWidth = systemInfo.windowWidth;
let windowHeight = systemInfo.windowHeight;
let isLandscape = windowWidth > windowHeight;
function accelerometerChangeCallback (res, cb) {
let resClone = {};
let x = res.x;
let y = res.y;
if (isLandscape) {
let tmp = x;
x = -y;
y = tmp;
}
resClone.x = x;
resClone.y = y;
resClone.z = res.z;
accelerometerCallback && accelerometerCallback(resClone);
}
Object.assign(globalAdapter, {
startAccelerometer (cb) {
accelerometerCallback = cb;
my.onAccelerometerChange && my.onAccelerometerChange(accelerometerChangeCallback);
},
stopAccelerometer () {
my.offAccelerometerChange && my.offAccelerometerChange(accelerometerChangeCallback);
},
});
}

View File

@ -0,0 +1,58 @@
const _global = GameGlobal;
const adapter = _global.__globalAdapter = {};
Object.assign(adapter, {
init () {
require('./wrapper/builtin');
_global.DOMParser = require('../../common/xmldom/dom-parser').DOMParser;
require('./wrapper/unify');
require('./wrapper/fs-utils');
require('../../common/engine/globalAdapter');
require('./wrapper/systemInfo');
},
adaptEngine () {
require('../../common/engine');
require('./wrapper/engine');
require('./wrapper/sub-context-adapter');
},
handleSystemInfo (cb) {
if (swan.getOpenDataContext) {
swan.getOpenDataContext().postMessage({
fromAdapter: true,
event: 'main-context-info',
sysInfo: __globalAdapter.getSystemInfoSync(), // send system info to open data context
innerWidth: window.innerWidth,
innerHeight: window.innerHeight,
devicePixelRatio: window.devicePixelRatio,
});
cb && cb();
}
else {
swan.onMessage(function (data) {
if (data.fromAdapter) {
if (data.event === 'main-context-info') {
GameGlobal._env = data.sysInfo; // revieve system info from main context
Object.defineProperties(window, {
'innerWidth': {
value: data.innerWidth,
enumerable: true,
},
'innerHeight': {
value: data.innerHeight,
enumerable: true,
},
'devicePixelRatio': {
value: data.devicePixelRatio,
enumerable: true,
},
});
cb && cb();
}
}
});
}
},
});

View File

@ -0,0 +1,11 @@
let moduleMap = {
// tail
};
window.__cocos_require__ = function (moduleName) {
let func = moduleMap[moduleName];
if (!func) {
throw new Error(`cannot find module ${moduleName}`);
}
return func();
};

View File

@ -0,0 +1,24 @@
require('adapter-js-path');
__globalAdapter.init();
// Ensure getting the system info in open data context
__globalAdapter.handleSystemInfo(() => {
require('cocos2d-js-path');
require('physics-js-path');
__globalAdapter.adaptEngine();
require('./ccRequire');
require('./src/settings');
// Introduce Cocos Service here
require('./main'); // TODO: move to common
// Adjust devicePixelRatio
cc.view._maxPixelRatio = 4;
if (cc.sys.platform !== cc.sys.BAIDU_GAME_SUB) {
// Release Image objects after uploaded gl texture
cc.macro.CLEANUP_IMAGE_CACHE = true;
}
window.boot();
});

View File

@ -0,0 +1,11 @@
{
"deviceOrientation": "landscape",
"openDataContext": "",
"networkTimeout":
{
"request": 5000,
"connectSocket": 5000,
"uploadFile": 5000,
"downloadFile": 5000
}
}

View File

@ -0,0 +1,66 @@
window.boot = function () {
var settings = window._CCSettings;
window._CCSettings = undefined;
var onStart = function () {
cc.view.enableRetina(true);
cc.view.resizeWithBrowserSize(true);
var launchScene = settings.launchScene;
// load scene
cc.director.loadScene(launchScene, null,
function () {
console.log('Success to load scene: ' + launchScene);
}
);
};
var isSubContext = (cc.sys.platform === cc.sys.BAIDU_GAME_SUB);
var option = {
id: 'GameCanvas',
debugMode: settings.debug ? cc.debug.DebugMode.INFO : cc.debug.DebugMode.ERROR,
showFPS: !isSubContext && settings.debug,
frameRate: 60,
groupList: settings.groupList,
collisionMatrix: settings.collisionMatrix,
}
cc.assetManager.init({
bundleVers: settings.bundleVers,
subpackages: settings.subpackages,
remoteBundles: settings.remoteBundles,
server: settings.server,
subContextRoot: settings.subContextRoot
});
var RESOURCES = cc.AssetManager.BuiltinBundleName.RESOURCES;
var INTERNAL = cc.AssetManager.BuiltinBundleName.INTERNAL;
var MAIN = cc.AssetManager.BuiltinBundleName.MAIN;
var START_SCENE = cc.AssetManager.BuiltinBundleName.START_SCENE;
var bundleRoot = [INTERNAL];
settings.hasResourcesBundle && bundleRoot.push(RESOURCES);
settings.hasStartSceneBundle && bundleRoot.push(MAIN);
var count = 0;
function cb (err) {
if (err) return console.error(err.message, err.stack);
count++;
if (count === bundleRoot.length + 1) {
// if there is start-scene bundle. should load start-scene bundle in the last stage
// Otherwise the main bundle should be the last
cc.assetManager.loadBundle(settings.hasStartSceneBundle ? START_SCENE : MAIN, function (err) {
if (!err) cc.game.run(option, onStart);
});
}
}
// load plugins
cc.assetManager.loadScript(settings.jsList.map(function (x) { return 'src/' + x;}), cb);
// load bundles
for (var i = 0; i < bundleRoot.length; i++) {
cc.assetManager.loadBundle(bundleRoot[i], cb);
}
};

View File

@ -0,0 +1,14 @@
{
"appid": "",
"compileType": "game",
"libVersion": "1.0.0",
"bundle":
{
"exclude": ["node_moudules"],
"entry": "game.js",
"compilers": [
{
"type": "babel"
}]
}
}

View File

@ -0,0 +1,228 @@
/* eslint-disable */
import HTMLAudioElement from './HTMLAudioElement'
let SN_SEED = 1
const _innerAudioContextMap = {}
class AudioMock {
play() {}
pause() {}
stop() {}
seek() {}
destroy() {}
onCanplay() {}
offCanplay() {}
onEnded() {}
offEnded() {}
onError() {}
offError() {}
onPause() {}
offPause() {}
onPlay() {}
offPlay() {}
onSeeked() {}
offSeeked() {}
onSeeking() {}
offSeeking() {}
onStop() {}
offStop() {}
onTimeUpdate() {}
offTimeUpdate() {}
offWaiting() {}
onWaitin() {}
}
export default class Audio extends HTMLAudioElement {
constructor(url) {
super()
this._$sn = SN_SEED++;
this.readyState = Audio.HAVE_NOTHING
const innerAudioContext = swan.createInnerAudioContext
? swan.createInnerAudioContext()
: new AudioMock();
_innerAudioContextMap[this._$sn] = innerAudioContext
this._canplayEvents = [
'load',
'loadend',
'canplay',
'canplaythrough',
'loadedmetadata'
]
innerAudioContext.onCanplay(() => {
this._loaded = true
this.readyState = Audio.HAVE_CURRENT_DATA
this._canplayEvents.forEach((type) => {
this.dispatchEvent({ type: type })
})
})
innerAudioContext.onPlay(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
this.dispatchEvent({ type: 'play' })
})
innerAudioContext.onPause(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
this.dispatchEvent({ type: 'pause' })
})
innerAudioContext.onEnded(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
if (_innerAudioContextMap[this._$sn].loop === false) {
this.dispatchEvent({ type: 'ended' })
}
this.readyState = Audio.HAVE_ENOUGH_DATA
})
innerAudioContext.onError(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
this.dispatchEvent({ type: 'error' })
})
if (url) {
this.src = url
} else {
this._src = ''
}
this._loop = innerAudioContext.loop
this._autoplay = innerAudioContext.autoplay
this._paused = innerAudioContext.paused
this._volume = innerAudioContext.volume
this._muted = false
}
addEventListener(type, listener, options = {}) {
type = String(type).toLowerCase()
super.addEventListener(type, listener, options)
if (this._loaded && this._canplayEvents.indexOf(type) !== -1) {
this.dispatchEvent({ type: type })
}
}
load() {
// console.warn('HTMLAudioElement.load() is not implemented.')
// weixin doesn't need call load() manually
}
play() {
_innerAudioContextMap[this._$sn].play()
}
resume() {
_innerAudioContextMap[this._$sn].resume()
}
pause() {
_innerAudioContextMap[this._$sn].pause()
}
destroy() {
_innerAudioContextMap[this._$sn].destroy()
}
canPlayType(mediaType = '') {
if (typeof mediaType !== 'string') {
return ''
}
if (mediaType.indexOf('audio/mpeg') > -1 || mediaType.indexOf('audio/mp4')) {
return 'probably'
}
return ''
}
get currentTime() {
return _innerAudioContextMap[this._$sn].currentTime
}
set currentTime(value) {
_innerAudioContextMap[this._$sn].seek(value)
}
get duration() {
return _innerAudioContextMap[this._$sn].duration
}
get src() {
return this._src
}
set src(value) {
this._src = value
this._loaded = false
this.readyState = Audio.HAVE_NOTHING
const innerAudioContext = _innerAudioContextMap[this._$sn]
innerAudioContext.src = value
}
get loop() {
return this._loop
}
set loop(value) {
this._loop = value
_innerAudioContextMap[this._$sn].loop = value
}
get autoplay() {
return this._autoplay
}
set autoplay(value) {
this._autoplay = value
_innerAudioContextMap[this._$sn].autoplay = value
}
get paused() {
return this._paused
}
get volume() {
return this._volume
}
set volume(value) {
this._volume = value
if (!this._muted) {
_innerAudioContextMap[this._$sn].volume = value
}
}
get muted() {
return this._muted
}
set muted(value) {
this._muted = value
if (value) {
_innerAudioContextMap[this._$sn].volume = 0
} else {
_innerAudioContextMap[this._$sn].volume = this._volume
}
}
cloneNode() {
const newAudio = new Audio()
newAudio.loop = this.loop
newAudio.autoplay = this.autoplay
newAudio.src = this.src
return newAudio
}
}
Audio.HAVE_NOTHING = 0
Audio.HAVE_METADATA = 1
Audio.HAVE_CURRENT_DATA = 2
Audio.HAVE_FUTURE_DATA = 3
Audio.HAVE_ENOUGH_DATA = 4

View File

@ -0,0 +1,60 @@
/* eslint-disable */
let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
function InvalidCharacterError(message) {
this.message = message;
}
InvalidCharacterError.prototype = new Error;
InvalidCharacterError.prototype.name = 'InvalidCharacterError';
// encoder
// [https://gist.github.com/999166] by [https://github.com/nignag]
function btoa(input) {
let str = String(input);
let output = '';
for (
// initialize result and counter
let block, charCode, idx = 0, map = chars;
// if the next str index does not exist:
// change the mapping table to "="
// check if d has no fractional digits
str.charAt(idx | 0) || (map = '=', idx % 1);
// "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8
output += map.charAt(63 & block >> 8 - idx % 1 * 8)
) {
charCode = str.charCodeAt(idx += 3 / 4);
if (charCode > 0xFF) {
throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");
}
block = block << 8 | charCode;
}
return output;
}
// decoder
// [https://gist.github.com/1020396] by [https://github.com/atk]
function atob(input) {
let str = String(input).replace(/=+$/, '');
if (str.length % 4 === 1) {
throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded.");
}
let output = '';
for (
// initialize result and counters
let bc = 0, bs, buffer, idx = 0;
// get next character
buffer = str.charAt(idx++);
// character found in table? initialize bit storage and add its ascii value;
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
// and if not first of each 4 characters,
// convert the first 8 bits to one ascii character
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
) {
// try to find character in table (0-63, not found => -1)
buffer = chars.indexOf(buffer);
}
return output;
}
export { btoa, atob }

View File

@ -0,0 +1,10 @@
/* eslint-disable */
import HTMLElement from './HTMLElement'
export default class Body extends HTMLElement {
constructor() {
// 为了性能, 此处不按照标准的DOM层级关系设计
// 将 body 设置为 0级, parent元素为null
super('body', 0)
}
}

View File

@ -0,0 +1,48 @@
/* eslint-disable */
import * as Mixin from './util/mixin'
// import HTMLCanvasElement from './HTMLCanvasElement'
// TODO
let hasModifiedCanvasPrototype = false
let hasInit2DContextConstructor = false
let hasInitWebGLContextConstructor = false
export default function Canvas() {
const canvas = swan.createCanvas()
const _getContext = canvas.getContext;
// canvas.__proto__.__proto__.__proto__ = new HTMLCanvasElement()
if (!('tagName' in canvas)) {
canvas.tagName = 'CANVAS'
}
canvas.type = 'canvas'
Mixin.parentNode(canvas);
Mixin.style(canvas);
Mixin.classList(canvas);
Mixin.clientRegion(canvas);
Mixin.offsetRegion(canvas);
canvas.focus = function() {};
canvas.blur = function() {};
canvas.addEventListener = function(type, listener, options = {}) {
// console.log('canvas.addEventListener', type);
document.addEventListener(type, listener, options);
}
canvas.removeEventListener = function(type, listener) {
// console.log('canvas.removeEventListener', type);
document.removeEventListener(type, listener);
}
canvas.dispatchEvent = function(event = {}) {
console.log('canvas.dispatchEvent', event.type, event);
// nothing to do
}
return canvas
}

View File

@ -0,0 +1,8 @@
/* eslint-disable */
import HTMLElement from './HTMLElement'
export default class DocumentElement extends HTMLElement {
constructor() {
super('html', 0)
}
}

View File

@ -0,0 +1,28 @@
/* eslint-disable */
import Node from './Node'
export default class Element extends Node {
constructor() {
super()
this.className = ''
this.children = []
}
setAttribute(name, value) {
this[name] = value
}
getAttribute(name) {
return this[name]
}
setAttributeNS(name, value) {
this[name] = value
}
getAttributeNS(name) {
return this[name]
}
}

View File

@ -0,0 +1,17 @@
/* eslint-disable */
import { noop } from './util/index.js'
export default class Event {
constructor(type) {
this.cancelBubble = false
this.cancelable = false
this.target = null
this.currentTarget = null
this.preventDefault = noop
this.stopPropagation = noop
this.type = type
this.timeStamp = Date.now()
}
}

View File

@ -0,0 +1,8 @@
/* eslint-disable */
import Event from '../Event'
export default class MouseEvent extends Event {
constructor(type) {
super(type)
}
}

View File

@ -0,0 +1,183 @@
/* eslint-disable */
import { noop } from '../util/index.js'
import Event from '../Event'
export default class PointerEvent extends Event {
constructor(type) {
super(type)
this.target = window.canvas
this.currentTarget = window.canvas
}
}
const CLONE_PROPS = [
// MouseEvent
'bubbles',
'cancelable',
'view',
'detail',
'screenX',
'screenY',
'clientX',
'clientY',
'ctrlKey',
'altKey',
'shiftKey',
'metaKey',
'button',
'relatedTarget',
// PointerEvent
'pointerId',
'width',
'height',
'pressure',
'tiltX',
'tiltY',
'pointerType',
'hwTimestamp',
'isPrimary',
// event instance
'pageX',
'pageY',
'timeStamp'
];
const CLONE_DEFAULTS = [
// MouseEvent
false,
false,
null,
null,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null,
// DOM Level 3
0,
// PointerEvent
0,
0,
0,
0,
0,
0,
'',
0,
false,
// event instance
0,
0,
0
];
const POINTER_TYPE = 'touch';
function touchToPointer(type, touch, rawEvent) {
const e = new PointerEvent(type);
for (let i = 0; i < CLONE_PROPS.length; i++) {
const p = CLONE_PROPS[i];
e[p] = touch[p] || CLONE_DEFAULTS[i];
}
e.type = type;
e.target = window.canvas;
e.currentTarget = window.canvas;
e.buttons = typeToButtons(type);
e.which = e.buttons;
e.pointerId = (touch.identifier || 0) + 2;
e.bubbles = true;
e.cancelable = true;
// e.detail = this.clickCount;
e.button = 0;
e.width = (touch.radiusX || 0.5) * 2;
e.height = (touch.radiusY || 0.5) * 2;
e.pressure = touch.force || 0.5;
e.isPrimary = isPrimaryPointer(touch);
e.pointerType = POINTER_TYPE;
// forward modifier keys
e.altKey = rawEvent.altKey;
e.ctrlKey = rawEvent.ctrlKey;
e.metaKey = rawEvent.metaKey;
e.shiftKey = rawEvent.shiftKey;
if (rawEvent.preventDefault) {
e.preventDefault = function() {
rawEvent.preventDefault();
};
}
return e;
}
function typeToButtons(type) {
let ret = 0;
if (type === 'touchstart' || type === 'touchmove' || type === 'pointerdown' || type === 'pointermove') {
ret = 1;
}
return ret;
}
let firstPointer = null;
function isPrimaryPointer(touch) {
return firstPointer === touch.identifier;
}
function setPrimaryPointer(touch) {
if (firstPointer === null) {
firstPointer = touch.identifier;
}
}
function removePrimaryPointer(touch) {
if (firstPointer === touch.identifier) {
firstPointer = null;
}
}
function eventHandlerFactory(type) {
return (rawEvent) => {
const changedTouches = rawEvent.changedTouches;
for (let i = 0; i < changedTouches.length; i++) {
const touch = changedTouches[i];
if (i === 0 && type === 'pointerdown') {
setPrimaryPointer(touch);
} else if (type === 'pointerup' || type === 'pointercancel') {
removePrimaryPointer(touch);
}
const event = touchToPointer(type, touch, rawEvent);
document.dispatchEvent(event);
}
}
}
if (swan.onTouchStart) {
swan.onTouchStart(eventHandlerFactory('pointerdown'))
swan.onTouchMove(eventHandlerFactory('pointermove'))
swan.onTouchEnd(eventHandlerFactory('pointerup'))
swan.onTouchCancel(eventHandlerFactory('pointercancel'))
}

View File

@ -0,0 +1,36 @@
/* eslint-disable */
import { noop } from '../util/index.js'
import Event from '../Event'
export default class TouchEvent extends Event {
constructor(type) {
super(type)
this.touches = []
this.targetTouches = []
this.changedTouches = []
this.target = window.canvas
this.currentTarget = window.canvas
}
}
function eventHandlerFactory(type) {
return (rawEvent) => {
const event = new TouchEvent(type)
event.changedTouches = rawEvent.changedTouches
event.touches = rawEvent.touches
event.targetTouches = Array.prototype.slice.call(rawEvent.touches)
event.timeStamp = rawEvent.timeStamp
document.dispatchEvent(event)
}
}
if (swan.onTouchStart) {
swan.onTouchStart(eventHandlerFactory('touchstart'))
swan.onTouchMove(eventHandlerFactory('touchmove'))
swan.onTouchEnd(eventHandlerFactory('touchend'))
swan.onTouchCancel(eventHandlerFactory('touchcancel'))
}

View File

@ -0,0 +1,4 @@
/* eslint-disable */
export { default as TouchEvent } from './TouchEvent'
export { default as PointerEvent } from './PointerEvent'
export { default as MouseEvent } from './MouseEvent'

View File

@ -0,0 +1,58 @@
/* eslint-disable */
const _events = new WeakMap()
export default class EventTarget {
constructor() {
_events.set(this, {})
}
addEventListener(type, listener, options = {}) {
let events = _events.get(this)
if (!events) {
events = {}
_events.set(this, events)
}
if (!events[type]) {
events[type] = []
}
events[type].push(listener)
if (options.capture) {
// console.warn('EventTarget.addEventListener: options.capture is not implemented.')
}
if (options.once) {
// console.warn('EventTarget.addEventListener: options.once is not implemented.')
}
if (options.passive) {
// console.warn('EventTarget.addEventListener: options.passive is not implemented.')
}
}
removeEventListener(type, listener, options = {}) {
const events = _events.get(this)
if (events) {
const listeners = events[type]
if (listeners && listeners.length > 0) {
for (let i = listeners.length; i--; i > 0) {
if (listeners[i] === listener) {
listeners.splice(i, 1)
break
}
}
}
}
}
dispatchEvent(event = {}) {
const listeners = _events.get(this)[event.type]
if (listeners) {
for (let i = 0; i < listeners.length; i++) {
listeners[i](event)
}
}
}
}

View File

@ -0,0 +1,7 @@
/* eslint-disable */
/*
* TODO 使用 swan.readFile 来封装 FileReader
*/
export default class FileReader {
construct() {}
}

View File

@ -0,0 +1,8 @@
/* eslint-disable */
import HTMLMediaElement from './HTMLMediaElement'
export default class HTMLAudioElement extends HTMLMediaElement {
constructor() {
super('audio')
}
}

View File

@ -0,0 +1,21 @@
/* eslint-disable */
// import HTMLElement from './HTMLElement';
// export default class HTMLCanvasElement extends HTMLElement
// {
// constructor(){
// super('canvas')
// }
// };
import Canvas from './Canvas'
import HTMLElement from './HTMLElement'
GameGlobal.screencanvas = GameGlobal.screencanvas || new Canvas();
const canvas = GameGlobal.screencanvas;
const canvasConstructor = canvas.constructor;
// canvasConstructor.__proto__.__proto__ = new HTMLElement();
export default canvasConstructor;

View File

@ -0,0 +1,33 @@
/* eslint-disable */
import { noop } from './util/index.js'
import * as Mixin from './util/mixin'
import Element from './Element'
export default class HTMLElement extends Element {
constructor(tagName = '', level) {
super()
this.className = ''
this.childern = []
this.focus = noop
this.blur = noop
this.insertBefore = noop
this.appendChild = noop
this.removeChild = noop
this.remove = noop
this.innerHTML = ''
this.tagName = tagName.toUpperCase()
Mixin.parentNode(this, level);
Mixin.style(this);
Mixin.classList(this);
Mixin.clientRegion(this);
Mixin.offsetRegion(this);
Mixin.scrollRegion(this);
}
}

View File

@ -0,0 +1,17 @@
/* eslint-disable */
// import HTMLElement from './HTMLElement';
// export default class HTMLImageElement extends HTMLElement
// {
// constructor(){
// super('img')
// }
// };
import HTMLElement from './HTMLElement'
const imageConstructor = swan.createImage().constructor;
// imageConstructor.__proto__.__proto__ = new HTMLElement();
export default imageConstructor;

View File

@ -0,0 +1,20 @@
/* eslint-disable */
import HTMLElement from './HTMLElement'
export default class HTMLMediaElement extends HTMLElement {
constructor(tagName) {
super(tagName)
}
addTextTrack() {}
captureStream() {}
fastSeek() {}
load() {}
pause() {}
play() {}
}

View File

@ -0,0 +1,9 @@
/* eslint-disable */
import HTMLMediaElement from './HTMLMediaElement';
export default class HTMLVideoElement extends HTMLMediaElement
{
constructor(){
super('video')
}
};

View File

@ -0,0 +1,18 @@
/* eslint-disable */
import * as Mixin from './util/mixin'
import HTMLImageElement from './HTMLImageElement'
export default function() {
const image = swan.createImage();
// image.__proto__.__proto__.__proto__ = new HTMLImageElement();
if (!('tagName' in image)) {
image.tagName = 'IMG'
}
Mixin.parentNode(image);
Mixin.classList(image);
return image;
};

View File

@ -0,0 +1,6 @@
/* eslint-disable */
export default class ImageBitmap {
constructor() {
// TODO
}
}

View File

@ -0,0 +1,34 @@
/* eslint-disable */
import EventTarget from './EventTarget.js'
export default class Node extends EventTarget {
constructor() {
super()
this.childNodes = []
}
appendChild(node) {
this.childNodes.push(node)
// if (node instanceof Node) {
// this.childNodes.push(node)
// } else {
// throw new TypeError('Failed to executed \'appendChild\' on \'Node\': parameter 1 is not of type \'Node\'.')
// }
}
cloneNode() {
const copyNode = Object.create(this)
Object.assign(copyNode, this)
return copyNode
}
removeChild(node) {
const index = this.childNodes.findIndex((child) => child === node)
if (index > -1) {
return this.childNodes.splice(index, 1)
}
return null
}
}

View File

@ -0,0 +1,6 @@
/* eslint-disable */
export default class WebGLRenderingContext {
constructor() {
// TODO
}
}

View File

@ -0,0 +1,87 @@
/* eslint-disable */
const _socketTask = new WeakMap()
export default class WebSocket {
constructor(url, protocols = []) {
this.binaryType = '' // TODO 更新 binaryType
this.bufferedAmount = 0 // TODO 更新 bufferedAmount
this.extensions = ''
this.onclose = null
this.onerror = null
this.onmessage = null
this.onopen = null
this.protocol = '' // TODO 小程序内目前获取不到,实际上需要根据服务器选择的 sub-protocol 返回
this.readyState = 3
if (typeof url !== 'string' || !(/(^ws:\/\/)|(^wss:\/\/)/).test(url)) {
throw new TypeError(`Failed to construct 'WebSocket': The URL '${url}' is invalid`)
}
this.url = url
this.readyState = WebSocket.CONNECTING
const socketTask = swan.connectSocket({
url,
protocols: Array.isArray(protocols) ? protocols : [protocols]
})
_socketTask.set(this, socketTask)
socketTask.onClose((res) => {
this.readyState = WebSocket.CLOSED
if (typeof this.onclose === 'function') {
this.onclose(res)
}
})
socketTask.onMessage((res) => {
if (typeof this.onmessage === 'function') {
this.onmessage(res)
}
})
socketTask.onOpen(() => {
this.readyState = WebSocket.OPEN
if (typeof this.onopen === 'function') {
this.onopen()
}
})
socketTask.onError((res) => {
if (typeof this.onerror === 'function') {
this.onerror(new Error(res.errMsg))
}
})
return this
}
close(code, reason) {
this.readyState = WebSocket.CLOSING
const socketTask = _socketTask.get(this)
socketTask.close({
code,
reason
})
}
send(data) {
if (typeof data !== 'string' && !(data instanceof ArrayBuffer)) {
throw new TypeError(`Failed to send message: The data ${data} is invalid`)
}
const socketTask = _socketTask.get(this)
socketTask.send({
data
})
}
}
WebSocket.CONNECTING = 0 // The connection is not yet open.
WebSocket.OPEN = 1 // The connection is open and ready to communicate.
WebSocket.CLOSING = 2 // The connection is in the process of closing.
WebSocket.CLOSED = 3 // The connection is closed or couldn't be opened.

View File

@ -0,0 +1,23 @@
/* eslint-disable */
const { screenWidth, screenHeight, devicePixelRatio } = swan.getSystemInfoSync
? swan.getSystemInfoSync()
: { screenWidth: 0, screenHeight: 0, devicePixelRatio: 1} // Mock data
export const innerWidth = screenWidth
export const innerHeight = screenHeight
export { devicePixelRatio }
export const screen = {
width: screenWidth,
height: screenHeight,
availWidth: innerWidth,
availHeight: innerHeight,
availLeft: 0,
availTop: 0,
}
export const scrollX = 0
export const scrollY = 0
export const ontouchstart = null
export const ontouchmove = null
export const ontouchend = null
export { default as performance } from './performance'

View File

@ -0,0 +1,44 @@
/* eslint-disable */
export default class Worker {
constructor(file) {
this.onmessage = null
// 目前 微信小游戏中 Worker 最大并发数量限制为 1 个,
// 所以创建新Worker前, 需要结束现有的 Worker.terminate
if (Worker.previousWorker) {
Worker.previousWorker.terminate()
}
Worker.previousWorker = this
this._file = file
this._worker = swan.createWorker(file)
this._worker.onMessage((res) => {
if (this.onmessage) {
this.onmessage({
target: this,
data: res,
})
}
})
}
postMessage(message, transferList) {
this._worker.postMessage(message, transferList)
}
terminate() {
this._worker.terminate()
Worker.previousWorker = null
}
}
Worker.previousWorker = null
// export default function(file) {
// const worker = swan.createWorker(file)
// return worker
// }

View File

@ -0,0 +1,229 @@
/* eslint-disable */
import EventTarget from './EventTarget.js'
const _url = new WeakMap()
const _method = new WeakMap()
const _requestHeader = new WeakMap()
const _responseHeader = new WeakMap()
const _requestTask = new WeakMap()
let fs;
function _triggerEvent(type, event = {}) {
event.target = event.target || this
if (typeof this[`on${type}`] === 'function') {
this[`on${type}`].call(this, event)
}
}
function _changeReadyState(readyState, event = {}) {
this.readyState = readyState
event.readyState = readyState;
_triggerEvent.call(this, 'readystatechange', event)
}
function _isRelativePath(url) {
return !(/^(http|https|ftp|wxfile):\/\/.*/i.test(url));
}
export default class XMLHttpRequest extends EventTarget {
constructor() {
super();
/*
* TODO 这一批事件应该是在 XMLHttpRequestEventTarget.prototype 上面的
*/
this.onabort = null
this.onerror = null
this.onload = null
this.onloadstart = null
this.onprogress = null
this.ontimeout = null
this.onloadend = null
this.onreadystatechange = null
this.readyState = 0
this.response = null
this.responseText = null
this.responseType = ''
this.responseXML = null
this.status = 0
this.statusText = ''
this.upload = {}
this.withCredentials = false
_requestHeader.set(this, {
'content-type': 'application/x-www-form-urlencoded'
})
_responseHeader.set(this, {})
}
abort() {
const myRequestTask = _requestTask.get(this)
if (myRequestTask) {
myRequestTask.abort()
}
}
getAllResponseHeaders() {
const responseHeader = _responseHeader.get(this)
return Object.keys(responseHeader).map((header) => {
return `${header}: ${responseHeader[header]}`
}).join('\n')
}
getResponseHeader(header) {
return _responseHeader.get(this)[header]
}
open(method, url /* async, user, password 这几个参数在小程序内不支持*/ ) {
_method.set(this, method)
_url.set(this, url)
_changeReadyState.call(this, XMLHttpRequest.OPENED)
}
overrideMimeType() {}
send(data = '') {
if (this.readyState !== XMLHttpRequest.OPENED) {
throw new Error("Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.")
} else {
const url = _url.get(this)
const header = _requestHeader.get(this)
const responseType = this.responseType
const relative = _isRelativePath(url)
let encoding;
if (responseType === 'arraybuffer') {
// encoding = 'binary'
} else {
encoding = 'utf8'
}
delete this.response;
this.response = null;
const onSuccess = ({ data, statusCode, header }) => {
statusCode = statusCode === undefined ? 200 : statusCode;
if (typeof data !== 'string' && !(data instanceof ArrayBuffer)) {
try {
data = JSON.stringify(data)
} catch (e) {
data = data
}
}
this.status = statusCode
if (header) {
_responseHeader.set(this, header)
}
_triggerEvent.call(this, 'loadstart')
_changeReadyState.call(this, XMLHttpRequest.HEADERS_RECEIVED)
_changeReadyState.call(this, XMLHttpRequest.LOADING)
this.response = data
if (data instanceof ArrayBuffer) {
Object.defineProperty(this, 'responseText', {
enumerable: true,
configurable: true,
get: function() {
throw "InvalidStateError : responseType is " + this.responseType;
}
});
} else {
Object.defineProperty(this, 'responseText', {
enumerable: true,
configurable: true,
value: data
});
}
_changeReadyState.call(this, XMLHttpRequest.DONE)
_triggerEvent.call(this, 'load')
_triggerEvent.call(this, 'loadend')
}
const onFail = ({ errMsg }) => {
// TODO 规范错误
if (errMsg.indexOf('abort') !== -1) {
_triggerEvent.call(this, 'abort')
} else {
_triggerEvent.call(this, 'error', {
message: errMsg
})
}
_triggerEvent.call(this, 'loadend')
if (relative) {
// 用户即使没监听error事件, 也给出相应的警告
console.warn(errMsg)
}
}
if (relative) {
var options = {
'filePath': url,
'success': onSuccess,
'fail': onFail
}
if (encoding) {
options['encoding'] = encoding;
}
if (!fs) {
fs = swan.getFileSystemManager();
}
fs.readFile(options)
return
}
swan.request({
data,
url: url,
method: _method.get(this),
header: header,
responseType: responseType,
success: onSuccess,
fail: onFail
})
}
}
setRequestHeader(header, value) {
const myHeader = _requestHeader.get(this)
myHeader[header] = value
_requestHeader.set(this, myHeader)
}
addEventListener(type, listener) {
if (typeof listener !== 'function') {
return;
}
this['on' + type] = (event = {}) => {
event.target = event.target || this
listener.call(this, event)
}
}
removeEventListener(type, listener) {
if (this['on' + type] === listener) {
this['on' + type] = null;
}
}
}
// TODO 没法模拟 HEADERS_RECEIVED 和 LOADING 两个状态
XMLHttpRequest.UNSEND = 0
XMLHttpRequest.OPENED = 1
XMLHttpRequest.HEADERS_RECEIVED = 2
XMLHttpRequest.LOADING = 3
XMLHttpRequest.DONE = 4

View File

@ -0,0 +1,185 @@
/* eslint-disable */
import * as window from './window'
import Event from './Event'
import HTMLElement from './HTMLElement'
import HTMLVideoElement from './HTMLVideoElement'
import Image from './Image'
import Audio from './Audio'
import Canvas from './Canvas'
import DocumentElement from './DocumentElement'
import Body from './Body'
import './EventIniter/index.js'
import location from './location';
const events = {}
const document = {
readyState: 'complete',
visibilityState: 'visible', // 'visible' , 'hidden'
hidden: false,
fullscreen: true,
URL: location.href,
location: window.location,
scripts: [],
style: {},
ontouchstart: null,
ontouchmove: null,
ontouchend: null,
onvisibilitychange: null,
parentNode: null,
parentElement: null,
createElement(tagName) {
tagName = tagName.toLowerCase();
if (tagName === 'canvas') {
return new Canvas()
} else if (tagName === 'audio') {
return new Audio()
} else if (tagName === 'img') {
return new Image()
} else if (tagName === 'video') {
return new HTMLVideoElement()
}
return new HTMLElement(tagName)
},
createElementNS(nameSpace, tagName) {
return this.createElement(tagName);
},
createTextNode(text) {
// TODO: Do we need the TextNode Class ???
return text;
},
getElementById(id) {
if (id === window.canvas.id) {
return window.canvas
}
return null
},
getElementsByTagName(tagName) {
tagName = tagName.toLowerCase();
if (tagName === 'head') {
return [document.head]
} else if (tagName === 'body') {
return [document.body]
} else if (tagName === 'canvas') {
return [window.canvas]
}
return []
},
getElementsByTagNameNS(nameSpace, tagName) {
return this.getElementsByTagName(tagName);
},
getElementsByName(tagName) {
if (tagName === 'head') {
return [document.head]
} else if (tagName === 'body') {
return [document.body]
} else if (tagName === 'canvas') {
return [window.canvas]
}
return []
},
querySelector(query) {
if (query === 'head') {
return document.head
} else if (query === 'body') {
return document.body
} else if (query === 'canvas') {
return window.canvas
} else if (query === `#${window.canvas.id}`) {
return window.canvas
}
return null
},
querySelectorAll(query) {
if (query === 'head') {
return [document.head]
} else if (query === 'body') {
return [document.body]
} else if (query === 'canvas') {
return [window.canvas]
}
return []
},
addEventListener(type, listener) {
if (!events[type]) {
events[type] = []
}
events[type].push(listener)
},
removeEventListener(type, listener) {
const listeners = events[type]
if (listeners && listeners.length > 0) {
for (let i = listeners.length; i--; i > 0) {
if (listeners[i] === listener) {
listeners.splice(i, 1)
break
}
}
}
},
dispatchEvent(event) {
const type = event.type;
const listeners = events[type]
if (listeners) {
for (let i = 0; i < listeners.length; i++) {
listeners[i](event)
}
}
if (event.target && typeof event.target['on' + type] === 'function') {
event.target['on' + type](event)
}
}
}
document.documentElement = new DocumentElement()
document.head = new HTMLElement('head')
document.body = new Body()
function onVisibilityChange(visible) {
return function() {
document.visibilityState = visible ? 'visible' : 'hidden';
const hidden = !visible;
if (document.hidden === hidden) {
return;
}
document.hidden = hidden;
const event = new Event('visibilitychange');
event.target = document;
event.timeStamp = Date.now();
document.dispatchEvent(event);
}
}
if (swan.onHide) {
swan.onHide(onVisibilityChange(false));
swan.onShow(onVisibilityChange(true));
}
export default document

View File

@ -0,0 +1,69 @@
/* eslint-disable */
import * as _$window from './window'
import document from './document'
import isDevtool from './util/isDevtool';
import HTMLElement from './HTMLElement'
// Avoid being static analyzed in webpack
const _window = _$window
const global = GameGlobal
GameGlobal.global = GameGlobal.global || global
function inject() {
_window.document = document;
_window.addEventListener = (type, listener) => {
_window.document.addEventListener(type, listener)
}
_window.removeEventListener = (type, listener) => {
_window.document.removeEventListener(type, listener)
}
_window.dispatchEvent = _window.document.dispatchEvent;
if (isDevtool()) {
for (const key in _window) {
const descriptor = Object.getOwnPropertyDescriptor(global, key)
if (!descriptor || descriptor.configurable === true) {
Object.defineProperty(window, key, {
value: _window[key]
})
}
}
for (const key in _window.document) {
const descriptor = Object.getOwnPropertyDescriptor(global.document, key)
if (!descriptor || descriptor.configurable === true) {
Object.defineProperty(global.document, key, {
value: _window.document[key]
})
}
}
window.parent = window
} else {
for (const key in _window) {
global[key] = _window[key]
}
global.window = global
global.top = global.parent = global
}
}
if (swan.getSharedCanvas) {
const sharedCanvas = swan.getSharedCanvas();
// sharedCanvas.__proto__.__proto__ = new HTMLCanvasElement;
if (!_window.sharedCanvas) {
// 兼容微信
_window.sharedCanvas = sharedCanvas;
}
sharedCanvas.addEventListener = _window.addEventListener;
sharedCanvas.removeEventListener = _window.removeEventListener;
}
if (!GameGlobal.__isAdapterInjected) {
GameGlobal.__isAdapterInjected = true
inject()
}

View File

@ -0,0 +1,32 @@
/* eslint-disable */
const localStorage = {
get length() {
const { keys } = swan.getStorageInfoSync()
return keys.length
},
key(n) {
const { keys } = swan.getStorageInfoSync()
return keys[n]
},
getItem(key) {
const value = swan.getStorageSync(key);
return value === "" ? null : value;
},
setItem(key, value) {
return swan.setStorageSync(key, value)
},
removeItem(key) {
swan.removeStorageSync(key)
},
clear() {
swan.clearStorageSync()
}
}
export default localStorage

View File

@ -0,0 +1,15 @@
/* eslint-disable */
const location = {
href: 'game.js',
search: '',
hash: '',
reload() {
},
replace(href) {
this.href = href
},
}
export default location

View File

@ -0,0 +1,37 @@
/* eslint-disable */
import { noop } from './util/index.js'
// TODO 开放域下用 userAgent
const systemInfo = swan.getSystemInfoSync && swan.getSystemInfoSync()
const system = (systemInfo && systemInfo.system) || '';
const platform = (systemInfo && systemInfo.platform) || '';
const language = (systemInfo && systemInfo.language) || '"zh_CN"';
const android = system.toLowerCase().indexOf('android') !== -1;
const uaDesc = android ? 'Android; CPU Android 6.0' : 'iPhone; CPU iPhone OS 10_3_1 like Mac OS X';
const ua = `Mozilla/5.0 (${uaDesc}) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301 MicroMessenger/6.6.0 SwanGame NetType/WIFI Language/${language}`;
const navigator = {
platform,
language: language,
appVersion: `5.0 (${uaDesc}) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1`,
userAgent: ua,
onLine: true, // TODO 用 swan.getNetworkStateChange 和 swan.onNetworkStateChange 来返回真实的状态
// TODO 用 swan.getLocation 来封装 geolocation
geolocation: {
getCurrentPosition: noop,
watchPosition: noop,
clearWatch: noop
}
}
if (swan.onNetworkStatusChange) {
swan.onNetworkStatusChange(function(event){
navigator.onLine = event.isConnected;
});
}
export default navigator

View File

@ -0,0 +1,23 @@
/* eslint-disable */
import isDevtool from './util/isDevtool';
let performance
if (swan.getPerformance) {
const swanPerf = swan.getPerformance()
const initTime = swanPerf.now()
const clientPerfAdapter = Object.assign({}, swanPerf, {
now: function() {
return (swanPerf.now() - initTime) / 1000
}
})
performance = isDevtool() ? swanPerf : clientPerfAdapter
}
else {
performance = {};
performance.now = Date.now;
}
export default performance

View File

@ -0,0 +1,20 @@
/* eslint-disable */
import CommonComputedStyle from './CommonComputedStyle'
function getCanvasComputedStyle(canvas) {
const rect = canvas.getBoundingClientRect();
const style = Object.assign(CommonComputedStyle, {
"display": "inline",
"position": "static",
"inlineSize": rect.width + "px",
"perspectiveOrigin": rect.width / 2 + "px " + rect.height / 2 + "px",
"transformOrigin": rect.width / 2 + "px " + rect.height / 2 + "px",
"webkitLogicalWidth": rect.width + "px",
"webkitLogicalHeight": rect.height + "px",
"width": rect.width + "px",
"height": rect.height + "px",
});
return style;
}
export default getCanvasComputedStyle;

View File

@ -0,0 +1,593 @@
/* eslint-disable */
const style = {
"0": "animation-delay",
"1": "animation-direction",
"2": "animation-duration",
"3": "animation-fill-mode",
"4": "animation-iteration-count",
"5": "animation-name",
"6": "animation-play-state",
"7": "animation-timing-function",
"8": "background-attachment",
"9": "background-blend-mode",
"10": "background-clip",
"11": "background-color",
"12": "background-image",
"13": "background-origin",
"14": "background-position",
"15": "background-repeat",
"16": "background-size",
"17": "border-bottom-color",
"18": "border-bottom-left-radius",
"19": "border-bottom-right-radius",
"20": "border-bottom-style",
"21": "border-bottom-width",
"22": "border-collapse",
"23": "border-image-outset",
"24": "border-image-repeat",
"25": "border-image-slice",
"26": "border-image-source",
"27": "border-image-width",
"28": "border-left-color",
"29": "border-left-style",
"30": "border-left-width",
"31": "border-right-color",
"32": "border-right-style",
"33": "border-right-width",
"34": "border-top-color",
"35": "border-top-left-radius",
"36": "border-top-right-radius",
"37": "border-top-style",
"38": "border-top-width",
"39": "bottom",
"40": "box-shadow",
"41": "box-sizing",
"42": "break-after",
"43": "break-before",
"44": "break-inside",
"45": "caption-side",
"46": "clear",
"47": "clip",
"48": "color",
"49": "content",
"50": "cursor",
"51": "direction",
"52": "display",
"53": "empty-cells",
"54": "float",
"55": "font-family",
"56": "font-kerning",
"57": "font-size",
"58": "font-stretch",
"59": "font-style",
"60": "font-variant",
"61": "font-variant-ligatures",
"62": "font-variant-caps",
"63": "font-variant-numeric",
"64": "font-variant-east-asian",
"65": "font-weight",
"66": "height",
"67": "image-rendering",
"68": "isolation",
"69": "justify-items",
"70": "justify-self",
"71": "left",
"72": "letter-spacing",
"73": "line-height",
"74": "list-style-image",
"75": "list-style-position",
"76": "list-style-type",
"77": "margin-bottom",
"78": "margin-left",
"79": "margin-right",
"80": "margin-top",
"81": "max-height",
"82": "max-width",
"83": "min-height",
"84": "min-width",
"85": "mix-blend-mode",
"86": "object-fit",
"87": "object-position",
"88": "offset-distance",
"89": "offset-path",
"90": "offset-rotate",
"91": "opacity",
"92": "orphans",
"93": "outline-color",
"94": "outline-offset",
"95": "outline-style",
"96": "outline-width",
"97": "overflow-anchor",
"98": "overflow-wrap",
"99": "overflow-x",
"100": "overflow-y",
"101": "padding-bottom",
"102": "padding-left",
"103": "padding-right",
"104": "padding-top",
"105": "pointer-events",
"106": "position",
"107": "resize",
"108": "right",
"109": "scroll-behavior",
"110": "speak",
"111": "table-layout",
"112": "tab-size",
"113": "text-align",
"114": "text-align-last",
"115": "text-decoration",
"116": "text-decoration-line",
"117": "text-decoration-style",
"118": "text-decoration-color",
"119": "text-decoration-skip-ink",
"120": "text-underline-position",
"121": "text-indent",
"122": "text-rendering",
"123": "text-shadow",
"124": "text-size-adjust",
"125": "text-overflow",
"126": "text-transform",
"127": "top",
"128": "touch-action",
"129": "transition-delay",
"130": "transition-duration",
"131": "transition-property",
"132": "transition-timing-function",
"133": "unicode-bidi",
"134": "vertical-align",
"135": "visibility",
"136": "white-space",
"137": "widows",
"138": "width",
"139": "will-change",
"140": "word-break",
"141": "word-spacing",
"142": "word-wrap",
"143": "z-index",
"144": "zoom",
"145": "-webkit-appearance",
"146": "backface-visibility",
"147": "-webkit-border-horizontal-spacing",
"148": "-webkit-border-image",
"149": "-webkit-border-vertical-spacing",
"150": "-webkit-box-align",
"151": "-webkit-box-decoration-break",
"152": "-webkit-box-direction",
"153": "-webkit-box-flex",
"154": "-webkit-box-flex-group",
"155": "-webkit-box-lines",
"156": "-webkit-box-ordinal-group",
"157": "-webkit-box-orient",
"158": "-webkit-box-pack",
"159": "-webkit-box-reflect",
"160": "column-count",
"161": "column-gap",
"162": "column-rule-color",
"163": "column-rule-style",
"164": "column-rule-width",
"165": "column-span",
"166": "column-width",
"167": "align-content",
"168": "align-items",
"169": "align-self",
"170": "flex-basis",
"171": "flex-grow",
"172": "flex-shrink",
"173": "flex-direction",
"174": "flex-wrap",
"175": "justify-content",
"176": "-webkit-font-smoothing",
"177": "grid-auto-columns",
"178": "grid-auto-flow",
"179": "grid-auto-rows",
"180": "grid-column-end",
"181": "grid-column-start",
"182": "grid-template-areas",
"183": "grid-template-columns",
"184": "grid-template-rows",
"185": "grid-row-end",
"186": "grid-row-start",
"187": "grid-column-gap",
"188": "grid-row-gap",
"189": "-webkit-highlight",
"190": "hyphens",
"191": "-webkit-hyphenate-character",
"192": "-webkit-line-break",
"193": "-webkit-line-clamp",
"194": "-webkit-locale",
"195": "-webkit-margin-before-collapse",
"196": "-webkit-margin-after-collapse",
"197": "-webkit-mask-box-image",
"198": "-webkit-mask-box-image-outset",
"199": "-webkit-mask-box-image-repeat",
"200": "-webkit-mask-box-image-slice",
"201": "-webkit-mask-box-image-source",
"202": "-webkit-mask-box-image-width",
"203": "-webkit-mask-clip",
"204": "-webkit-mask-composite",
"205": "-webkit-mask-image",
"206": "-webkit-mask-origin",
"207": "-webkit-mask-position",
"208": "-webkit-mask-repeat",
"209": "-webkit-mask-size",
"210": "order",
"211": "perspective",
"212": "perspective-origin",
"213": "-webkit-print-color-adjust",
"214": "-webkit-rtl-ordering",
"215": "shape-outside",
"216": "shape-image-threshold",
"217": "shape-margin",
"218": "-webkit-tap-highlight-color",
"219": "-webkit-text-combine",
"220": "-webkit-text-decorations-in-effect",
"221": "-webkit-text-emphasis-color",
"222": "-webkit-text-emphasis-position",
"223": "-webkit-text-emphasis-style",
"224": "-webkit-text-fill-color",
"225": "-webkit-text-orientation",
"226": "-webkit-text-security",
"227": "-webkit-text-stroke-color",
"228": "-webkit-text-stroke-width",
"229": "transform",
"230": "transform-origin",
"231": "transform-style",
"232": "-webkit-user-drag",
"233": "-webkit-user-modify",
"234": "user-select",
"235": "-webkit-writing-mode",
"236": "-webkit-app-region",
"237": "buffered-rendering",
"238": "clip-path",
"239": "clip-rule",
"240": "mask",
"241": "filter",
"242": "flood-color",
"243": "flood-opacity",
"244": "lighting-color",
"245": "stop-color",
"246": "stop-opacity",
"247": "color-interpolation",
"248": "color-interpolation-filters",
"249": "color-rendering",
"250": "fill",
"251": "fill-opacity",
"252": "fill-rule",
"253": "marker-end",
"254": "marker-mid",
"255": "marker-start",
"256": "mask-type",
"257": "shape-rendering",
"258": "stroke",
"259": "stroke-dasharray",
"260": "stroke-dashoffset",
"261": "stroke-linecap",
"262": "stroke-linejoin",
"263": "stroke-miterlimit",
"264": "stroke-opacity",
"265": "stroke-width",
"266": "alignment-baseline",
"267": "baseline-shift",
"268": "dominant-baseline",
"269": "text-anchor",
"270": "writing-mode",
"271": "vector-effect",
"272": "paint-order",
"273": "d",
"274": "cx",
"275": "cy",
"276": "x",
"277": "y",
"278": "r",
"279": "rx",
"280": "ry",
"281": "caret-color",
"282": "line-break",
"display": "inline",
"dominantBaseline": "auto",
"emptyCells": "show",
"fill": "rgb(0, 0, 0)",
"fillOpacity": "1",
"fillRule": "nonzero",
"filter": "none",
"flex": "0 1 auto",
"flexBasis": "auto",
"flexDirection": "row",
"flexFlow": "row nowrap",
"flexGrow": "0",
"flexShrink": "1",
"flexWrap": "nowrap",
"float": "none",
"floodColor": "rgb(0, 0, 0)",
"floodOpacity": "1",
"font": "normal normal 400 normal 16px / normal \"PingFang SC\"",
"fontDisplay": "",
"fontFamily": "\"PingFang SC\"",
"fontFeatureSettings": "normal",
"fontKerning": "auto",
"fontSize": "16px",
"fontStretch": "100%",
"fontStyle": "normal",
"fontVariant": "normal",
"fontVariantCaps": "normal",
"fontVariantEastAsian": "normal",
"fontVariantLigatures": "normal",
"fontVariantNumeric": "normal",
"fontVariationSettings": "normal",
"fontWeight": "400",
"grid": "none / none / none / row / auto / auto",
"gridArea": "auto / auto / auto / auto",
"gridAutoColumns": "auto",
"gridAutoFlow": "row",
"gridAutoRows": "auto",
"gridColumn": "auto / auto",
"gridColumnEnd": "auto",
"gridColumnGap": "0px",
"gridColumnStart": "auto",
"gridGap": "0px 0px",
"gridRow": "auto / auto",
"gridRowEnd": "auto",
"gridRowGap": "0px",
"gridRowStart": "auto",
"gridTemplate": "none / none / none",
"gridTemplateAreas": "none",
"gridTemplateColumns": "none",
"gridTemplateRows": "none",
"height": "0px",
"hyphens": "manual",
"imageRendering": "auto",
"inlineSize": "0px",
"isolation": "auto",
"justifyContent": "normal",
"justifyItems": "normal",
"justifySelf": "auto",
"left": "auto",
"letterSpacing": "normal",
"lightingColor": "rgb(255, 255, 255)",
"lineBreak": "auto",
"lineHeight": "normal",
"listStyle": "disc outside none",
"listStyleImage": "none",
"listStylePosition": "outside",
"listStyleType": "disc",
"margin": "0px",
"marginBottom": "0px",
"marginLeft": "0px",
"marginRight": "0px",
"marginTop": "0px",
"marker": "",
"markerEnd": "none",
"markerMid": "none",
"markerStart": "none",
"mask": "none",
"maskType": "luminance",
"maxBlockSize": "none",
"maxHeight": "none",
"maxInlineSize": "none",
"maxWidth": "none",
"maxZoom": "",
"minBlockSize": "0px",
"minHeight": "0px",
"minInlineSize": "0px",
"minWidth": "0px",
"minZoom": "",
"mixBlendMode": "normal",
"objectFit": "fill",
"objectPosition": "50% 50%",
"offset": "none 0px auto 0deg",
"offsetDistance": "0px",
"offsetPath": "none",
"offsetRotate": "auto 0deg",
"opacity": "1",
"order": "0",
"orientation": "",
"orphans": "2",
"outline": "rgb(0, 0, 0) none 0px",
"outlineColor": "rgb(0, 0, 0)",
"outlineOffset": "0px",
"outlineStyle": "none",
"outlineWidth": "0px",
"overflow": "visible",
"overflowAnchor": "auto",
"overflowWrap": "normal",
"overflowX": "visible",
"overflowY": "visible",
"overscrollBehavior": "auto auto",
"overscrollBehaviorX": "auto",
"overscrollBehaviorY": "auto",
"padding": "0px",
"paddingBottom": "0px",
"paddingLeft": "0px",
"paddingRight": "0px",
"paddingTop": "0px",
"page": "",
"pageBreakAfter": "auto",
"pageBreakBefore": "auto",
"pageBreakInside": "auto",
"paintOrder": "fill stroke markers",
"perspective": "none",
"perspectiveOrigin": "0px 0px",
"placeContent": "normal normal",
"placeItems": "normal normal",
"placeSelf": "auto auto",
"pointerEvents": "auto",
"position": "static",
"quotes": "",
"r": "0px",
"resize": "none",
"right": "auto",
"rx": "auto",
"ry": "auto",
"scrollBehavior": "auto",
"shapeImageThreshold": "0",
"shapeMargin": "0px",
"shapeOutside": "none",
"shapeRendering": "auto",
"size": "",
"speak": "normal",
"src": "",
"stopColor": "rgb(0, 0, 0)",
"stopOpacity": "1",
"stroke": "none",
"strokeDasharray": "none",
"strokeDashoffset": "0px",
"strokeLinecap": "butt",
"strokeLinejoin": "miter",
"strokeMiterlimit": "4",
"strokeOpacity": "1",
"strokeWidth": "1px",
"tabSize": "8",
"tableLayout": "auto",
"textAlign": "start",
"textAlignLast": "auto",
"textAnchor": "start",
"textCombineUpright": "none",
"textDecoration": "none solid rgb(0, 0, 0)",
"textDecorationColor": "rgb(0, 0, 0)",
"textDecorationLine": "none",
"textDecorationSkipInk": "auto",
"textDecorationStyle": "solid",
"textIndent": "0px",
"textOrientation": "mixed",
"textOverflow": "clip",
"textRendering": "auto",
"textShadow": "none",
"textSizeAdjust": "auto",
"textTransform": "none",
"textUnderlinePosition": "auto",
"top": "auto",
"touchAction": "auto",
"transform": "none",
"transformBox": "view-box",
"transformOrigin": "0px 0px",
"transformStyle": "flat",
"transition": "all 0s ease 0s",
"transitionDelay": "0s",
"transitionDuration": "0s",
"transitionProperty": "all",
"transitionTimingFunction": "ease",
"unicodeBidi": "normal",
"unicodeRange": "",
"userSelect": "auto",
"userZoom": "",
"vectorEffect": "none",
"verticalAlign": "baseline",
"visibility": "visible",
"webkitAppRegion": "no-drag",
"webkitAppearance": "none",
"webkitBorderAfter": "0px none rgb(0, 0, 0)",
"webkitBorderAfterColor": "rgb(0, 0, 0)",
"webkitBorderAfterStyle": "none",
"webkitBorderAfterWidth": "0px",
"webkitBorderBefore": "0px none rgb(0, 0, 0)",
"webkitBorderBeforeColor": "rgb(0, 0, 0)",
"webkitBorderBeforeStyle": "none",
"webkitBorderBeforeWidth": "0px",
"webkitBorderEnd": "0px none rgb(0, 0, 0)",
"webkitBorderEndColor": "rgb(0, 0, 0)",
"webkitBorderEndStyle": "none",
"webkitBorderEndWidth": "0px",
"webkitBorderHorizontalSpacing": "0px",
"webkitBorderImage": "none",
"webkitBorderStart": "0px none rgb(0, 0, 0)",
"webkitBorderStartColor": "rgb(0, 0, 0)",
"webkitBorderStartStyle": "none",
"webkitBorderStartWidth": "0px",
"webkitBorderVerticalSpacing": "0px",
"webkitBoxAlign": "stretch",
"webkitBoxDecorationBreak": "slice",
"webkitBoxDirection": "normal",
"webkitBoxFlex": "0",
"webkitBoxFlexGroup": "1",
"webkitBoxLines": "single",
"webkitBoxOrdinalGroup": "1",
"webkitBoxOrient": "horizontal",
"webkitBoxPack": "start",
"webkitBoxReflect": "none",
"webkitColumnBreakAfter": "auto",
"webkitColumnBreakBefore": "auto",
"webkitColumnBreakInside": "auto",
"webkitFontSizeDelta": "",
"webkitFontSmoothing": "auto",
"webkitHighlight": "none",
"webkitHyphenateCharacter": "auto",
"webkitLineBreak": "auto",
"webkitLineClamp": "none",
"webkitLocale": "auto",
"webkitLogicalHeight": "0px",
"webkitLogicalWidth": "0px",
"webkitMarginAfter": "0px",
"webkitMarginAfterCollapse": "collapse",
"webkitMarginBefore": "0px",
"webkitMarginBeforeCollapse": "collapse",
"webkitMarginBottomCollapse": "collapse",
"webkitMarginCollapse": "",
"webkitMarginEnd": "0px",
"webkitMarginStart": "0px",
"webkitMarginTopCollapse": "collapse",
"webkitMask": "",
"webkitMaskBoxImage": "none",
"webkitMaskBoxImageOutset": "0px",
"webkitMaskBoxImageRepeat": "stretch",
"webkitMaskBoxImageSlice": "0 fill",
"webkitMaskBoxImageSource": "none",
"webkitMaskBoxImageWidth": "auto",
"webkitMaskClip": "border-box",
"webkitMaskComposite": "source-over",
"webkitMaskImage": "none",
"webkitMaskOrigin": "border-box",
"webkitMaskPosition": "0% 0%",
"webkitMaskPositionX": "0%",
"webkitMaskPositionY": "0%",
"webkitMaskRepeat": "repeat",
"webkitMaskRepeatX": "",
"webkitMaskRepeatY": "",
"webkitMaskSize": "auto",
"webkitMaxLogicalHeight": "none",
"webkitMaxLogicalWidth": "none",
"webkitMinLogicalHeight": "0px",
"webkitMinLogicalWidth": "0px",
"webkitPaddingAfter": "0px",
"webkitPaddingBefore": "0px",
"webkitPaddingEnd": "0px",
"webkitPaddingStart": "0px",
"webkitPerspectiveOriginX": "",
"webkitPerspectiveOriginY": "",
"webkitPrintColorAdjust": "economy",
"webkitRtlOrdering": "logical",
"webkitRubyPosition": "before",
"webkitTapHighlightColor": "rgba(0, 0, 0, 0.4)",
"webkitTextCombine": "none",
"webkitTextDecorationsInEffect": "none",
"webkitTextEmphasis": "",
"webkitTextEmphasisColor": "rgb(0, 0, 0)",
"webkitTextEmphasisPosition": "over right",
"webkitTextEmphasisStyle": "none",
"webkitTextFillColor": "rgb(0, 0, 0)",
"webkitTextOrientation": "vertical-right",
"webkitTextSecurity": "none",
"webkitTextStroke": "",
"webkitTextStrokeColor": "rgb(0, 0, 0)",
"webkitTextStrokeWidth": "0px",
"webkitTransformOriginX": "",
"webkitTransformOriginY": "",
"webkitTransformOriginZ": "",
"webkitUserDrag": "auto",
"webkitUserModify": "read-only",
"webkitWritingMode": "horizontal-tb",
"whiteSpace": "normal",
"widows": "2",
"width": "0px",
"willChange": "auto",
"wordBreak": "normal",
"wordSpacing": "0px",
"wordWrap": "normal",
"writingMode": "horizontal-tb",
"x": "0px",
"y": "0px",
"zIndex": "auto",
"zoom": "1"
};
export default style;

View File

@ -0,0 +1,21 @@
/* eslint-disable */
import CommonComputedStyle from './CommonComputedStyle'
function getImageComputedStyle(image) {
const width = image.width;
const height = image.height;
const style = Object.assign(CommonComputedStyle, {
"display": "inline",
"position": "static",
"inlineSize": width + "px",
"perspectiveOrigin": width / 2 + "px " + height / 2 + "px",
"transformOrigin": width / 2 + "px " + height / 2 + "px",
"webkitLogicalWidth": width + "px",
"webkitLogicalHeight": height + "px",
"width": width + "px",
"height": height + "px",
});
return style;
}
export default getImageComputedStyle;

View File

@ -0,0 +1,2 @@
/* eslint-disable */
export function noop() {}

View File

@ -0,0 +1,16 @@
/* eslint-disable */
let isDevtool = false;
if (swan.getSystemInfoSync) {
const { platform } = swan.getSystemInfoSync();
isDevtool = platform === 'devtools';
}
else {
let descriptor = Object.getOwnPropertyDescriptor(global, 'window')
// 开发者工具无法重定义 window
isDevtool = !(!descriptor || descriptor.configurable === true);
}
export default function () {
return isDevtool;
}

View File

@ -0,0 +1,125 @@
/* eslint-disable */
import { innerWidth, innerHeight } from '../WindowProperties'
export function parentNode(obj, level) {
if (!('parentNode' in obj)) {
let _parent;
if (level === 0) {
_parent = function() {
// return document
return null
}
} else if (level === 1) {
_parent = function() {
return document.documentElement
}
} else {
_parent = function() {
return document.body
}
}
Object.defineProperty(obj, 'parentNode', {
enumerable: true,
get: _parent
})
}
if (!('parentElement' in obj)) {
let _parent;
if (level === 0) {
_parent = function() {
return null
}
} else if (level === 1) {
_parent = function() {
return document.documentElement
}
} else {
_parent = function() {
return document.body
}
}
Object.defineProperty(obj, 'parentElement', {
enumerable: true,
get: _parent
})
}
}
export function style(obj) {
obj.style = obj.style || {}
Object.assign(obj.style, {
top: '0px',
left: '0px',
width: innerWidth + 'px',
height: innerHeight + 'px',
margin: '0px',
padding: '0px',
removeProperty() {},
setProperty() {}
})
}
export function clientRegion(obj) {
if (!('clientLeft' in obj)) {
obj.clientLeft = 0
obj.clientTop = 0
}
if (!('clientWidth' in obj)) {
obj.clientWidth = innerWidth
obj.clientHeight = innerHeight
}
if (!('getBoundingClientRect' in obj)) {
obj.getBoundingClientRect = function() {
const ret = {
x: 0,
y: 0,
top: 0,
left: 0,
width: this.clientWidth,
height: this.clientHeight
}
ret.right = ret.width
ret.bottom = ret.height
return ret
}
}
}
export function offsetRegion(obj) {
if (!('offsetLeft' in obj)) {
obj.offsetLeft = 0
obj.offsetTop = 0
}
if (!('offsetWidth' in obj)) {
obj.offsetWidth = innerWidth
obj.offsetHeight = innerHeight
}
}
export function scrollRegion(obj) {
if (!('scrollLeft' in obj)) {
obj.scrollLeft = 0
obj.scrollTop = 0
}
if (!('scrollWidth' in obj)) {
obj.scrollWidth = innerWidth
obj.scrollHeight = innerHeight
}
}
export function classList(obj) {
const noop = function() {}
obj.classList = []
obj.classList.add = noop
obj.classList.remove = noop
obj.classList.contains = noop
obj.classList.toggle = noop
}

View File

@ -0,0 +1,125 @@
/* eslint-disable */
import Canvas from './Canvas'
import CommonComputedStyle from './style/CommonComputedStyle'
import getImageComputedStyle from './style/ImageComputedStyle'
import getCanvasComputedStyle from './style/CanvasComputedStyle'
import Event from './Event'
import isDevtool from './util/isDevtool';
export { default as navigator } from './navigator'
export { default as XMLHttpRequest } from './XMLHttpRequest'
export { default as WebSocket } from './WebSocket'
export { default as Worker } from './Worker'
export { default as Image } from './Image'
export { default as ImageBitmap } from './ImageBitmap'
export { default as Audio } from './Audio'
// export { default as FileReader } from './FileReader' // TODO: FileReader adaption blocks in BAIDU_DEV_TOOL
export { default as HTMLElement } from './HTMLElement'
export { default as HTMLImageElement } from './HTMLImageElement'
export { default as HTMLCanvasElement } from './HTMLCanvasElement'
export { default as HTMLMediaElement } from './HTMLMediaElement'
export { default as HTMLAudioElement } from './HTMLAudioElement'
export { default as HTMLVideoElement } from './HTMLVideoElement'
export { default as WebGLRenderingContext } from './WebGLRenderingContext'
export { TouchEvent, PointerEvent, MouseEvent } from './EventIniter/index.js'
export { default as localStorage } from './localStorage'
export { default as location } from './location'
export { btoa, atob } from './Base64.js'
export * from './WindowProperties'
// 暴露全局的 canvas
GameGlobal.screencanvas = GameGlobal.screencanvas || new Canvas()
const canvas = GameGlobal.screencanvas;
function getComputedStyle(dom) {
const tagName = dom.tagName;
if (tagName === "CANVAS") {
return getCanvasComputedStyle(dom);
} else if (tagName === "IMG") {
return getImageComputedStyle(dom);
}
return CommonComputedStyle;
}
function scrollTo(x, y) {
// x = Math.min(window.innerWidth, Math.max(0, x));
// y = Math.min(window.innerHeight, Math.max(0, y));
// We can't scroll the page of WeChatTinyGame, so it'll always be 0.
// window.scrollX = 0;
// window.scrollY = 0;
}
function scrollBy(dx, dy) {
window.scrollTo(window.scrollX + dx, window.scrollY + dy);
}
function alert(msg) {
console.log(msg);
}
function focus() {}
function blur() {}
if (isDevtool() && swan.getPerformance) {
const wxPerf = swan.getPerformance();
const consoleTimers = {};
console.time = function(name) {
consoleTimers[name] = wxPerf.now();
};
console.timeEnd = function(name) {
const timeStart = consoleTimers[name];
if(!timeStart) {
return;
}
const timeElapsed = wxPerf.now() - timeStart;
console.log(name + ": " + timeElapsed / 1000 + "ms");
delete consoleTimers[name];
};
}
function eventHandlerFactory() {
return (res) => {
const event = new Event('resize')
event.target = window;
event.timeStamp = Date.now();
event.res = res;
event.windowWidth = res.windowWidth;
event.windowHeight = res.windowHeight;
document.dispatchEvent(event);
}
}
// TODO
// swan.onWindowResize(eventHandlerFactory())
const _setTimeout = setTimeout;
const _clearTimeout = clearTimeout;
const _setInterval = setInterval;
const _clearInterval = clearInterval;
const _requestAnimationFrame = requestAnimationFrame;
const _cancelAnimationFrame = cancelAnimationFrame;
export {
canvas,
alert,
focus,
blur,
getComputedStyle,
scrollTo,
scrollBy,
_setTimeout as setTimeout,
_clearTimeout as clearTimeout,
_setInterval as setInterval,
_clearInterval as clearInterval,
_requestAnimationFrame as requestAnimationFrame,
_cancelAnimationFrame as cancelAnimationFrame
}

View File

@ -0,0 +1,24 @@
if (cc.Texture2D) {
cc.Texture2D.prototype._checkPackable = function () {
let dynamicAtlas = cc.dynamicAtlasManager;
if (!dynamicAtlas) return;
if (this._isCompressed()) {
this._packable = false;
return;
}
let w = this.width, h = this.height;
if (!this._image ||
w > dynamicAtlas.maxFrameSize || h > dynamicAtlas.maxFrameSize ||
this._getHash() !== dynamicAtlas.Atlas.DEFAULT_HASH) {
this._packable = false;
return;
}
// HACK: Can't tell if it's a Canvas or an Image by instanceof on Baidu.
if (this._image && this._image.getContext) {
this._packable = true;
}
};
}

View File

@ -0,0 +1 @@
require('./Texture2D');

View File

@ -0,0 +1,267 @@
/****************************************************************************
Copyright (c) 2017-2019 Xiamen Yaji Software Co., Ltd.
https://www.cocos.com/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated engine source code (the "Software"), a limited,
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
to use Cocos Creator solely to develop games on your target platforms. You shall
not use Cocos Creator software for developing other software or tools that's
used for developing games. You are not granted to publish, distribute,
sublicense, and/or sell copies of Cocos Creator.
The software or tools in this License Agreement are licensed, not sold.
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
var fs = swan.getFileSystemManager ? swan.getFileSystemManager() : null;
var outOfStorageRegExp = /file size over/;
var fsUtils = {
fs,
isOutOfStorage (errMsg) {
return outOfStorageRegExp.test(errMsg);
},
getUserDataPath () {
return swan.env.USER_DATA_PATH;
},
checkFsValid () {
if (!fs) {
console.warn('can not get the file system!');
return false;
}
return true;
},
deleteFile (filePath, onComplete) {
fs.unlink({
filePath: filePath,
success: function () {
onComplete && onComplete(null);
},
fail: function (res) {
console.warn(`Delete file failed: path: ${filePath} message: ${res.errMsg}`);
onComplete && onComplete(new Error(res.errMsg));
}
});
},
downloadFile (remoteUrl, filePath, header, onProgress, onComplete) {
var options = {
url: remoteUrl,
success: function (res) {
if (res.statusCode === 200) {
onComplete && onComplete(null, res.tempFilePath || res.filePath);
}
else {
if (res.filePath) {
fsUtils.deleteFile(res.filePath);
}
console.warn(`Download file failed: path: ${remoteUrl} message: ${res.statusCode}`);
onComplete && onComplete(new Error(res.statusCode), null);
}
},
fail: function (res) {
console.warn(`Download file failed: path: ${remoteUrl} message: ${res.errMsg}`);
onComplete && onComplete(new Error(res.errMsg), null);
}
}
if (filePath) options.filePath = filePath;
if (header) options.header = header;
var task = swan.downloadFile(options);
onProgress && task.onProgressUpdate(onProgress);
},
saveFile (srcPath, destPath, onComplete) {
swan.saveFile({
tempFilePath: srcPath,
filePath: destPath,
success: function (res) {
onComplete && onComplete(null);
},
fail: function (res) {
console.warn(`Save file failed: path: ${srcPath} message: ${res.errMsg}`);
onComplete && onComplete(new Error(res.errMsg));
}
});
},
copyFile (srcPath, destPath, onComplete) {
fs.copyFile({
srcPath: srcPath,
destPath: destPath,
success: function () {
onComplete && onComplete(null);
},
fail: function (res) {
console.warn(`Copy file failed: path: ${srcPath} message: ${res.errMsg}`);
onComplete && onComplete(new Error(res.errMsg));
}
});
},
writeFile (path, data, encoding, onComplete) {
fs.writeFile({
filePath: path,
encoding: encoding,
data: data,
success: function () {
onComplete && onComplete(null);
},
fail: function (res) {
console.warn(`Write file failed: path: ${path} message: ${res.errMsg}`);
onComplete && onComplete(new Error(res.errMsg));
}
});
},
writeFileSync (path, data, encoding) {
try {
fs.writeFileSync(path, data, encoding);
return null;
}
catch (e) {
console.warn(`Write file failed: path: ${path} message: ${e.message}`);
return new Error(e.message);
}
},
readFile (filePath, encoding, onComplete) {
fs.readFile({
filePath: filePath,
encoding: encoding,
success: function (res) {
onComplete && onComplete(null, res.data);
},
fail: function (res) {
console.warn(`Read file failed: path: ${filePath} message: ${res.errMsg}`);
onComplete && onComplete (new Error(res.errMsg), null);
}
});
},
readDir (filePath, onComplete) {
fs.readdir({
dirPath: filePath,
success: function (res) {
onComplete && onComplete(null, res.files);
},
fail: function (res) {
console.warn(`Read directory failed: path: ${filePath} message: ${res.errMsg}`);
onComplete && onComplete(new Error(res.errMsg), null);
}
});
},
readText (filePath, onComplete) {
fsUtils.readFile(filePath, 'utf8', onComplete);
},
readArrayBuffer (filePath, onComplete) {
fsUtils.readFile(filePath, '', onComplete);
},
readJson (filePath, onComplete) {
fsUtils.readFile(filePath, 'utf8', function (err, text) {
var out = null;
if (!err) {
try {
out = JSON.parse(text);
}
catch (e) {
console.warn(`Read json failed: path: ${filePath} message: ${e.message}`);
err = new Error(e.message);
}
}
onComplete && onComplete(err, out);
});
},
readJsonSync (path) {
try {
var str = fs.readFileSync(path, 'utf8');
return JSON.parse(str);
}
catch (e) {
console.warn(`Read json failed: path: ${path} message: ${e.message}`);
return new Error(e.message);
}
},
makeDirSync (path, recursive) {
try {
fs.mkdirSync(path, recursive);
return null;
}
catch (e) {
console.warn(`Make directory failed: path: ${path} message: ${e.message}`);
return new Error(e.message);
}
},
rmdirSync (dirPath, recursive) {
try {
fs.rmdirSync(dirPath, recursive);
}
catch (e) {
console.warn(`rm directory failed: path: ${dirPath} message: ${e.message}`);
return new Error(e.message);
}
},
exists (filePath, onComplete) {
fs.access({
path: filePath,
success: function () {
onComplete && onComplete(true);
},
fail: function () {
onComplete && onComplete(false);
}
});
},
loadSubpackage (name, onProgress, onComplete) {
var task = swan.loadSubpackage({
name: name,
success: function () {
onComplete && onComplete();
},
fail: function (res) {
console.warn(`Load Subpackage failed: path: ${name} message: ${res.errMsg}`);
onComplete && onComplete(new Error(`Failed to load subpackage ${name}: ${res.errMsg}`));
}
});
onProgress && task.onProgressUpdate(onProgress);
return task;
},
unzip (zipFilePath, targetPath, onComplete) {
fs.unzip({
zipFilePath,
targetPath,
success () {
onComplete && onComplete(null);
},
fail (res) {
console.warn(`unzip failed: path: ${zipFilePath} message: ${res.errMsg}`);
onComplete && onComplete(new Error('unzip failed: ' + res.errMsg));
},
})
},
};
window.fsUtils = module.exports = fsUtils;

View File

@ -0,0 +1,101 @@
// Ensure recieving message from main context before engine being inited
let isEngineReady = false;
const game = cc.game;
game.once(game.EVENT_ENGINE_INITED, function () {
isEngineReady = true;
});
var viewportInMain = {
x: 0,
y: 0,
width: 0,
height: 0
};
// Touch conversion
cc.view.convertToLocationInView = function (tx, ty, relatedPos, out) {
var result = out || cc.v2();
var x = this._devicePixelRatio * (tx - relatedPos.left);
var y = this._devicePixelRatio * (relatedPos.top + relatedPos.height - ty);
// Move to real viewport area
x = (x - viewportInMain.x) * this._viewportRect.width / viewportInMain.width;
y = (y - viewportInMain.y) * this._viewportRect.height / viewportInMain.height;
if (this._isRotated) {
result.x = this._viewportRect.width - y;
result.y = x;
}
else {
result.x = x;
result.y = y;
}
return result;
};
// In sub context, run main loop after subContextView component get enabled.
game._prepareFinished = function (cb) {
this._prepared = true;
// Init engine
this._initEngine();
cc.assetManager.builtins.init(() => {
// Log engine version
console.log('Cocos Creator v' + cc.ENGINE_VERSION);
this._setAnimFrame();
this.emit(this.EVENT_GAME_INITED);
if (cb) cb();
});
};
swan.onMessage(function (data) {
if (data.fromEngine) {
if (data.event === 'boot') {
game._banRunningMainLoop = false;
if (game._firstSceneLaunched) {
game._runMainLoop();
}
}
else if (data.event === 'viewport') {
viewportInMain.x = data.x;
viewportInMain.y = data.y;
viewportInMain.width = data.width;
viewportInMain.height = data.height;
}
else if (data.event === 'resize') {
window.dispatchEvent({type: 'resize'});
}
else if (isEngineReady) {
if (data.event === 'mainLoop') {
if (data.value) {
game.resume();
}
else {
game.pause();
}
}
else if (data.event === 'frameRate') {
game.setFrameRate(data.value);
}
else if (data.event === 'step') {
game.step();
}
}
}
});
// Canvas component adaptation
cc.Canvas.prototype.update = function () {
if (this._width !== game.canvas.width || this._height !== game.canvas.height) {
this.applySettings();
}
};
let originalApplySettings = cc.Canvas.prototype.applySettings;
cc.Canvas.prototype.applySettings = function () {
originalApplySettings.call(this);
this._width = game.canvas.width;
this._height = game.canvas.height;
};

View File

@ -0,0 +1,25 @@
const adapter = window.__globalAdapter;
let adaptSysFunc = adapter.adaptSys;
Object.assign(adapter, {
// Extend adaptSys interface
adaptSys (sys) {
adaptSysFunc.call(this, sys, GameGlobal._env);
delete GameGlobal._env; // release env
// baidugame subdomain
if (!swan.getOpenDataContext) {
sys.platform = sys.BAIDU_GAME_SUB;
}
else {
sys.platform = sys.BAIDU_GAME;
}
// sys.glExtension = function (name) {
// if (name === 'OES_texture_float') {
// return false;
// }
// return !!cc.renderer.device.ext(name);
// };
},
});

View File

@ -0,0 +1,114 @@
const utils = require('../../../common/utils');
if (window.__globalAdapter) {
let globalAdapter = window.__globalAdapter;
let isLandscape = false; // getSystemInfoSync not supported in sub context
// SystemInfo
if (swan.getSystemInfoSync) {
let systemInfo = swan.getSystemInfoSync();
let windowWidth = systemInfo.windowWidth;
let windowHeight = systemInfo.windowHeight;
isLandscape = windowWidth > windowHeight;
globalAdapter.isDevTool = systemInfo.platform === 'devtools';
}
else {
// can't define window in devtool
let descriptor = Object.getOwnPropertyDescriptor(global, 'window');
globalAdapter.isDevTool = !(!descriptor || descriptor.configurable === true);
}
globalAdapter.isSubContext = (swan.getOpenDataContext === undefined);
utils.cloneMethod(globalAdapter, swan, 'getSystemInfoSync');
// TouchEvent
utils.cloneMethod(globalAdapter, swan, 'onTouchStart');
utils.cloneMethod(globalAdapter, swan, 'onTouchMove');
utils.cloneMethod(globalAdapter, swan, 'onTouchEnd');
utils.cloneMethod(globalAdapter, swan, 'onTouchCancel');
// Audio
utils.cloneMethod(globalAdapter, swan, 'createInnerAudioContext');
// FrameRate
utils.cloneMethod(globalAdapter, swan, 'setPreferredFramesPerSecond');
// Keyboard
utils.cloneMethod(globalAdapter, swan, 'showKeyboard');
utils.cloneMethod(globalAdapter, swan, 'hideKeyboard');
utils.cloneMethod(globalAdapter, swan, 'updateKeyboard');
utils.cloneMethod(globalAdapter, swan, 'onKeyboardInput');
utils.cloneMethod(globalAdapter, swan, 'onKeyboardConfirm');
utils.cloneMethod(globalAdapter, swan, 'onKeyboardComplete');
utils.cloneMethod(globalAdapter, swan, 'offKeyboardInput');
utils.cloneMethod(globalAdapter, swan, 'offKeyboardConfirm');
utils.cloneMethod(globalAdapter, swan, 'offKeyboardComplete');
// Message
utils.cloneMethod(globalAdapter, swan, 'getOpenDataContext');
utils.cloneMethod(globalAdapter, swan, 'onMessage');
// SharedCanvas
utils.cloneMethod(globalAdapter, swan, 'getSharedCanvas');
// Font
utils.cloneMethod(globalAdapter, swan, 'loadFont');
// hide show Event
utils.cloneMethod(globalAdapter, swan, 'onShow');
utils.cloneMethod(globalAdapter, swan, 'onHide');
// Accelerometer
let isAccelerometerInit = false;
let deviceOrientation = 1;
if (swan.onDeviceOrientationChange) {
swan.onDeviceOrientationChange(function (res) {
if (res.value === 'landscape') {
deviceOrientation = 1;
}
else if (res.value === 'landscapeReverse') {
deviceOrientation = -1;
}
});
}
Object.assign(globalAdapter, {
startAccelerometer (cb) {
if (!isAccelerometerInit) {
isAccelerometerInit = true;
swan.onAccelerometerChange && swan.onAccelerometerChange(function (res) {
let resClone = {};
let x = res.x;
let y = res.y;
if (isLandscape) {
let tmp = x;
x = -y;
y = tmp;
}
resClone.x = x * deviceOrientation;
resClone.y = y * deviceOrientation;
resClone.z = res.z;
cb && cb(resClone);
});
}
else {
swan.startAccelerometer && swan.startAccelerometer({
fail (err) {
console.error('start accelerometer failed', err);
},
// success () {},
// complete () {},
});
}
},
stopAccelerometer () {
swan.stopAccelerometer && swan.stopAccelerometer({
fail (err) {
console.error('stop accelerometer failed', err);
},
// success () {},
// complete () {},
});
},
});
}

View File

@ -0,0 +1,19 @@
const _global = GameGlobal;
const adapter = _global.__globalAdapter = {};
Object.assign(adapter, {
init () {
require('./wrapper/builtin');
_global.DOMParser = require('../../common/xmldom/dom-parser').DOMParser;
require('./wrapper/unify');
require('./wrapper/fs-utils');
require('../../common/engine/globalAdapter');
require('./wrapper/systemInfo');
},
adaptEngine () {
require('../../common/engine');
require('./wrapper/engine');
require('./wrapper/sub-context-adapter');
},
});

View File

@ -0,0 +1,11 @@
let moduleMap = {
// tail
};
window.__cocos_require__ = function (moduleName) {
let func = moduleMap[moduleName];
if (!func) {
throw new Error(`cannot find module ${moduleName}`);
}
return func();
};

View File

@ -0,0 +1,3 @@
{
"main": "cocos2d-js-min.js"
}

View File

@ -0,0 +1,9 @@
{
"provider": "tt9186e73b0ebd04c2",
"signature": [
{
"path": "cocos2d-js-min.js",
"md5": ""
}
]
}

View File

@ -0,0 +1,20 @@
require('adapter-js-path');
__globalAdapter.init();
require('cocos2d-js-path');
require('physics-js-path');
__globalAdapter.adaptEngine();
require('./ccRequire');
require('./src/settings');
// Introduce Cocos Service here
require('./main'); // TODO: move to common
// Adjust devicePixelRatio
cc.view._maxPixelRatio = 4;
if (cc.sys.platform !== cc.sys.BYTEDANCE_GAME_SUB) {
// Release Image objects after uploaded gl texture
cc.macro.CLEANUP_IMAGE_CACHE = true;
}
window.boot();

View File

@ -0,0 +1,18 @@
{
"deviceOrientation": "portrait",
"showStatusBar": false,
"openDataContext": "",
"networkTimeout": {
"request": 5000,
"connectSocket": 20000,
"uploadFile": 5000,
"downloadFile": 5000
},
"plugins": {
"cocos": {
"provider": "tt9186e73b0ebd04c2",
"version": "",
"path": "cocos"
}
}
}

View File

@ -0,0 +1,67 @@
window.boot = function () {
var settings = window._CCSettings;
window._CCSettings = undefined;
var onStart = function () {
cc.view.enableRetina(true);
cc.view.resizeWithBrowserSize(true);
var launchScene = settings.launchScene;
// load scene
cc.director.loadScene(launchScene, null,
function () {
console.log('Success to load scene: ' + launchScene);
}
);
};
var isSubContext = __globalAdapter.isSubContext;
var option = {
id: 'GameCanvas',
debugMode: settings.debug ? cc.debug.DebugMode.INFO : cc.debug.DebugMode.ERROR,
showFPS: !isSubContext && settings.debug,
frameRate: 60,
groupList: settings.groupList,
collisionMatrix: settings.collisionMatrix,
}
cc.assetManager.init({
bundleVers: settings.bundleVers,
subpackages: settings.subpackages,
remoteBundles: settings.remoteBundles,
server: settings.server,
subContextRoot: settings.subContextRoot
});
var RESOURCES = cc.AssetManager.BuiltinBundleName.RESOURCES;
var INTERNAL = cc.AssetManager.BuiltinBundleName.INTERNAL;
var MAIN = cc.AssetManager.BuiltinBundleName.MAIN;
var START_SCENE = cc.AssetManager.BuiltinBundleName.START_SCENE;
var bundleRoot = [INTERNAL];
settings.hasResourcesBundle && bundleRoot.push(RESOURCES);
settings.hasStartSceneBundle && bundleRoot.push(MAIN);
var count = 0;
function cb (err) {
if (err) return console.error(err.message, err.stack);
count++;
if (count === bundleRoot.length + 1) {
// if there is start-scene bundle. should load start-scene bundle in the last stage
// Otherwise the main bundle should be the last
cc.assetManager.loadBundle(settings.hasStartSceneBundle ? START_SCENE : MAIN, function (err) {
if (!err) cc.game.run(option, onStart);
});
}
}
// load plugins
cc.assetManager.loadScript(settings.jsList.map(function (x) { return 'src/' + x;}), cb);
// load bundles
for (var i = 0; i < bundleRoot.length; i++) {
cc.assetManager.loadBundle(bundleRoot[i], cb);
}
};

View File

@ -0,0 +1,11 @@
{
"setting": {
"urlCheck": true,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true
},
"appid": "testappId",
"projectname": ""
}

View File

@ -0,0 +1,205 @@
import HTMLAudioElement from './HTMLAudioElement'
const HAVE_NOTHING = 0
const HAVE_METADATA = 1
const HAVE_CURRENT_DATA = 2
const HAVE_FUTURE_DATA = 3
const HAVE_ENOUGH_DATA = 4
let SN_SEED = 1
const _innerAudioContextMap = {}
export default class Audio extends HTMLAudioElement {
constructor(url) {
super()
this._$sn = SN_SEED++;
this.HAVE_NOTHING = HAVE_NOTHING
this.HAVE_METADATA = HAVE_METADATA
this.HAVE_CURRENT_DATA = HAVE_CURRENT_DATA
this.HAVE_FUTURE_DATA = HAVE_FUTURE_DATA
this.HAVE_ENOUGH_DATA = HAVE_ENOUGH_DATA
this.readyState = HAVE_NOTHING
const innerAudioContext = tt.createInnerAudioContext()
_innerAudioContextMap[this._$sn] = innerAudioContext
this._canplayEvents = [
'load',
'loadend',
'canplay',
'canplaythrough',
'loadedmetadata'
]
innerAudioContext.onCanplay(() => {
this._loaded = true
this.readyState = this.HAVE_CURRENT_DATA
this._canplayEvents.forEach((type) => {
this.dispatchEvent({ type: type })
})
})
innerAudioContext.onPlay(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
this.dispatchEvent({ type: 'play' })
})
innerAudioContext.onPause(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
this.dispatchEvent({ type: 'pause' })
})
innerAudioContext.onEnded(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
if (_innerAudioContextMap[this._$sn].loop === false) {
this.dispatchEvent({ type: 'ended' })
}
this.readyState = HAVE_ENOUGH_DATA
})
innerAudioContext.onError(() => {
this._paused = _innerAudioContextMap[this._$sn].paused
this.dispatchEvent({ type: 'error' })
})
if (url) {
this.src = url
} else {
this._src = ''
}
this._loop = innerAudioContext.loop
this._autoplay = innerAudioContext.autoplay
this._paused = innerAudioContext.paused
this._volume = innerAudioContext.volume
this._muted = false;
}
addEventListener(type, listener, options = {}) {
super.addEventListener(type, listener, options)
type = String(type).toLowerCase()
if (this._loaded && this._canplayEvents.indexOf(type) !== -1) {
this.dispatchEvent({ type: type })
}
}
load() {
// console.warn('HTMLAudioElement.load() is not implemented.')
// weixin doesn't need call load() manually
}
play() {
_innerAudioContextMap[this._$sn].play()
}
resume() {
_innerAudioContextMap[this._$sn].resume()
}
pause() {
_innerAudioContextMap[this._$sn].pause()
}
stop() {
_innerAudioContextMap[this._$sn].stop()
}
destroy() {
_innerAudioContextMap[this._$sn].destroy()
}
canPlayType(mediaType = '') {
if (typeof mediaType !== 'string') {
return ''
}
if (mediaType.indexOf('audio/mpeg') > -1 || mediaType.indexOf('audio/mp4')) {
return 'probably'
}
return ''
}
get currentTime() {
return _innerAudioContextMap[this._$sn].currentTime
}
set currentTime(value) {
_innerAudioContextMap[this._$sn].seek(value)
}
get duration () {
return _innerAudioContextMap[this._$sn].duration
}
get src() {
return this._src
}
set src(value) {
this._src = value
this._loaded = false
this.readyState = this.HAVE_NOTHING
const innerAudioContext = _innerAudioContextMap[this._$sn]
innerAudioContext.src = value
}
get loop() {
return this._loop
}
set loop(value) {
this._loop = value
_innerAudioContextMap[this._$sn].loop = value
}
get autoplay() {
return this.autoplay
}
set autoplay(value) {
this._autoplay = value
_innerAudioContextMap[this._$sn].autoplay = value
}
get paused() {
return this._paused;
}
get volume() {
return this._volume;
}
set volume(value) {
this._volume = value;
if (!this._muted) {
_innerAudioContextMap[this._$sn].volume = value;
}
}
get muted() {
return this._muted;
}
set muted(value) {
this._muted = value;
if (value) {
_innerAudioContextMap[this._$sn].volume = 0;
} else {
_innerAudioContextMap[this._$sn].volume = this._volume;
}
}
cloneNode() {
const newAudio = new Audio()
newAudio.loop = this.loop
newAudio.autoplay = this.autoplay
newAudio.src = this.src
return newAudio
}
}

View File

@ -0,0 +1,64 @@
// import HTMLCanvasElement from './HTMLCanvasElement'
import { innerWidth, innerHeight } from './WindowProperties'
let hasModifiedCanvasPrototype = false
let hasInit2DContextConstructor = false
let hasInitWebGLContextConstructor = false
export default function Canvas() {
const canvas = tt.createCanvas()
canvas.type = 'canvas'
// canvas.__proto__.__proto__.__proto__ = new HTMLCanvasElement()
const _getContext = canvas.getContext
canvas.getBoundingClientRect = () => {
const ret = {
top: 0,
left: 0,
width: window.innerWidth,
height: window.innerHeight
}
return ret
}
canvas.style = {
top: '0px',
left: '0px',
width: innerWidth + 'px',
height: innerHeight + 'px',
}
canvas.addEventListener = function (type, listener, options = {}) {
// console.log('canvas.addEventListener', type);
document.addEventListener(type, listener, options);
}
canvas.removeEventListener = function (type, listener) {
// console.log('canvas.removeEventListener', type);
document.removeEventListener(type, listener);
}
canvas.dispatchEvent = function (event = {}) {
console.log('canvas.dispatchEvent' , event.type, event);
// nothing to do
}
Object.defineProperty(canvas, 'clientWidth', {
enumerable: true,
get: function get() {
return innerWidth
}
})
Object.defineProperty(canvas, 'clientHeight', {
enumerable: true,
get: function get() {
return innerHeight
}
})
return canvas
}

View File

@ -0,0 +1,10 @@
import Node from './Node'
export default class Element extends Node {
className = ''
children = []
constructor() {
super()
}
}

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