Skip to content

Commit

Permalink
Improve extension to search MediaExcerpts for current page and annota…
Browse files Browse the repository at this point in the history
…te UrlLocators (#541)

Signed-off-by: Carl Gieringer <[email protected]>
  • Loading branch information
carlgieringer committed Aug 29, 2023
1 parent 85964ba commit fea5714
Show file tree
Hide file tree
Showing 20 changed files with 389 additions and 52 deletions.
8 changes: 8 additions & 0 deletions howdju-client-common/lib/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
PersistedJustificationWithRootRef,
UrlOut,
JustificationView,
UrlLocator,
MediaExcerptView,
} from "howdju-common";

/**
Expand Down Expand Up @@ -35,6 +37,12 @@ export const extension = {
},
})
),
highlightUrlLocator: createAction(
"EXTENSION/HIGHLIGHT_URL_LOCATOR",
(mediaExcerpt: MediaExcerptView, urlLocator: UrlLocator) => ({
payload: { mediaExcerpt, urlLocator },
})
),
messageHandlerReady: createAction("EXTENSION/MESSAGE_HANDLER_READY"),
} as const;

Expand Down
5 changes: 4 additions & 1 deletion howdju-client-common/lib/extensionMessages.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { UrlTarget } from "howdju-common";
import { DomAnchor, UrlTarget } from "howdju-common";
import { RequireExactlyOne } from "type-fest";
import { actions } from ".";
import { ExtensionFrameActionName } from "./actions";
Expand Down Expand Up @@ -30,6 +30,9 @@ export type ContentScriptCommand =
}
| {
annotateTarget: [UrlTarget];
}
| {
annotateUrlLocatorAnchors: DomAnchor[];
};

export const toggleSidebar = () => ({ type: "TOGGLE_SIDEBAR" } as const);
Expand Down
7 changes: 6 additions & 1 deletion howdju-client-common/lib/target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
UrlTarget,
makeDomAnchor,
nodeIsBefore,
DomAnchor,
} from "howdju-common";

import { getPreviousLeafNode } from "./dom";
Expand Down Expand Up @@ -48,8 +49,12 @@ function rangeToAnchor(range: Range): CreateDomAnchor {
}

export function targetToRanges(target: UrlTarget) {
return anchorsToRanges(target.anchors as [DomAnchor]);
}

export function anchorsToRanges(anchors: DomAnchor[]) {
const ranges = [];
for (const anchor of target.anchors) {
for (const anchor of anchors) {
let options = {};
if (anchor.startOffset) {
// The average of the start and end seems like a good idea
Expand Down
6 changes: 5 additions & 1 deletion howdju-common/lib/commonPaths.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// TODO(196): ensure that these paths follow a pattern compatible with the web app paths.
// TODO(#196): ensure that these paths follow a pattern compatible with the web app paths. Maybe
// move all paths here so that the extension and mobile app can access them.
module.exports.CommonPaths = class CommonPaths {
confirmRegistration() {
return "/complete-registration";
Expand All @@ -12,6 +13,9 @@ module.exports.CommonPaths = class CommonPaths {
requestPasswordReset() {
return "/request-password-reset";
}
searchMediaExcerpts() {
return "/search-media-excerpts";
}
};

module.exports.commonPaths = new module.exports.CommonPaths();
15 changes: 13 additions & 2 deletions howdju-common/lib/serialization.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import cloneDeep from "lodash/cloneDeep";
import { cloneDeep } from "lodash";
import { isMoment } from "moment";

import { JustificationOut, JustificationWithRootOut } from "./apiModels";
import { mapValuesDeep } from "./general";
import { JustificationView } from "./viewModels";

import { Entity, Proposition, SourceExcerpt } from "./zodSchemas";

// Recursively replace all Entity subtypes with Entity so that they can be
Expand All @@ -12,6 +14,15 @@ export type Decircularized<T> = {
: Decircularized<T[key]>;
};

export function domSerializationSafe(obj: any) {
return mapValuesDeep(obj, (value) => {
if (isMoment(value)) {
return value.toISOString();
}
return value;
});
}

export function decircularizeJustification(
justification: JustificationOut | JustificationWithRootOut | JustificationView
): Decircularized<JustificationOut> {
Expand Down
69 changes: 38 additions & 31 deletions howdju-text-fragments/dist/rangeToFragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -8906,7 +8906,7 @@
updateInProgress = false;
}
}
function isMoment(obj) {
function isMoment2(obj) {
return obj instanceof Moment3 || obj != null && obj._isAMomentObject != null;
}
function warn(msg) {
Expand Down Expand Up @@ -10747,7 +10747,7 @@
if (typeof input === "string") {
config._i = input = config._locale.preparse(input);
}
if (isMoment(input)) {
if (isMoment2(input)) {
return new Moment3(checkOverflow(input));
} else if (isDate(input)) {
config._d = input;
Expand Down Expand Up @@ -10956,7 +10956,7 @@
var res, diff2;
if (model._isUTC) {
res = model.clone();
diff2 = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
diff2 = (isMoment2(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
res._d.setTime(res._d.valueOf() + diff2);
hooks.updateOffset(res, false);
return res;
Expand Down Expand Up @@ -11210,7 +11210,7 @@
return typeof input === "string" || input instanceof String;
}
function isMomentInput(input) {
return isMoment(input) || isDate(input) || isString3(input) || isNumber2(input) || isNumberOrStringArray(input) || isMomentInputObject(input) || input === null || input === void 0;
return isMoment2(input) || isDate(input) || isString3(input) || isNumber2(input) || isNumberOrStringArray(input) || isMomentInputObject(input) || input === null || input === void 0;
}
function isMomentInputObject(input) {
var objectTest = isObject3(input) && !isObjectEmpty(input), propertyTest = false, properties = [
Expand Down Expand Up @@ -11295,7 +11295,7 @@
return new Moment3(this);
}
function isAfter(input, units) {
var localInput = isMoment(input) ? input : createLocal(input);
var localInput = isMoment2(input) ? input : createLocal(input);
if (!(this.isValid() && localInput.isValid())) {
return false;
}
Expand All @@ -11307,7 +11307,7 @@
}
}
function isBefore(input, units) {
var localInput = isMoment(input) ? input : createLocal(input);
var localInput = isMoment2(input) ? input : createLocal(input);
if (!(this.isValid() && localInput.isValid())) {
return false;
}
Expand All @@ -11319,15 +11319,15 @@
}
}
function isBetween(from2, to2, units, inclusivity) {
var localFrom = isMoment(from2) ? from2 : createLocal(from2), localTo = isMoment(to2) ? to2 : createLocal(to2);
var localFrom = isMoment2(from2) ? from2 : createLocal(from2), localTo = isMoment2(to2) ? to2 : createLocal(to2);
if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
return false;
}
inclusivity = inclusivity || "()";
return (inclusivity[0] === "(" ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && (inclusivity[1] === ")" ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
}
function isSame(input, units) {
var localInput = isMoment(input) ? input : createLocal(input), inputMs;
var localInput = isMoment2(input) ? input : createLocal(input), inputMs;
if (!(this.isValid() && localInput.isValid())) {
return false;
}
Expand Down Expand Up @@ -11451,7 +11451,7 @@
return this.localeData().postformat(output);
}
function from(time, withoutSuffix) {
if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
if (this.isValid() && (isMoment2(time) && time.isValid() || createLocal(time).isValid())) {
return createDuration({ to: this, from: time }).locale(this.locale()).humanize(!withoutSuffix);
} else {
return this.localeData().invalidDate();
Expand All @@ -11461,7 +11461,7 @@
return this.from(createLocal(), withoutSuffix);
}
function to(time, withoutSuffix) {
if (this.isValid() && (isMoment(time) && time.isValid() || createLocal(time).isValid())) {
if (this.isValid() && (isMoment2(time) && time.isValid() || createLocal(time).isValid())) {
return createDuration({ from: this, to: time }).locale(this.locale()).humanize(!withoutSuffix);
} else {
return this.localeData().invalidDate();
Expand Down Expand Up @@ -12604,7 +12604,7 @@
hooks.locale = getSetGlobalLocale;
hooks.invalid = createInvalid;
hooks.duration = createDuration;
hooks.isMoment = isMoment;
hooks.isMoment = isMoment2;
hooks.weekdays = listWeekdays;
hooks.parseZone = createInZone;
hooks.localeData = getLocale;
Expand Down Expand Up @@ -12980,6 +12980,9 @@
requestPasswordReset() {
return "/request-password-reset";
}
searchMediaExcerpts() {
return "/search-media-excerpts";
}
};
module.exports.commonPaths = new module.exports.CommonPaths();
}
Expand Down Expand Up @@ -30882,19 +30885,6 @@
}
});

// ../node_modules/lodash/cloneDeep.js
var require_cloneDeep = __commonJS({
"../node_modules/lodash/cloneDeep.js"(exports, module) {
var baseClone = require_baseClone();
var CLONE_DEEP_FLAG = 1;
var CLONE_SYMBOLS_FLAG = 4;
function cloneDeep5(value) {
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
}
module.exports = cloneDeep5;
}
});

// ../node_modules/lodash/_assignMergeValue.js
var require_assignMergeValue = __commonJS({
"../node_modules/lodash/_assignMergeValue.js"(exports, module) {
Expand Down Expand Up @@ -33044,6 +33034,7 @@
demuxJustificationBasisSourceExcerptInput: () => demuxJustificationBasisSourceExcerptInput,
differenceDuration: () => differenceDuration,
doTargetSameRoot: () => doTargetSameRoot,
domSerializationSafe: () => domSerializationSafe,
emptyValidationResult: () => emptyValidationResult,
encodeQueryStringObject: () => encodeQueryStringObject,
encodeSorts: () => encodeSorts,
Expand Down Expand Up @@ -34928,9 +34919,19 @@
__reExport(lib_exports, __toESM(require_standaloneValidation()));

// ../howdju-common/lib/serialization.ts
var import_cloneDeep = __toESM(require_cloneDeep());
var import_lodash11 = __toESM(require_lodash());
var import_moment5 = __toESM(require_moment());
init_general();
function domSerializationSafe(obj) {
return mapValuesDeep(obj, (value) => {
if ((0, import_moment5.isMoment)(value)) {
return value.toISOString();
}
return value;
});
}
function decircularizeJustification(justification) {
const decircularized = (0, import_cloneDeep.default)(justification);
const decircularized = (0, import_lodash11.cloneDeep)(justification);
if (decircularized.rootTarget.id) {
decircularized.rootTarget = { id: decircularized.rootTarget.id };
}
Expand Down Expand Up @@ -35113,24 +35114,24 @@
}

// ../howdju-common/lib/validation.ts
var import_lodash11 = __toESM(require_lodash());
var import_lodash12 = __toESM(require_lodash());
init_logger();
var EmptyBespokeValidationErrors = {
hasErrors: false,
modelErrors: [],
fieldErrors: {}
};
function newBespokeValidationErrors() {
return (0, import_lodash11.cloneDeep)(
return (0, import_lodash12.cloneDeep)(
EmptyBespokeValidationErrors
);
}
var onlyFieldError = (fieldError, code) => {
const errors = (0, import_lodash11.filter)(fieldError, (fe) => (0, import_lodash11.isObject)(fe) && fe.code === code);
const errors = (0, import_lodash12.filter)(fieldError, (fe) => (0, import_lodash12.isObject)(fe) && fe.code === code);
if (errors.length > 1) {
logger.error(`Multiple field errors have the code ${code}.`);
}
return (0, import_lodash11.head)(errors);
return (0, import_lodash12.head)(errors);
};

// ../howdju-common/lib/index.ts
Expand All @@ -35152,6 +35153,12 @@
}
})
),
highlightUrlLocator: createAction(
"EXTENSION/HIGHLIGHT_URL_LOCATOR",
(mediaExcerpt, urlLocator) => ({
payload: { mediaExcerpt, urlLocator }
})
),
messageHandlerReady: createAction("EXTENSION/MESSAGE_HANDLER_READY")
};
var extensionFrame = {
Expand Down Expand Up @@ -35361,7 +35368,7 @@

// ../howdju-client-common/lib/models.ts
var import_merge = __toESM(require_merge2());
var import_lodash12 = __toESM(require_lodash());
var import_lodash13 = __toESM(require_lodash());

// ../howdju-client-common/lib/target.ts
var textPosition2 = __toESM(require_dom_anchor_text_position2());
Expand Down
9 changes: 8 additions & 1 deletion premiser-ext/src/annotate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import concat from "lodash/concat";
import { isUndefined } from "lodash";

import { logger, UrlTarget, nodeIsBefore } from "howdju-common";
import { logger, UrlTarget, nodeIsBefore, DomAnchor } from "howdju-common";
import {
getSelection,
clearSelection,
Expand All @@ -13,6 +13,7 @@ import {
isCoextensive,
insertNodeAfter,
insertNodeBefore,
anchorsToRanges,
} from "howdju-client-common";

import { getNodeData } from "./node-data";
Expand Down Expand Up @@ -58,6 +59,12 @@ export function annotateTarget(target: UrlTarget) {
return getOrCreateAnnotation(nodes);
}

export function annotateAnchors(anchors: DomAnchor[]) {
const ranges = anchorsToRanges(anchors);
const nodes = rangesToNodes(ranges);
return getOrCreateAnnotation(nodes);
}

/** Returns an existing annotation if it's equivalent; only uses target if it returns a new annotation. */
function getOrCreateAnnotation(nodes: Node[]) {
const equivalentAnnotation = getEquivalentAnnotation(nodes);
Expand Down
Loading

0 comments on commit fea5714

Please sign in to comment.