|
1817 | 1817 | copy2[symbol] = value[symbol];
|
1818 | 1818 | });
|
1819 | 1819 | return copy2;
|
1820 |
| - } else if (isJSONObject(value)) { |
| 1820 | + } |
| 1821 | + if (isJSONObject(value)) { |
1821 | 1822 | const copy2 = {
|
1822 | 1823 | ...value
|
1823 | 1824 | };
|
1824 | 1825 | Object.getOwnPropertySymbols(value).forEach((symbol) => {
|
1825 | 1826 | copy2[symbol] = value[symbol];
|
1826 | 1827 | });
|
1827 | 1828 | return copy2;
|
1828 |
| - } else { |
1829 |
| - return value; |
1830 | 1829 | }
|
| 1830 | + return value; |
1831 | 1831 | }
|
1832 | 1832 | function applyProp(object, key, value) {
|
1833 | 1833 | if (object[key] === value) {
|
1834 | 1834 | return object;
|
1835 |
| - } else { |
1836 |
| - const updatedObject = shallowClone(object); |
1837 |
| - updatedObject[key] = value; |
1838 |
| - return updatedObject; |
1839 | 1835 | }
|
| 1836 | + const updatedObject = shallowClone(object); |
| 1837 | + updatedObject[key] = value; |
| 1838 | + return updatedObject; |
1840 | 1839 | }
|
1841 | 1840 | function getIn(object, path) {
|
1842 | 1841 | let value = object;
|
|
1845 | 1844 | if (isJSONObject(value)) {
|
1846 | 1845 | value = value[path[i]];
|
1847 | 1846 | } else if (isJSONArray(value)) {
|
1848 |
| - value = value[parseInt(path[i])]; |
| 1847 | + value = value[Number.parseInt(path[i])]; |
1849 | 1848 | } else {
|
1850 | 1849 | value = void 0;
|
1851 | 1850 | }
|
|
1862 | 1861 | const updatedValue = setIn(object ? object[key] : void 0, path.slice(1), value, createPath);
|
1863 | 1862 | if (isJSONObject(object) || isJSONArray(object)) {
|
1864 | 1863 | return applyProp(object, key, updatedValue);
|
1865 |
| - } else { |
1866 |
| - if (createPath) { |
1867 |
| - const newObject = IS_INTEGER_REGEX.test(key) ? [] : {}; |
1868 |
| - newObject[key] = updatedValue; |
1869 |
| - return newObject; |
1870 |
| - } else { |
1871 |
| - throw new Error("Path does not exist"); |
1872 |
| - } |
1873 | 1864 | }
|
| 1865 | + if (createPath) { |
| 1866 | + const newObject = IS_INTEGER_REGEX.test(key) ? [] : {}; |
| 1867 | + newObject[key] = updatedValue; |
| 1868 | + return newObject; |
| 1869 | + } |
| 1870 | + throw new Error("Path does not exist"); |
1874 | 1871 | }
|
1875 | 1872 | var IS_INTEGER_REGEX = /^\d+$/;
|
1876 | 1873 | function updateIn(object, path, transform) {
|
|
1895 | 1892 | const key2 = path[0];
|
1896 | 1893 | if (!(key2 in object)) {
|
1897 | 1894 | return object;
|
1898 |
| - } else { |
1899 |
| - const updatedObject = shallowClone(object); |
1900 |
| - if (isJSONArray(updatedObject)) { |
1901 |
| - updatedObject.splice(parseInt(key2), 1); |
1902 |
| - } |
1903 |
| - if (isJSONObject(updatedObject)) { |
1904 |
| - delete updatedObject[key2]; |
1905 |
| - } |
1906 |
| - return updatedObject; |
1907 | 1895 | }
|
| 1896 | + const updatedObject = shallowClone(object); |
| 1897 | + if (isJSONArray(updatedObject)) { |
| 1898 | + updatedObject.splice(Number.parseInt(key2), 1); |
| 1899 | + } |
| 1900 | + if (isJSONObject(updatedObject)) { |
| 1901 | + delete updatedObject[key2]; |
| 1902 | + } |
| 1903 | + return updatedObject; |
1908 | 1904 | }
|
1909 | 1905 | const key = path[0];
|
1910 | 1906 | const updatedValue = deleteIn(object[key], path.slice(1));
|
|
1915 | 1911 | const index = path[path.length - 1];
|
1916 | 1912 | return updateIn(document2, parentPath, (items) => {
|
1917 | 1913 | if (!Array.isArray(items)) {
|
1918 |
| - throw new TypeError("Array expected at path " + JSON.stringify(parentPath)); |
| 1914 | + throw new TypeError(`Array expected at path ${JSON.stringify(parentPath)}`); |
1919 | 1915 | }
|
1920 | 1916 | const updatedItems = shallowClone(items);
|
1921 |
| - updatedItems.splice(parseInt(index), 0, value); |
| 1917 | + updatedItems.splice(Number.parseInt(index), 0, value); |
1922 | 1918 | return updatedItems;
|
1923 | 1919 | });
|
1924 | 1920 | }
|
|
1945 | 1941 | return path.map(compileJSONPointerProp).join("");
|
1946 | 1942 | }
|
1947 | 1943 | function compileJSONPointerProp(pathProp) {
|
1948 |
| - return "/" + String(pathProp).replace(/~/g, "~0").replace(/\//g, "~1"); |
| 1944 | + return `/${String(pathProp).replace(/~/g, "~0").replace(/\//g, "~1")}`; |
1949 | 1945 | }
|
1950 | 1946 |
|
1951 | 1947 | // ../node_modules/immutable-json-patch/lib/esm/immutableJSONPatch.js
|
|
1954 | 1950 | for (let i = 0; i < operations.length; i++) {
|
1955 | 1951 | validateJSONPatchOperation(operations[i]);
|
1956 | 1952 | let operation = operations[i];
|
1957 |
| - if (options && options.before) { |
| 1953 | + if (options?.before) { |
1958 | 1954 | const result = options.before(updatedDocument, operation);
|
1959 | 1955 | if (result !== void 0) {
|
1960 | 1956 | if (result.document !== void 0) {
|
|
1983 | 1979 | } else if (operation.op === "test") {
|
1984 | 1980 | test(updatedDocument, path, operation.value);
|
1985 | 1981 | } else {
|
1986 |
| - throw new Error("Unknown JSONPatch operation " + JSON.stringify(operation)); |
| 1982 | + throw new Error(`Unknown JSONPatch operation ${JSON.stringify(operation)}`); |
1987 | 1983 | }
|
1988 |
| - if (options && options.after) { |
| 1984 | + if (options?.after) { |
1989 | 1985 | const result = options.after(updatedDocument, operation, previousDocument);
|
1990 | 1986 | if (result !== void 0) {
|
1991 | 1987 | updatedDocument = result;
|
|
1995 | 1991 | return updatedDocument;
|
1996 | 1992 | }
|
1997 | 1993 | function replace(document2, path, value) {
|
1998 |
| - return setIn(document2, path, value); |
| 1994 | + return existsIn(document2, path) ? setIn(document2, path, value) : document2; |
1999 | 1995 | }
|
2000 | 1996 | function remove(document2, path) {
|
2001 | 1997 | return deleteIn(document2, path);
|
2002 | 1998 | }
|
2003 | 1999 | function add(document2, path, value) {
|
2004 | 2000 | if (isArrayItem(document2, path)) {
|
2005 | 2001 | return insertAt(document2, path, value);
|
2006 |
| - } else { |
2007 |
| - return setIn(document2, path, value); |
2008 | 2002 | }
|
| 2003 | + return setIn(document2, path, value); |
2009 | 2004 | }
|
2010 | 2005 | function copy(document2, path, from) {
|
2011 | 2006 | const value = getIn(document2, from);
|
2012 | 2007 | if (isArrayItem(document2, path)) {
|
2013 | 2008 | return insertAt(document2, path, value);
|
2014 |
| - } else { |
2015 |
| - const value2 = getIn(document2, from); |
2016 |
| - return setIn(document2, path, value2); |
2017 | 2009 | }
|
| 2010 | + return setIn(document2, path, value); |
2018 | 2011 | }
|
2019 | 2012 | function move(document2, path, from) {
|
2020 | 2013 | const value = getIn(document2, from);
|
|
2051 | 2044 | function validateJSONPatchOperation(operation) {
|
2052 | 2045 | const ops = ["add", "remove", "replace", "copy", "move", "test"];
|
2053 | 2046 | if (!ops.includes(operation.op)) {
|
2054 |
| - throw new Error("Unknown JSONPatch op " + JSON.stringify(operation.op)); |
| 2047 | + throw new Error(`Unknown JSONPatch op ${JSON.stringify(operation.op)}`); |
2055 | 2048 | }
|
2056 | 2049 | if (typeof operation.path !== "string") {
|
2057 |
| - throw new Error('Required property "path" missing or not a string in operation ' + JSON.stringify(operation)); |
| 2050 | + throw new Error(`Required property "path" missing or not a string in operation ${JSON.stringify(operation)}`); |
2058 | 2051 | }
|
2059 | 2052 | if (operation.op === "copy" || operation.op === "move") {
|
2060 | 2053 | if (typeof operation.from !== "string") {
|
2061 |
| - throw new Error('Required property "from" missing or not a string in operation ' + JSON.stringify(operation)); |
| 2054 | + throw new Error(`Required property "from" missing or not a string in operation ${JSON.stringify(operation)}`); |
2062 | 2055 | }
|
2063 | 2056 | }
|
2064 | 2057 | }
|
|
2887 | 2880 | get featureSettings() {
|
2888 | 2881 | return __privateGet(this, _args)?.featureSettings;
|
2889 | 2882 | }
|
| 2883 | + /** |
| 2884 | + * Getter for injectName, will be overridden by subclasses (namely ContentFeature) |
| 2885 | + * @returns {string | undefined} |
| 2886 | + */ |
| 2887 | + get injectName() { |
| 2888 | + return void 0; |
| 2889 | + } |
2890 | 2890 | /**
|
2891 | 2891 | * Given a config key, interpret the value as a list of conditionals objects, and return the elements that match the current page
|
2892 | 2892 | * Consider in your feature using patchSettings instead as per `getFeatureSetting`.
|
|
2925 | 2925 | * @property {object} [experiment]
|
2926 | 2926 | * @property {string} [experiment.experimentName]
|
2927 | 2927 | * @property {string} [experiment.cohort]
|
| 2928 | + * @property {object} [context] |
| 2929 | + * @property {boolean} [context.frame] - true if the condition applies to frames |
| 2930 | + * @property {boolean} [context.top] - true if the condition applies to the top frame |
| 2931 | + * @property {string} [injectName] - the inject name to match against (e.g., "apple-isolated") |
2928 | 2932 | */
|
2929 | 2933 | /**
|
2930 | 2934 | * Takes multiple conditional blocks and returns true if any apply.
|
|
2946 | 2950 | _matchConditionalBlock(conditionBlock) {
|
2947 | 2951 | const conditionChecks = {
|
2948 | 2952 | domain: this._matchDomainConditional,
|
| 2953 | + context: this._matchContextConditional, |
2949 | 2954 | urlPattern: this._matchUrlPatternConditional,
|
2950 | 2955 | experiment: this._matchExperimentConditional,
|
2951 |
| - minSupportedVersion: this._matchMinSupportedVersion |
| 2956 | + minSupportedVersion: this._matchMinSupportedVersion, |
| 2957 | + injectName: this._matchInjectNameConditional |
2952 | 2958 | };
|
2953 | 2959 | for (const key in conditionBlock) {
|
2954 | 2960 | if (!conditionChecks[key]) {
|
|
2984 | 2990 | return cohort.feature === "contentScopeExperiments" && cohort.subfeature === experiment.experimentName && cohort.cohort === experiment.cohort;
|
2985 | 2991 | });
|
2986 | 2992 | }
|
| 2993 | + /** |
| 2994 | + * Takes a condition block and returns true if the current context matches the context. |
| 2995 | + * @param {ConditionBlock} conditionBlock |
| 2996 | + * @returns {boolean} |
| 2997 | + */ |
| 2998 | + _matchContextConditional(conditionBlock) { |
| 2999 | + if (!conditionBlock.context) return false; |
| 3000 | + const isFrame = window.self !== window.top; |
| 3001 | + if (conditionBlock.context.frame && isFrame) { |
| 3002 | + return true; |
| 3003 | + } |
| 3004 | + if (conditionBlock.context.top && !isFrame) { |
| 3005 | + return true; |
| 3006 | + } |
| 3007 | + return false; |
| 3008 | + } |
2987 | 3009 | /**
|
2988 | 3010 | * Takes a condtion block and returns true if the current url matches the urlPattern.
|
2989 | 3011 | * @param {ConditionBlock} conditionBlock
|
|
3012 | 3034 | }
|
3013 | 3035 | return matchHostname(domain, conditionBlock.domain);
|
3014 | 3036 | }
|
| 3037 | + /** |
| 3038 | + * Takes a condition block and returns true if the current inject name matches the injectName. |
| 3039 | + * @param {ConditionBlock} conditionBlock |
| 3040 | + * @returns {boolean} |
| 3041 | + */ |
| 3042 | + _matchInjectNameConditional(conditionBlock) { |
| 3043 | + if (!conditionBlock.injectName) return false; |
| 3044 | + const currentInjectName = this.injectName; |
| 3045 | + if (!currentInjectName) return false; |
| 3046 | + return conditionBlock.injectName === currentInjectName; |
| 3047 | + } |
3015 | 3048 | /**
|
3016 | 3049 | * Takes a condition block and returns true if the platform version satisfies the `minSupportedFeature`
|
3017 | 3050 | * @param {ConditionBlock} conditionBlock
|
|
3889 | 3922 | const historyMethodProxy = new DDGProxy(urlChangedInstance, History.prototype, "pushState", {
|
3890 | 3923 | apply(target, thisArg, args) {
|
3891 | 3924 | const changeResult = DDGReflect.apply(target, thisArg, args);
|
3892 |
| - console.log("pushstate event"); |
3893 | 3925 | handleURLChange("push");
|
3894 | 3926 | return changeResult;
|
3895 | 3927 | }
|
|
0 commit comments