зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1070479 - Allow passing uri specs to transactions. r=mak.
This commit is contained in:
Родитель
33627a20f5
Коммит
5a42d8ad31
|
@ -54,7 +54,7 @@ this.EXPORTED_SYMBOLS = ["PlacesTransactions"];
|
||||||
* valid values across all transactions which accept it in the input object.
|
* valid values across all transactions which accept it in the input object.
|
||||||
* Here is a list of all supported input properties along with their expected
|
* Here is a list of all supported input properties along with their expected
|
||||||
* values:
|
* values:
|
||||||
* - uri: an nsIURI object.
|
* - uri: an nsIURI object or an uri spec string.
|
||||||
* - feedURI: an nsIURI object, holding the url for a live bookmark.
|
* - feedURI: an nsIURI object, holding the url for a live bookmark.
|
||||||
* - siteURI: an nsIURI object, holding the url for the site with which
|
* - siteURI: an nsIURI object, holding the url for the site with which
|
||||||
* a live bookmark is associated.
|
* a live bookmark is associated.
|
||||||
|
@ -576,15 +576,28 @@ function DefineTransaction(aRequiredProps = [], aOptionalProps = []) {
|
||||||
return ctor;
|
return ctor;
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineTransaction.isStr = v => typeof(v) == "string";
|
function simpleValidateFunc(aCheck) {
|
||||||
DefineTransaction.isStrOrNull = v => typeof(v) == "string" || v === null;
|
return v => {
|
||||||
DefineTransaction.isURI = v => v instanceof Components.interfaces.nsIURI;
|
if (!aCheck(v))
|
||||||
DefineTransaction.isIndex = v => Number.isInteger(v) &&
|
throw new Error("Invalid value");
|
||||||
v >= PlacesUtils.bookmarks.DEFAULT_INDEX;
|
return v;
|
||||||
DefineTransaction.isGuid = v => /^[a-zA-Z0-9\-_]{12}$/.test(v);
|
};
|
||||||
DefineTransaction.isPrimitive = v => v === null || (typeof(v) != "object" &&
|
}
|
||||||
typeof(v) != "function");
|
|
||||||
DefineTransaction.isAnnotationObject = function (obj) {
|
DefineTransaction.strValidate = simpleValidateFunc(v => typeof(v) == "string");
|
||||||
|
DefineTransaction.strOrNullValidate =
|
||||||
|
simpleValidateFunc(v => typeof(v) == "string" || v === null);
|
||||||
|
DefineTransaction.indexValidate =
|
||||||
|
simpleValidateFunc(v => Number.isInteger(v) &&
|
||||||
|
v >= PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||||
|
DefineTransaction.guidValidate =
|
||||||
|
simpleValidateFunc(v => /^[a-zA-Z0-9\-_]{12}$/.test(v));
|
||||||
|
|
||||||
|
function isPrimitive(v) {
|
||||||
|
return v === null || (typeof(v) != "object" && typeof(v) != "function");
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineTransaction.annotationObjectValidate = function (obj) {
|
||||||
let checkProperty = (aPropName, aRequired, aCheckFunc) => {
|
let checkProperty = (aPropName, aRequired, aCheckFunc) => {
|
||||||
if (aPropName in obj)
|
if (aPropName in obj)
|
||||||
return aCheckFunc(obj[aPropName]);
|
return aCheckFunc(obj[aPropName]);
|
||||||
|
@ -593,22 +606,27 @@ DefineTransaction.isAnnotationObject = function (obj) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (obj &&
|
if (obj &&
|
||||||
checkProperty("name", true, DefineTransaction.isStr) &&
|
checkProperty("name", true, v => typeof(v) == "string" && v.length > 0) &&
|
||||||
checkProperty("expires", false, Number.isInteger) &&
|
checkProperty("expires", false, Number.isInteger) &&
|
||||||
checkProperty("flags", false, Number.isInteger) &&
|
checkProperty("flags", false, Number.isInteger) &&
|
||||||
checkProperty("value", false, DefineTransaction.isPrimitive) ) {
|
checkProperty("value", false, isPrimitive) ) {
|
||||||
// Nothing else should be set
|
// Nothing else should be set
|
||||||
let validKeys = ["name", "value", "flags", "expires"];
|
let validKeys = ["name", "value", "flags", "expires"];
|
||||||
if (Object.keys(obj).every( (k) => validKeys.indexOf(k) != -1 ))
|
if (Object.keys(obj).every( (k) => validKeys.indexOf(k) != -1 ))
|
||||||
return true;
|
return obj;
|
||||||
}
|
}
|
||||||
return false;
|
throw new Error("Invalid annotation object");
|
||||||
|
};
|
||||||
|
|
||||||
|
DefineTransaction.uriValidate = function(uriOrSpec) {
|
||||||
|
if (uriOrSpec instanceof Components.interfaces.nsIURI)
|
||||||
|
return uriOrSpec;
|
||||||
|
return NetUtil.newURI(uriOrSpec);
|
||||||
};
|
};
|
||||||
|
|
||||||
DefineTransaction.inputProps = new Map();
|
DefineTransaction.inputProps = new Map();
|
||||||
DefineTransaction.defineInputProps =
|
DefineTransaction.defineInputProps =
|
||||||
function (aNames, aValidationFunction,
|
function (aNames, aValidationFunction, aDefaultValue) {
|
||||||
aDefaultValue, aTransformFunction = null) {
|
|
||||||
for (let name of aNames) {
|
for (let name of aNames) {
|
||||||
// Workaround bug 449811.
|
// Workaround bug 449811.
|
||||||
let propName = name;
|
let propName = name;
|
||||||
|
@ -616,9 +634,12 @@ function (aNames, aValidationFunction,
|
||||||
validateValue: function (aValue) {
|
validateValue: function (aValue) {
|
||||||
if (aValue === undefined)
|
if (aValue === undefined)
|
||||||
return aDefaultValue;
|
return aDefaultValue;
|
||||||
if (!aValidationFunction(aValue))
|
try {
|
||||||
|
return aValidationFunction(aValue);
|
||||||
|
}
|
||||||
|
catch(ex) {
|
||||||
throw new Error(`Invalid value for input property ${propName}`);
|
throw new Error(`Invalid value for input property ${propName}`);
|
||||||
return aTransformFunction ? aTransformFunction(aValue) : aValue;
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
validateInput: function (aInput, aRequired) {
|
validateInput: function (aInput, aRequired) {
|
||||||
|
@ -720,7 +741,7 @@ function (aInput, aRequiredProps = [], aOptionalProps = []) {
|
||||||
// the moment anyway).
|
// the moment anyway).
|
||||||
let input = aInput;
|
let input = aInput;
|
||||||
let isSinglePropertyInput =
|
let isSinglePropertyInput =
|
||||||
this.isPrimitive(aInput) ||
|
isPrimitive(aInput) ||
|
||||||
Array.isArray(aInput) ||
|
Array.isArray(aInput) ||
|
||||||
(aInput instanceof Components.interfaces.nsISupports);
|
(aInput instanceof Components.interfaces.nsISupports);
|
||||||
if (isSinglePropertyInput) {
|
if (isSinglePropertyInput) {
|
||||||
|
@ -743,19 +764,19 @@ function (aInput, aRequiredProps = [], aOptionalProps = []) {
|
||||||
// Update the documentation at the top of this module if you add or
|
// Update the documentation at the top of this module if you add or
|
||||||
// remove properties.
|
// remove properties.
|
||||||
DefineTransaction.defineInputProps(["uri", "feedURI", "siteURI"],
|
DefineTransaction.defineInputProps(["uri", "feedURI", "siteURI"],
|
||||||
DefineTransaction.isURI, null);
|
DefineTransaction.uriValidate, null);
|
||||||
DefineTransaction.defineInputProps(["guid", "parentGuid", "newParentGuid"],
|
DefineTransaction.defineInputProps(["guid", "parentGuid", "newParentGuid"],
|
||||||
DefineTransaction.isGuid);
|
DefineTransaction.guidValidate);
|
||||||
DefineTransaction.defineInputProps(["title"],
|
DefineTransaction.defineInputProps(["title"],
|
||||||
DefineTransaction.isStrOrNull, null);
|
DefineTransaction.strOrNullValidate, null);
|
||||||
DefineTransaction.defineInputProps(["keyword", "postData", "tag",
|
DefineTransaction.defineInputProps(["keyword", "postData", "tag",
|
||||||
"excludingAnnotation"],
|
"excludingAnnotation"],
|
||||||
DefineTransaction.isStr, "");
|
DefineTransaction.strValidate, "");
|
||||||
DefineTransaction.defineInputProps(["index", "newIndex"],
|
DefineTransaction.defineInputProps(["index", "newIndex"],
|
||||||
DefineTransaction.isIndex,
|
DefineTransaction.indexValidate,
|
||||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||||
DefineTransaction.defineInputProps(["annotation"],
|
DefineTransaction.defineInputProps(["annotation"],
|
||||||
DefineTransaction.isAnnotationObject);
|
DefineTransaction.annotationObjectValidate);
|
||||||
DefineTransaction.defineArrayInputProp("uris", "uri");
|
DefineTransaction.defineArrayInputProp("uris", "uri");
|
||||||
DefineTransaction.defineArrayInputProp("tags", "tag");
|
DefineTransaction.defineArrayInputProp("tags", "tag");
|
||||||
DefineTransaction.defineArrayInputProp("annotations", "annotation");
|
DefineTransaction.defineArrayInputProp("annotations", "annotation");
|
||||||
|
|
|
@ -1078,8 +1078,9 @@ add_task(function* test_edit_keyword() {
|
||||||
ensureUndoState();
|
ensureUndoState();
|
||||||
});
|
});
|
||||||
|
|
||||||
add_task(function* doTest() {
|
add_task(function* test_tag_uri() {
|
||||||
let bm_info_a = { uri: NetUtil.newURI("http://bookmarked.uri")
|
// This also tests passing uri specs.
|
||||||
|
let bm_info_a = { uri: "http://bookmarked.uri"
|
||||||
, parentGuid: yield PlacesUtils.promiseItemGuid(root) };
|
, parentGuid: yield PlacesUtils.promiseItemGuid(root) };
|
||||||
let bm_info_b = { uri: NetUtil.newURI("http://bookmarked2.uri")
|
let bm_info_b = { uri: NetUtil.newURI("http://bookmarked2.uri")
|
||||||
, parentGuid: yield PlacesUtils.promiseItemGuid(root) };
|
, parentGuid: yield PlacesUtils.promiseItemGuid(root) };
|
||||||
|
@ -1102,6 +1103,9 @@ add_task(function* doTest() {
|
||||||
let uris = "uri" in aInfo ? [aInfo.uri] : aInfo.uris;
|
let uris = "uri" in aInfo ? [aInfo.uri] : aInfo.uris;
|
||||||
let tags = "tag" in aInfo ? [aInfo.tag] : aInfo.tags;
|
let tags = "tag" in aInfo ? [aInfo.tag] : aInfo.tags;
|
||||||
|
|
||||||
|
let ensureURI = uri => typeof(uri) == "string" ? NetUtil.newURI(uri) : uri;
|
||||||
|
uris = [for (uri of uris) ensureURI(uri)];
|
||||||
|
|
||||||
let tagWillAlsoBookmark = new Set();
|
let tagWillAlsoBookmark = new Set();
|
||||||
for (let uri of uris) {
|
for (let uri of uris) {
|
||||||
if (!(yield promiseIsBookmarked(uri))) {
|
if (!(yield promiseIsBookmarked(uri))) {
|
||||||
|
@ -1557,3 +1561,17 @@ add_task(function* test_copy_excluding_annotations() {
|
||||||
yield PT.undo();
|
yield PT.undo();
|
||||||
yield PT.clearTransactionsHistory();
|
yield PT.clearTransactionsHistory();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(function* test_invalid_uri_spec_throws() {
|
||||||
|
let rootGuid = yield PlacesUtils.promiseItemGuid(root);
|
||||||
|
Assert.throws(() =>
|
||||||
|
PT.NewBookmark({ parentGuid: rootGuid
|
||||||
|
, uri: "invalid uri spec"
|
||||||
|
, title: "test bookmark" }));
|
||||||
|
Assert.throws(() =>
|
||||||
|
PT.Tag({ tag: "TheTag"
|
||||||
|
, uris: ["invalid uri spec"] }));
|
||||||
|
Assert.throws(() =>
|
||||||
|
PT.Tag({ tag: "TheTag"
|
||||||
|
, uris: ["about:blank", "invalid uri spec"] }));
|
||||||
|
});
|
||||||
|
|
Загрузка…
Ссылка в новой задаче