Selection.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. "use strict";
  2. const conversions = require("webidl-conversions");
  3. const utils = require("./utils.js");
  4. const Range = require("./Range.js");
  5. const Node = require("./Node.js");
  6. const ceReactionsPreSteps_jsdom_living_helpers_custom_elements =
  7. require("../../jsdom/living/helpers/custom-elements.js").ceReactionsPreSteps;
  8. const ceReactionsPostSteps_jsdom_living_helpers_custom_elements =
  9. require("../../jsdom/living/helpers/custom-elements.js").ceReactionsPostSteps;
  10. const implSymbol = utils.implSymbol;
  11. const ctorRegistrySymbol = utils.ctorRegistrySymbol;
  12. const interfaceName = "Selection";
  13. exports.is = value => {
  14. return utils.isObject(value) && Object.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation;
  15. };
  16. exports.isImpl = value => {
  17. return utils.isObject(value) && value instanceof Impl.implementation;
  18. };
  19. exports.convert = (globalObject, value, { context = "The provided value" } = {}) => {
  20. if (exports.is(value)) {
  21. return utils.implForWrapper(value);
  22. }
  23. throw new globalObject.TypeError(`${context} is not of type 'Selection'.`);
  24. };
  25. function makeWrapper(globalObject, newTarget) {
  26. let proto;
  27. if (newTarget !== undefined) {
  28. proto = newTarget.prototype;
  29. }
  30. if (!utils.isObject(proto)) {
  31. proto = globalObject[ctorRegistrySymbol]["Selection"].prototype;
  32. }
  33. return Object.create(proto);
  34. }
  35. exports.create = (globalObject, constructorArgs, privateData) => {
  36. const wrapper = makeWrapper(globalObject);
  37. return exports.setup(wrapper, globalObject, constructorArgs, privateData);
  38. };
  39. exports.createImpl = (globalObject, constructorArgs, privateData) => {
  40. const wrapper = exports.create(globalObject, constructorArgs, privateData);
  41. return utils.implForWrapper(wrapper);
  42. };
  43. exports._internalSetup = (wrapper, globalObject) => {};
  44. exports.setup = (wrapper, globalObject, constructorArgs = [], privateData = {}) => {
  45. privateData.wrapper = wrapper;
  46. exports._internalSetup(wrapper, globalObject);
  47. Object.defineProperty(wrapper, implSymbol, {
  48. value: new Impl.implementation(globalObject, constructorArgs, privateData),
  49. configurable: true
  50. });
  51. wrapper[implSymbol][utils.wrapperSymbol] = wrapper;
  52. if (Impl.init) {
  53. Impl.init(wrapper[implSymbol]);
  54. }
  55. return wrapper;
  56. };
  57. exports.new = (globalObject, newTarget) => {
  58. const wrapper = makeWrapper(globalObject, newTarget);
  59. exports._internalSetup(wrapper, globalObject);
  60. Object.defineProperty(wrapper, implSymbol, {
  61. value: Object.create(Impl.implementation.prototype),
  62. configurable: true
  63. });
  64. wrapper[implSymbol][utils.wrapperSymbol] = wrapper;
  65. if (Impl.init) {
  66. Impl.init(wrapper[implSymbol]);
  67. }
  68. return wrapper[implSymbol];
  69. };
  70. const exposed = new Set(["Window"]);
  71. exports.install = (globalObject, globalNames) => {
  72. if (!globalNames.some(globalName => exposed.has(globalName))) {
  73. return;
  74. }
  75. const ctorRegistry = utils.initCtorRegistry(globalObject);
  76. class Selection {
  77. constructor() {
  78. throw new globalObject.TypeError("Illegal constructor");
  79. }
  80. getRangeAt(index) {
  81. const esValue = this !== null && this !== undefined ? this : globalObject;
  82. if (!exports.is(esValue)) {
  83. throw new globalObject.TypeError("'getRangeAt' called on an object that is not a valid instance of Selection.");
  84. }
  85. if (arguments.length < 1) {
  86. throw new globalObject.TypeError(
  87. `Failed to execute 'getRangeAt' on 'Selection': 1 argument required, but only ${arguments.length} present.`
  88. );
  89. }
  90. const args = [];
  91. {
  92. let curArg = arguments[0];
  93. curArg = conversions["unsigned long"](curArg, {
  94. context: "Failed to execute 'getRangeAt' on 'Selection': parameter 1",
  95. globals: globalObject
  96. });
  97. args.push(curArg);
  98. }
  99. return utils.tryWrapperForImpl(esValue[implSymbol].getRangeAt(...args));
  100. }
  101. addRange(range) {
  102. const esValue = this !== null && this !== undefined ? this : globalObject;
  103. if (!exports.is(esValue)) {
  104. throw new globalObject.TypeError("'addRange' called on an object that is not a valid instance of Selection.");
  105. }
  106. if (arguments.length < 1) {
  107. throw new globalObject.TypeError(
  108. `Failed to execute 'addRange' on 'Selection': 1 argument required, but only ${arguments.length} present.`
  109. );
  110. }
  111. const args = [];
  112. {
  113. let curArg = arguments[0];
  114. curArg = Range.convert(globalObject, curArg, {
  115. context: "Failed to execute 'addRange' on 'Selection': parameter 1"
  116. });
  117. args.push(curArg);
  118. }
  119. return esValue[implSymbol].addRange(...args);
  120. }
  121. removeRange(range) {
  122. const esValue = this !== null && this !== undefined ? this : globalObject;
  123. if (!exports.is(esValue)) {
  124. throw new globalObject.TypeError(
  125. "'removeRange' called on an object that is not a valid instance of Selection."
  126. );
  127. }
  128. if (arguments.length < 1) {
  129. throw new globalObject.TypeError(
  130. `Failed to execute 'removeRange' on 'Selection': 1 argument required, but only ${arguments.length} present.`
  131. );
  132. }
  133. const args = [];
  134. {
  135. let curArg = arguments[0];
  136. curArg = Range.convert(globalObject, curArg, {
  137. context: "Failed to execute 'removeRange' on 'Selection': parameter 1"
  138. });
  139. args.push(curArg);
  140. }
  141. return esValue[implSymbol].removeRange(...args);
  142. }
  143. removeAllRanges() {
  144. const esValue = this !== null && this !== undefined ? this : globalObject;
  145. if (!exports.is(esValue)) {
  146. throw new globalObject.TypeError(
  147. "'removeAllRanges' called on an object that is not a valid instance of Selection."
  148. );
  149. }
  150. return esValue[implSymbol].removeAllRanges();
  151. }
  152. empty() {
  153. const esValue = this !== null && this !== undefined ? this : globalObject;
  154. if (!exports.is(esValue)) {
  155. throw new globalObject.TypeError("'empty' called on an object that is not a valid instance of Selection.");
  156. }
  157. return esValue[implSymbol].empty();
  158. }
  159. collapse(node) {
  160. const esValue = this !== null && this !== undefined ? this : globalObject;
  161. if (!exports.is(esValue)) {
  162. throw new globalObject.TypeError("'collapse' called on an object that is not a valid instance of Selection.");
  163. }
  164. if (arguments.length < 1) {
  165. throw new globalObject.TypeError(
  166. `Failed to execute 'collapse' on 'Selection': 1 argument required, but only ${arguments.length} present.`
  167. );
  168. }
  169. const args = [];
  170. {
  171. let curArg = arguments[0];
  172. if (curArg === null || curArg === undefined) {
  173. curArg = null;
  174. } else {
  175. curArg = Node.convert(globalObject, curArg, {
  176. context: "Failed to execute 'collapse' on 'Selection': parameter 1"
  177. });
  178. }
  179. args.push(curArg);
  180. }
  181. {
  182. let curArg = arguments[1];
  183. if (curArg !== undefined) {
  184. curArg = conversions["unsigned long"](curArg, {
  185. context: "Failed to execute 'collapse' on 'Selection': parameter 2",
  186. globals: globalObject
  187. });
  188. } else {
  189. curArg = 0;
  190. }
  191. args.push(curArg);
  192. }
  193. return esValue[implSymbol].collapse(...args);
  194. }
  195. setPosition(node) {
  196. const esValue = this !== null && this !== undefined ? this : globalObject;
  197. if (!exports.is(esValue)) {
  198. throw new globalObject.TypeError(
  199. "'setPosition' called on an object that is not a valid instance of Selection."
  200. );
  201. }
  202. if (arguments.length < 1) {
  203. throw new globalObject.TypeError(
  204. `Failed to execute 'setPosition' on 'Selection': 1 argument required, but only ${arguments.length} present.`
  205. );
  206. }
  207. const args = [];
  208. {
  209. let curArg = arguments[0];
  210. if (curArg === null || curArg === undefined) {
  211. curArg = null;
  212. } else {
  213. curArg = Node.convert(globalObject, curArg, {
  214. context: "Failed to execute 'setPosition' on 'Selection': parameter 1"
  215. });
  216. }
  217. args.push(curArg);
  218. }
  219. {
  220. let curArg = arguments[1];
  221. if (curArg !== undefined) {
  222. curArg = conversions["unsigned long"](curArg, {
  223. context: "Failed to execute 'setPosition' on 'Selection': parameter 2",
  224. globals: globalObject
  225. });
  226. } else {
  227. curArg = 0;
  228. }
  229. args.push(curArg);
  230. }
  231. return esValue[implSymbol].setPosition(...args);
  232. }
  233. collapseToStart() {
  234. const esValue = this !== null && this !== undefined ? this : globalObject;
  235. if (!exports.is(esValue)) {
  236. throw new globalObject.TypeError(
  237. "'collapseToStart' called on an object that is not a valid instance of Selection."
  238. );
  239. }
  240. return esValue[implSymbol].collapseToStart();
  241. }
  242. collapseToEnd() {
  243. const esValue = this !== null && this !== undefined ? this : globalObject;
  244. if (!exports.is(esValue)) {
  245. throw new globalObject.TypeError(
  246. "'collapseToEnd' called on an object that is not a valid instance of Selection."
  247. );
  248. }
  249. return esValue[implSymbol].collapseToEnd();
  250. }
  251. extend(node) {
  252. const esValue = this !== null && this !== undefined ? this : globalObject;
  253. if (!exports.is(esValue)) {
  254. throw new globalObject.TypeError("'extend' called on an object that is not a valid instance of Selection.");
  255. }
  256. if (arguments.length < 1) {
  257. throw new globalObject.TypeError(
  258. `Failed to execute 'extend' on 'Selection': 1 argument required, but only ${arguments.length} present.`
  259. );
  260. }
  261. const args = [];
  262. {
  263. let curArg = arguments[0];
  264. curArg = Node.convert(globalObject, curArg, {
  265. context: "Failed to execute 'extend' on 'Selection': parameter 1"
  266. });
  267. args.push(curArg);
  268. }
  269. {
  270. let curArg = arguments[1];
  271. if (curArg !== undefined) {
  272. curArg = conversions["unsigned long"](curArg, {
  273. context: "Failed to execute 'extend' on 'Selection': parameter 2",
  274. globals: globalObject
  275. });
  276. } else {
  277. curArg = 0;
  278. }
  279. args.push(curArg);
  280. }
  281. return esValue[implSymbol].extend(...args);
  282. }
  283. setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset) {
  284. const esValue = this !== null && this !== undefined ? this : globalObject;
  285. if (!exports.is(esValue)) {
  286. throw new globalObject.TypeError(
  287. "'setBaseAndExtent' called on an object that is not a valid instance of Selection."
  288. );
  289. }
  290. if (arguments.length < 4) {
  291. throw new globalObject.TypeError(
  292. `Failed to execute 'setBaseAndExtent' on 'Selection': 4 arguments required, but only ${arguments.length} present.`
  293. );
  294. }
  295. const args = [];
  296. {
  297. let curArg = arguments[0];
  298. curArg = Node.convert(globalObject, curArg, {
  299. context: "Failed to execute 'setBaseAndExtent' on 'Selection': parameter 1"
  300. });
  301. args.push(curArg);
  302. }
  303. {
  304. let curArg = arguments[1];
  305. curArg = conversions["unsigned long"](curArg, {
  306. context: "Failed to execute 'setBaseAndExtent' on 'Selection': parameter 2",
  307. globals: globalObject
  308. });
  309. args.push(curArg);
  310. }
  311. {
  312. let curArg = arguments[2];
  313. curArg = Node.convert(globalObject, curArg, {
  314. context: "Failed to execute 'setBaseAndExtent' on 'Selection': parameter 3"
  315. });
  316. args.push(curArg);
  317. }
  318. {
  319. let curArg = arguments[3];
  320. curArg = conversions["unsigned long"](curArg, {
  321. context: "Failed to execute 'setBaseAndExtent' on 'Selection': parameter 4",
  322. globals: globalObject
  323. });
  324. args.push(curArg);
  325. }
  326. return esValue[implSymbol].setBaseAndExtent(...args);
  327. }
  328. selectAllChildren(node) {
  329. const esValue = this !== null && this !== undefined ? this : globalObject;
  330. if (!exports.is(esValue)) {
  331. throw new globalObject.TypeError(
  332. "'selectAllChildren' called on an object that is not a valid instance of Selection."
  333. );
  334. }
  335. if (arguments.length < 1) {
  336. throw new globalObject.TypeError(
  337. `Failed to execute 'selectAllChildren' on 'Selection': 1 argument required, but only ${arguments.length} present.`
  338. );
  339. }
  340. const args = [];
  341. {
  342. let curArg = arguments[0];
  343. curArg = Node.convert(globalObject, curArg, {
  344. context: "Failed to execute 'selectAllChildren' on 'Selection': parameter 1"
  345. });
  346. args.push(curArg);
  347. }
  348. return esValue[implSymbol].selectAllChildren(...args);
  349. }
  350. deleteFromDocument() {
  351. const esValue = this !== null && this !== undefined ? this : globalObject;
  352. if (!exports.is(esValue)) {
  353. throw new globalObject.TypeError(
  354. "'deleteFromDocument' called on an object that is not a valid instance of Selection."
  355. );
  356. }
  357. ceReactionsPreSteps_jsdom_living_helpers_custom_elements(globalObject);
  358. try {
  359. return esValue[implSymbol].deleteFromDocument();
  360. } finally {
  361. ceReactionsPostSteps_jsdom_living_helpers_custom_elements(globalObject);
  362. }
  363. }
  364. containsNode(node) {
  365. const esValue = this !== null && this !== undefined ? this : globalObject;
  366. if (!exports.is(esValue)) {
  367. throw new globalObject.TypeError(
  368. "'containsNode' called on an object that is not a valid instance of Selection."
  369. );
  370. }
  371. if (arguments.length < 1) {
  372. throw new globalObject.TypeError(
  373. `Failed to execute 'containsNode' on 'Selection': 1 argument required, but only ${arguments.length} present.`
  374. );
  375. }
  376. const args = [];
  377. {
  378. let curArg = arguments[0];
  379. curArg = Node.convert(globalObject, curArg, {
  380. context: "Failed to execute 'containsNode' on 'Selection': parameter 1"
  381. });
  382. args.push(curArg);
  383. }
  384. {
  385. let curArg = arguments[1];
  386. if (curArg !== undefined) {
  387. curArg = conversions["boolean"](curArg, {
  388. context: "Failed to execute 'containsNode' on 'Selection': parameter 2",
  389. globals: globalObject
  390. });
  391. } else {
  392. curArg = false;
  393. }
  394. args.push(curArg);
  395. }
  396. return esValue[implSymbol].containsNode(...args);
  397. }
  398. toString() {
  399. const esValue = this !== null && this !== undefined ? this : globalObject;
  400. if (!exports.is(esValue)) {
  401. throw new globalObject.TypeError("'toString' called on an object that is not a valid instance of Selection.");
  402. }
  403. return esValue[implSymbol].toString();
  404. }
  405. get anchorNode() {
  406. const esValue = this !== null && this !== undefined ? this : globalObject;
  407. if (!exports.is(esValue)) {
  408. throw new globalObject.TypeError(
  409. "'get anchorNode' called on an object that is not a valid instance of Selection."
  410. );
  411. }
  412. return utils.tryWrapperForImpl(esValue[implSymbol]["anchorNode"]);
  413. }
  414. get anchorOffset() {
  415. const esValue = this !== null && this !== undefined ? this : globalObject;
  416. if (!exports.is(esValue)) {
  417. throw new globalObject.TypeError(
  418. "'get anchorOffset' called on an object that is not a valid instance of Selection."
  419. );
  420. }
  421. return esValue[implSymbol]["anchorOffset"];
  422. }
  423. get focusNode() {
  424. const esValue = this !== null && this !== undefined ? this : globalObject;
  425. if (!exports.is(esValue)) {
  426. throw new globalObject.TypeError(
  427. "'get focusNode' called on an object that is not a valid instance of Selection."
  428. );
  429. }
  430. return utils.tryWrapperForImpl(esValue[implSymbol]["focusNode"]);
  431. }
  432. get focusOffset() {
  433. const esValue = this !== null && this !== undefined ? this : globalObject;
  434. if (!exports.is(esValue)) {
  435. throw new globalObject.TypeError(
  436. "'get focusOffset' called on an object that is not a valid instance of Selection."
  437. );
  438. }
  439. return esValue[implSymbol]["focusOffset"];
  440. }
  441. get isCollapsed() {
  442. const esValue = this !== null && this !== undefined ? this : globalObject;
  443. if (!exports.is(esValue)) {
  444. throw new globalObject.TypeError(
  445. "'get isCollapsed' called on an object that is not a valid instance of Selection."
  446. );
  447. }
  448. return esValue[implSymbol]["isCollapsed"];
  449. }
  450. get rangeCount() {
  451. const esValue = this !== null && this !== undefined ? this : globalObject;
  452. if (!exports.is(esValue)) {
  453. throw new globalObject.TypeError(
  454. "'get rangeCount' called on an object that is not a valid instance of Selection."
  455. );
  456. }
  457. return esValue[implSymbol]["rangeCount"];
  458. }
  459. get type() {
  460. const esValue = this !== null && this !== undefined ? this : globalObject;
  461. if (!exports.is(esValue)) {
  462. throw new globalObject.TypeError("'get type' called on an object that is not a valid instance of Selection.");
  463. }
  464. return esValue[implSymbol]["type"];
  465. }
  466. }
  467. Object.defineProperties(Selection.prototype, {
  468. getRangeAt: { enumerable: true },
  469. addRange: { enumerable: true },
  470. removeRange: { enumerable: true },
  471. removeAllRanges: { enumerable: true },
  472. empty: { enumerable: true },
  473. collapse: { enumerable: true },
  474. setPosition: { enumerable: true },
  475. collapseToStart: { enumerable: true },
  476. collapseToEnd: { enumerable: true },
  477. extend: { enumerable: true },
  478. setBaseAndExtent: { enumerable: true },
  479. selectAllChildren: { enumerable: true },
  480. deleteFromDocument: { enumerable: true },
  481. containsNode: { enumerable: true },
  482. toString: { enumerable: true },
  483. anchorNode: { enumerable: true },
  484. anchorOffset: { enumerable: true },
  485. focusNode: { enumerable: true },
  486. focusOffset: { enumerable: true },
  487. isCollapsed: { enumerable: true },
  488. rangeCount: { enumerable: true },
  489. type: { enumerable: true },
  490. [Symbol.toStringTag]: { value: "Selection", configurable: true }
  491. });
  492. ctorRegistry[interfaceName] = Selection;
  493. Object.defineProperty(globalObject, interfaceName, {
  494. configurable: true,
  495. writable: true,
  496. value: Selection
  497. });
  498. };
  499. const Impl = require("../../jsdom/living/selection/Selection-impl.js");