Merge branch 'devel' into release-1.3

This commit is contained in:
Martijn Walraven
2016-02-09 11:03:26 +01:00
11 changed files with 124 additions and 89 deletions

View File

@@ -158,7 +158,7 @@ designed to stand separately. At the same time, all the parts of core fit toget
distinctive Meteor development experience. Core APIs should be consistent between the client and
the server (not always workable; we don't have fibers on the client or a DOM on the server). We
prefer synchronous APIs wherever possible: you can use `Meteor.wrapAsync` on the server to wrap
async APIs that take a callback.
async APIs that take a callback.
Above all, we are concerned with two design requirements when evaluating
any change to a core package:
@@ -242,6 +242,17 @@ these guidelines:
* Be sure your author field in git is properly filled out with your full name
and email address so we can credit you.
#### Need help with your pull request?
Meteor now has groups defined to cover different areas of the codebase. If you need help getting acceptance on a certain pull requests with an area of focus listed below, you can address the appropriate people in the pull request:
* Meteor Data Team - This includes DDP, tracker, mongo, accounts, etc. You can mention @stubailo in the PR.
* Blaze - This includes Spacebars, Blaze, etc. You can mention @urigo or @yyx990803 in the PR.
* Build tools - This includes modules, build tool changes, etc. You can memtion @avital or @benjamn in the PR.
* Mobile integration - This includes Cordova, React Native, etc. You can mention @martijnwalraven in the PR.
Including the people above is no guarantee that you will get a response, or ultimately that your pull request will be accepted. This section exists to give some minor guidance on internal Meteor Development Group team structures.
## Running tests on Meteor core
When you are working with code in the core Meteor packages, you will want to make sure you run the

View File

@@ -139,6 +139,10 @@
* Detect new Facebook user-agent in the `spiderable` package. #5516
* `check` will now check all keys of an object, including inherited ones #6140
* Allow `git+` URL schemes for npm dependencies #844
Patches contributed by GitHub users vereed, mitar, nathan-muir,
robfallows, skishore, okland, Primigenus, zimme, welelay, rgoomar,
bySabi, mbrookes, TomFreudenberg, TechPlexEngineer, zacharydenton,

View File

@@ -19,12 +19,10 @@ $(document).on("keydown", function (event) {
}
});
// Open search with any non-special key
var keysToOpenSearch = /[A-Za-z0-9]/;
$(document).on("keydown", function (event) {
// Don't activate search for special keys or keys with modifiers
if (event.which && keysToOpenSearch.test(String.fromCharCode(event.which)) &&
(! event.ctrlKey) && (! event.metaKey) && (! Session.get("searchOpen"))) {
if (event.which >= 48 && event.which <= 90 && (!event.ctrlKey) &&
(!event.metaKey) && (!Session.get("searchOpen"))) {
Session.set("searchOpen", true);
Tracker.flush();

3
meteor
View File

@@ -1,8 +1,9 @@
#!/usr/bin/env bash
# Note: 0.5.17 used on branch origin/npm3
# Note: 0.5.20 used on branch origin/cordova-improvements
# Note: 0.5.20 and 0.5.25 used on branch origin/cordova-improvements
# Note: 0.5.21 used on branch release-1.2.2
# Note: 0.5.23 used on branch release-1.3
BUNDLE_VERSION=0.5.24
# OS Check. Put here because here is where we download the precompiled

View File

@@ -325,7 +325,16 @@ var testSubtree = function (value, pattern) {
requiredPatterns[key] = subPattern;
});
for (var keys = _.keys(value), i = 0, length = keys.length; i < length; i++) {
//XXX: replace with underscore's _.allKeys if Meteor updates underscore to 1.8+ (or lodash)
var allKeys = function(obj){
var keys = [];
if (_.isObject(obj)){
for (var key in obj) keys.push(key);
}
return keys;
}
for (var keys = allKeys(value), i = 0, length = keys.length; i < length; i++) {
var key = keys[i];
var subValue = value[key];
if (_.has(requiredPatterns, key)) {

View File

@@ -161,6 +161,14 @@ Tinytest.add("check - check", function (test) {
fails(function () {}, Match.Integer);
fails(new Date, Match.Integer);
// Test objects that have a prototype
var parentObj = {foo:"bar"};
var childObj = Object.assign(Object.create(parentObj),{bar:"foo"});
matches(childObj,{foo:String,bar:String});
fails(childObj,{bar:String});
// Test that "arguments" is treated like an array.
var argumentsMatches = function () {
matches(arguments, [Number]);

View File

@@ -12,7 +12,7 @@ Package.onUse(function (api) {
});
Package.onTest(function (api) {
api.use(['check', 'tinytest', 'underscore', 'ejson'], ['client', 'server']);
api.use(['check', 'tinytest', 'underscore', 'ejson', 'ecmascript'], ['client', 'server']);
api.addFiles('match_test.js', ['client', 'server']);
});

View File

@@ -323,7 +323,7 @@ var staticFiles;
// Serve static files from the manifest or added with
// `addStaticJs`. Exported for tests.
WebAppInternals.staticFilesMiddleware = function (staticFiles, req, res, next) {
if ('GET' != req.method && 'HEAD' != req.method) {
if ('GET' != req.method && 'HEAD' != req.method && 'OPTIONS' != req.method) {
next();
return;
}
@@ -501,9 +501,9 @@ var runWebAppServer = function () {
// Serve the program as a string at /foo/<arch>/manifest.json
// XXX change manifest.json -> program.json
staticFiles[path.join(urlPrefix, getItemPathname('/manifest.json'))] = {
staticFiles[urlPrefix + getItemPathname('/manifest.json')] = {
content: JSON.stringify(program),
cacheable: true,
cacheable: false,
hash: program.version,
type: "json"
};
@@ -649,81 +649,83 @@ var runWebAppServer = function () {
});
app.use(function (req, res, next) {
if (! appUrl(req.url))
return next();
Fiber(function () {
if (!appUrl(req.url))
return next();
var headers = {
'Content-Type': 'text/html; charset=utf-8'
};
if (shuttingDown)
headers['Connection'] = 'Close';
var headers = {
'Content-Type': 'text/html; charset=utf-8'
};
if (shuttingDown)
headers['Connection'] = 'Close';
var request = WebApp.categorizeRequest(req);
var request = WebApp.categorizeRequest(req);
if (request.url.query && request.url.query['meteor_css_resource']) {
// In this case, we're requesting a CSS resource in the meteor-specific
// way, but we don't have it. Serve a static css file that indicates that
// we didn't have it, so we can detect that and refresh. Make sure
// that any proxies or CDNs don't cache this error! (Normally proxies
// or CDNs are smart enough not to cache error pages, but in order to
// make this hack work, we need to return the CSS file as a 200, which
// would otherwise be cached.)
headers['Content-Type'] = 'text/css; charset=utf-8';
headers['Cache-Control'] = 'no-cache';
res.writeHead(200, headers);
res.write(".meteor-css-not-found-error { width: 0px;}");
if (request.url.query && request.url.query['meteor_css_resource']) {
// In this case, we're requesting a CSS resource in the meteor-specific
// way, but we don't have it. Serve a static css file that indicates that
// we didn't have it, so we can detect that and refresh. Make sure
// that any proxies or CDNs don't cache this error! (Normally proxies
// or CDNs are smart enough not to cache error pages, but in order to
// make this hack work, we need to return the CSS file as a 200, which
// would otherwise be cached.)
headers['Content-Type'] = 'text/css; charset=utf-8';
headers['Cache-Control'] = 'no-cache';
res.writeHead(200, headers);
res.write(".meteor-css-not-found-error { width: 0px;}");
res.end();
return undefined;
}
if (request.url.query && request.url.query['meteor_js_resource']) {
// Similarly, we're requesting a JS resource that we don't have.
// Serve an uncached 404. (We can't use the same hack we use for CSS,
// because actually acting on that hack requires us to have the JS
// already!)
headers['Cache-Control'] = 'no-cache';
res.writeHead(404, headers);
res.end("404 Not Found");
return undefined;
}
if (request.url.query && request.url.query['meteor_dont_serve_index']) {
// When downloading files during a Cordova hot code push, we need
// to detect if a file is not available instead of inadvertently
// downloading the default index page.
// So similar to the situation above, we serve an uncached 404.
headers['Cache-Control'] = 'no-cache';
res.writeHead(404, headers);
res.end("404 Not Found");
return undefined;
}
// /packages/asdfsad ... /__cordova/dafsdf.js
var pathname = parseurl(req).pathname;
var archKey = pathname.split('/')[1];
var archKeyCleaned = 'web.' + archKey.replace(/^__/, '');
if (!/^__/.test(archKey) || !_.has(archPath, archKeyCleaned)) {
archKey = WebApp.defaultArch;
} else {
archKey = archKeyCleaned;
}
var boilerplate;
try {
boilerplate = getBoilerplate(request, archKey);
} catch (e) {
Log.error("Error running template: " + e.stack);
res.writeHead(500, headers);
res.end();
return undefined;
}
var statusCode = res.statusCode ? res.statusCode : 200;
res.writeHead(statusCode, headers);
res.write(boilerplate);
res.end();
return undefined;
}
if (request.url.query && request.url.query['meteor_js_resource']) {
// Similarly, we're requesting a JS resource that we don't have.
// Serve an uncached 404. (We can't use the same hack we use for CSS,
// because actually acting on that hack requires us to have the JS
// already!)
headers['Cache-Control'] = 'no-cache';
res.writeHead(404, headers);
res.end("404 Not Found");
return undefined;
}
if (request.url.query && request.url.query['meteor_dont_serve_index']) {
// When downloading files during a Cordova hot code push, we need
// to detect if a file is not available instead of inadvertently
// downloading the default index page.
// So similar to the situation above, we serve an uncached 404.
headers['Cache-Control'] = 'no-cache';
res.writeHead(404, headers);
res.end("404 Not Found");
return undefined;
}
// /packages/asdfsad ... /__cordova/dafsdf.js
var pathname = parseurl(req).pathname;
var archKey = pathname.split('/')[1];
var archKeyCleaned = 'web.' + archKey.replace(/^__/, '');
if (! /^__/.test(archKey) || ! _.has(archPath, archKeyCleaned)) {
archKey = WebApp.defaultArch;
} else {
archKey = archKeyCleaned;
}
var boilerplate;
try {
boilerplate = getBoilerplate(request, archKey);
} catch (e) {
Log.error("Error running template: " + e.stack);
res.writeHead(500, headers);
res.end();
return undefined;
}
var statusCode = res.statusCode ? res.statusCode : 200;
res.writeHead(statusCode, headers);
res.write(boilerplate);
res.end();
return undefined;
}).run();
});
// Return 404 by default, if no other handlers serve this URL.

View File

@@ -43,7 +43,7 @@ main.registerCommand({
for (platform of platformsToAdd) {
if (_.contains(installedPlatforms, platform)) {
buildmessage.error(`${platform}: platform is already added`);
} else if (!_.contains(cordova.AVAILABLE_PLATFORMS, platform)) {
} else if (!_.contains(cordova.CORDOVA_PLATFORMS, platform)) {
buildmessage.error(`${platform}: no such platform`);
}
}
@@ -67,7 +67,9 @@ main.registerCommand({
for (platform of platformsToAdd) {
Console.info(`${platform}: added platform`);
cordovaProject.checkPlatformRequirements(platform);
if (_.contains(cordovaPlatforms, platform)) {
cordovaProject.checkPlatformRequirements(platform);
}
}
});
});
@@ -142,10 +144,10 @@ main.registerCommand({
const platform = options.args[0];
if (!_.contains(cordova.AVAILABLE_PLATFORMS, platform)) {
if (!_.contains(cordova.CORDOVA_PLATFORMS, platform)) {
Console.warn(`Unknown platform: ${platform}`);
Console.info(`Valid platforms are: \
${cordova.AVAILABLE_PLATFORMS.join(', ')}`);
${cordova.CORDOVA_PLATFORMS.join(', ')}`);
return 1;
}

View File

@@ -8,7 +8,7 @@ import { oldToNew as oldToNewPluginIds, newToOld as newToOldPluginIds }
export const CORDOVA_ARCH = "web.cordova";
export const AVAILABLE_PLATFORMS = ['ios', 'android'];
export const CORDOVA_PLATFORMS = ['ios', 'android'];
const PLATFORM_TO_DISPLAY_NAME_MAP = {
'ios': 'iOS',
@@ -28,7 +28,7 @@ export function displayNamesForPlatforms(platforms) {
// Right now, the only other platforms are the default browser and server
// platforms.
export function filterPlatforms(platforms) {
return _.intersection(platforms, AVAILABLE_PLATFORMS);
return _.intersection(platforms, CORDOVA_PLATFORMS);
}
export function splitPluginsAndPackages(packages) {

View File

@@ -21,7 +21,7 @@ import cordova_util from 'cordova-lib/src/cordova/util.js';
import superspawn from 'cordova-lib/src/cordova/superspawn.js';
import PluginInfoProvider from 'cordova-lib/src/PluginInfoProvider.js';
import { AVAILABLE_PLATFORMS, displayNameForPlatform, displayNamesForPlatforms,
import { CORDOVA_PLATFORMS, displayNameForPlatform, displayNamesForPlatforms,
newPluginId, convertPluginVersions, convertToGitUrl,
installationInstructionsUrlForPlatform } from './index.js';
import { CordovaBuilder } from './builder.js';
@@ -363,7 +363,7 @@ from Cordova project`, async () => {
for (platform of installedPlatforms) {
if (!_.contains(platforms, platform) &&
_.contains(AVAILABLE_PLATFORMS, platform)) {
_.contains(CORDOVA_PLATFORMS, platform)) {
this.removePlatform(platform);
}
}