annotation_layer.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. /* Copyright 2017 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. 'use strict';
  16. var sharedUtil = require('../shared/util.js');
  17. var displayDOMUtils = require('./dom_utils.js');
  18. var AnnotationBorderStyleType = sharedUtil.AnnotationBorderStyleType;
  19. var AnnotationType = sharedUtil.AnnotationType;
  20. var stringToPDFString = sharedUtil.stringToPDFString;
  21. var Util = sharedUtil.Util;
  22. var addLinkAttributes = displayDOMUtils.addLinkAttributes;
  23. var LinkTarget = displayDOMUtils.LinkTarget;
  24. var getFilenameFromUrl = displayDOMUtils.getFilenameFromUrl;
  25. var warn = sharedUtil.warn;
  26. var CustomStyle = displayDOMUtils.CustomStyle;
  27. var getDefaultSetting = displayDOMUtils.getDefaultSetting;
  28. function AnnotationElementFactory() {}
  29. AnnotationElementFactory.prototype = {
  30. create: function AnnotationElementFactory_create(parameters) {
  31. var subtype = parameters.data.annotationType;
  32. switch (subtype) {
  33. case AnnotationType.LINK:
  34. return new LinkAnnotationElement(parameters);
  35. case AnnotationType.TEXT:
  36. return new TextAnnotationElement(parameters);
  37. case AnnotationType.WIDGET:
  38. var fieldType = parameters.data.fieldType;
  39. switch (fieldType) {
  40. case 'Tx':
  41. return new TextWidgetAnnotationElement(parameters);
  42. case 'Btn':
  43. if (parameters.data.radioButton) {
  44. return new RadioButtonWidgetAnnotationElement(parameters);
  45. } else if (parameters.data.checkBox) {
  46. return new CheckboxWidgetAnnotationElement(parameters);
  47. }
  48. warn('Unimplemented button widget annotation: pushbutton');
  49. break;
  50. case 'Ch':
  51. return new ChoiceWidgetAnnotationElement(parameters);
  52. }
  53. return new WidgetAnnotationElement(parameters);
  54. case AnnotationType.POPUP:
  55. return new PopupAnnotationElement(parameters);
  56. case AnnotationType.LINE:
  57. return new LineAnnotationElement(parameters);
  58. case AnnotationType.HIGHLIGHT:
  59. return new HighlightAnnotationElement(parameters);
  60. case AnnotationType.UNDERLINE:
  61. return new UnderlineAnnotationElement(parameters);
  62. case AnnotationType.SQUIGGLY:
  63. return new SquigglyAnnotationElement(parameters);
  64. case AnnotationType.STRIKEOUT:
  65. return new StrikeOutAnnotationElement(parameters);
  66. case AnnotationType.FILEATTACHMENT:
  67. return new FileAttachmentAnnotationElement(parameters);
  68. default:
  69. return new AnnotationElement(parameters);
  70. }
  71. }
  72. };
  73. var AnnotationElement = function AnnotationElementClosure() {
  74. function AnnotationElement(parameters, isRenderable, ignoreBorder) {
  75. this.isRenderable = isRenderable || false;
  76. this.data = parameters.data;
  77. this.layer = parameters.layer;
  78. this.page = parameters.page;
  79. this.viewport = parameters.viewport;
  80. this.linkService = parameters.linkService;
  81. this.downloadManager = parameters.downloadManager;
  82. this.imageResourcesPath = parameters.imageResourcesPath;
  83. this.renderInteractiveForms = parameters.renderInteractiveForms;
  84. if (isRenderable) {
  85. this.container = this._createContainer(ignoreBorder);
  86. }
  87. }
  88. AnnotationElement.prototype = {
  89. _createContainer: function AnnotationElement_createContainer(ignoreBorder) {
  90. var data = this.data,
  91. page = this.page,
  92. viewport = this.viewport;
  93. var container = document.createElement('section');
  94. var width = data.rect[2] - data.rect[0];
  95. var height = data.rect[3] - data.rect[1];
  96. container.setAttribute('data-annotation-id', data.id);
  97. var rect = Util.normalizeRect([data.rect[0], page.view[3] - data.rect[1] + page.view[1], data.rect[2], page.view[3] - data.rect[3] + page.view[1]]);
  98. CustomStyle.setProp('transform', container, 'matrix(' + viewport.transform.join(',') + ')');
  99. CustomStyle.setProp('transformOrigin', container, -rect[0] + 'px ' + -rect[1] + 'px');
  100. if (!ignoreBorder && data.borderStyle.width > 0) {
  101. container.style.borderWidth = data.borderStyle.width + 'px';
  102. if (data.borderStyle.style !== AnnotationBorderStyleType.UNDERLINE) {
  103. width = width - 2 * data.borderStyle.width;
  104. height = height - 2 * data.borderStyle.width;
  105. }
  106. var horizontalRadius = data.borderStyle.horizontalCornerRadius;
  107. var verticalRadius = data.borderStyle.verticalCornerRadius;
  108. if (horizontalRadius > 0 || verticalRadius > 0) {
  109. var radius = horizontalRadius + 'px / ' + verticalRadius + 'px';
  110. CustomStyle.setProp('borderRadius', container, radius);
  111. }
  112. switch (data.borderStyle.style) {
  113. case AnnotationBorderStyleType.SOLID:
  114. container.style.borderStyle = 'solid';
  115. break;
  116. case AnnotationBorderStyleType.DASHED:
  117. container.style.borderStyle = 'dashed';
  118. break;
  119. case AnnotationBorderStyleType.BEVELED:
  120. warn('Unimplemented border style: beveled');
  121. break;
  122. case AnnotationBorderStyleType.INSET:
  123. warn('Unimplemented border style: inset');
  124. break;
  125. case AnnotationBorderStyleType.UNDERLINE:
  126. container.style.borderBottomStyle = 'solid';
  127. break;
  128. default:
  129. break;
  130. }
  131. if (data.color) {
  132. container.style.borderColor = Util.makeCssRgb(data.color[0] | 0, data.color[1] | 0, data.color[2] | 0);
  133. } else {
  134. container.style.borderWidth = 0;
  135. }
  136. }
  137. container.style.left = rect[0] + 'px';
  138. container.style.top = rect[1] + 'px';
  139. container.style.width = width + 'px';
  140. container.style.height = height + 'px';
  141. return container;
  142. },
  143. _createPopup: function AnnotationElement_createPopup(container, trigger, data) {
  144. if (!trigger) {
  145. trigger = document.createElement('div');
  146. trigger.style.height = container.style.height;
  147. trigger.style.width = container.style.width;
  148. container.appendChild(trigger);
  149. }
  150. var popupElement = new PopupElement({
  151. container: container,
  152. trigger: trigger,
  153. color: data.color,
  154. title: data.title,
  155. contents: data.contents,
  156. hideWrapper: true
  157. });
  158. var popup = popupElement.render();
  159. popup.style.left = container.style.width;
  160. container.appendChild(popup);
  161. },
  162. render: function AnnotationElement_render() {
  163. throw new Error('Abstract method AnnotationElement.render called');
  164. }
  165. };
  166. return AnnotationElement;
  167. }();
  168. var LinkAnnotationElement = function LinkAnnotationElementClosure() {
  169. function LinkAnnotationElement(parameters) {
  170. AnnotationElement.call(this, parameters, true);
  171. }
  172. Util.inherit(LinkAnnotationElement, AnnotationElement, {
  173. render: function LinkAnnotationElement_render() {
  174. this.container.className = 'linkAnnotation';
  175. var link = document.createElement('a');
  176. addLinkAttributes(link, {
  177. url: this.data.url,
  178. target: this.data.newWindow ? LinkTarget.BLANK : undefined
  179. });
  180. if (!this.data.url) {
  181. if (this.data.action) {
  182. this._bindNamedAction(link, this.data.action);
  183. } else {
  184. this._bindLink(link, this.data.dest);
  185. }
  186. }
  187. this.container.appendChild(link);
  188. return this.container;
  189. },
  190. _bindLink: function LinkAnnotationElement_bindLink(link, destination) {
  191. var self = this;
  192. link.href = this.linkService.getDestinationHash(destination);
  193. link.onclick = function () {
  194. if (destination) {
  195. self.linkService.navigateTo(destination);
  196. }
  197. return false;
  198. };
  199. if (destination) {
  200. link.className = 'internalLink';
  201. }
  202. },
  203. _bindNamedAction: function LinkAnnotationElement_bindNamedAction(link, action) {
  204. var self = this;
  205. link.href = this.linkService.getAnchorUrl('');
  206. link.onclick = function () {
  207. self.linkService.executeNamedAction(action);
  208. return false;
  209. };
  210. link.className = 'internalLink';
  211. }
  212. });
  213. return LinkAnnotationElement;
  214. }();
  215. var TextAnnotationElement = function TextAnnotationElementClosure() {
  216. function TextAnnotationElement(parameters) {
  217. var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
  218. AnnotationElement.call(this, parameters, isRenderable);
  219. }
  220. Util.inherit(TextAnnotationElement, AnnotationElement, {
  221. render: function TextAnnotationElement_render() {
  222. this.container.className = 'textAnnotation';
  223. var image = document.createElement('img');
  224. image.style.height = this.container.style.height;
  225. image.style.width = this.container.style.width;
  226. image.src = this.imageResourcesPath + 'annotation-' + this.data.name.toLowerCase() + '.svg';
  227. image.alt = '[{{type}} Annotation]';
  228. image.dataset.l10nId = 'text_annotation_type';
  229. image.dataset.l10nArgs = JSON.stringify({ type: this.data.name });
  230. if (!this.data.hasPopup) {
  231. this._createPopup(this.container, image, this.data);
  232. }
  233. this.container.appendChild(image);
  234. return this.container;
  235. }
  236. });
  237. return TextAnnotationElement;
  238. }();
  239. var WidgetAnnotationElement = function WidgetAnnotationElementClosure() {
  240. function WidgetAnnotationElement(parameters, isRenderable) {
  241. AnnotationElement.call(this, parameters, isRenderable);
  242. }
  243. Util.inherit(WidgetAnnotationElement, AnnotationElement, {
  244. render: function WidgetAnnotationElement_render() {
  245. return this.container;
  246. }
  247. });
  248. return WidgetAnnotationElement;
  249. }();
  250. var TextWidgetAnnotationElement = function TextWidgetAnnotationElementClosure() {
  251. var TEXT_ALIGNMENT = ['left', 'center', 'right'];
  252. function TextWidgetAnnotationElement(parameters) {
  253. var isRenderable = parameters.renderInteractiveForms || !parameters.data.hasAppearance && !!parameters.data.fieldValue;
  254. WidgetAnnotationElement.call(this, parameters, isRenderable);
  255. }
  256. Util.inherit(TextWidgetAnnotationElement, WidgetAnnotationElement, {
  257. render: function TextWidgetAnnotationElement_render() {
  258. this.container.className = 'textWidgetAnnotation';
  259. var element = null;
  260. if (this.renderInteractiveForms) {
  261. if (this.data.multiLine) {
  262. element = document.createElement('textarea');
  263. element.textContent = this.data.fieldValue;
  264. } else {
  265. element = document.createElement('input');
  266. element.type = 'text';
  267. element.setAttribute('value', this.data.fieldValue);
  268. }
  269. element.disabled = this.data.readOnly;
  270. if (this.data.maxLen !== null) {
  271. element.maxLength = this.data.maxLen;
  272. }
  273. if (this.data.comb) {
  274. var fieldWidth = this.data.rect[2] - this.data.rect[0];
  275. var combWidth = fieldWidth / this.data.maxLen;
  276. element.classList.add('comb');
  277. element.style.letterSpacing = 'calc(' + combWidth + 'px - 1ch)';
  278. }
  279. } else {
  280. element = document.createElement('div');
  281. element.textContent = this.data.fieldValue;
  282. element.style.verticalAlign = 'middle';
  283. element.style.display = 'table-cell';
  284. var font = null;
  285. if (this.data.fontRefName) {
  286. font = this.page.commonObjs.getData(this.data.fontRefName);
  287. }
  288. this._setTextStyle(element, font);
  289. }
  290. if (this.data.textAlignment !== null) {
  291. element.style.textAlign = TEXT_ALIGNMENT[this.data.textAlignment];
  292. }
  293. this.container.appendChild(element);
  294. return this.container;
  295. },
  296. _setTextStyle: function TextWidgetAnnotationElement_setTextStyle(element, font) {
  297. var style = element.style;
  298. style.fontSize = this.data.fontSize + 'px';
  299. style.direction = this.data.fontDirection < 0 ? 'rtl' : 'ltr';
  300. if (!font) {
  301. return;
  302. }
  303. style.fontWeight = font.black ? font.bold ? '900' : 'bold' : font.bold ? 'bold' : 'normal';
  304. style.fontStyle = font.italic ? 'italic' : 'normal';
  305. var fontFamily = font.loadedName ? '"' + font.loadedName + '", ' : '';
  306. var fallbackName = font.fallbackName || 'Helvetica, sans-serif';
  307. style.fontFamily = fontFamily + fallbackName;
  308. }
  309. });
  310. return TextWidgetAnnotationElement;
  311. }();
  312. var CheckboxWidgetAnnotationElement = function CheckboxWidgetAnnotationElementClosure() {
  313. function CheckboxWidgetAnnotationElement(parameters) {
  314. WidgetAnnotationElement.call(this, parameters, parameters.renderInteractiveForms);
  315. }
  316. Util.inherit(CheckboxWidgetAnnotationElement, WidgetAnnotationElement, {
  317. render: function CheckboxWidgetAnnotationElement_render() {
  318. this.container.className = 'buttonWidgetAnnotation checkBox';
  319. var element = document.createElement('input');
  320. element.disabled = this.data.readOnly;
  321. element.type = 'checkbox';
  322. if (this.data.fieldValue && this.data.fieldValue !== 'Off') {
  323. element.setAttribute('checked', true);
  324. }
  325. this.container.appendChild(element);
  326. return this.container;
  327. }
  328. });
  329. return CheckboxWidgetAnnotationElement;
  330. }();
  331. var RadioButtonWidgetAnnotationElement = function RadioButtonWidgetAnnotationElementClosure() {
  332. function RadioButtonWidgetAnnotationElement(parameters) {
  333. WidgetAnnotationElement.call(this, parameters, parameters.renderInteractiveForms);
  334. }
  335. Util.inherit(RadioButtonWidgetAnnotationElement, WidgetAnnotationElement, {
  336. render: function RadioButtonWidgetAnnotationElement_render() {
  337. this.container.className = 'buttonWidgetAnnotation radioButton';
  338. var element = document.createElement('input');
  339. element.disabled = this.data.readOnly;
  340. element.type = 'radio';
  341. element.name = this.data.fieldName;
  342. if (this.data.fieldValue === this.data.buttonValue) {
  343. element.setAttribute('checked', true);
  344. }
  345. this.container.appendChild(element);
  346. return this.container;
  347. }
  348. });
  349. return RadioButtonWidgetAnnotationElement;
  350. }();
  351. var ChoiceWidgetAnnotationElement = function ChoiceWidgetAnnotationElementClosure() {
  352. function ChoiceWidgetAnnotationElement(parameters) {
  353. WidgetAnnotationElement.call(this, parameters, parameters.renderInteractiveForms);
  354. }
  355. Util.inherit(ChoiceWidgetAnnotationElement, WidgetAnnotationElement, {
  356. render: function ChoiceWidgetAnnotationElement_render() {
  357. this.container.className = 'choiceWidgetAnnotation';
  358. var selectElement = document.createElement('select');
  359. selectElement.disabled = this.data.readOnly;
  360. if (!this.data.combo) {
  361. selectElement.size = this.data.options.length;
  362. if (this.data.multiSelect) {
  363. selectElement.multiple = true;
  364. }
  365. }
  366. for (var i = 0, ii = this.data.options.length; i < ii; i++) {
  367. var option = this.data.options[i];
  368. var optionElement = document.createElement('option');
  369. optionElement.textContent = option.displayValue;
  370. optionElement.value = option.exportValue;
  371. if (this.data.fieldValue.indexOf(option.displayValue) >= 0) {
  372. optionElement.setAttribute('selected', true);
  373. }
  374. selectElement.appendChild(optionElement);
  375. }
  376. this.container.appendChild(selectElement);
  377. return this.container;
  378. }
  379. });
  380. return ChoiceWidgetAnnotationElement;
  381. }();
  382. var PopupAnnotationElement = function PopupAnnotationElementClosure() {
  383. var IGNORE_TYPES = ['Line'];
  384. function PopupAnnotationElement(parameters) {
  385. var isRenderable = !!(parameters.data.title || parameters.data.contents);
  386. AnnotationElement.call(this, parameters, isRenderable);
  387. }
  388. Util.inherit(PopupAnnotationElement, AnnotationElement, {
  389. render: function PopupAnnotationElement_render() {
  390. this.container.className = 'popupAnnotation';
  391. if (IGNORE_TYPES.indexOf(this.data.parentType) >= 0) {
  392. return this.container;
  393. }
  394. var selector = '[data-annotation-id="' + this.data.parentId + '"]';
  395. var parentElement = this.layer.querySelector(selector);
  396. if (!parentElement) {
  397. return this.container;
  398. }
  399. var popup = new PopupElement({
  400. container: this.container,
  401. trigger: parentElement,
  402. color: this.data.color,
  403. title: this.data.title,
  404. contents: this.data.contents
  405. });
  406. var parentLeft = parseFloat(parentElement.style.left);
  407. var parentWidth = parseFloat(parentElement.style.width);
  408. CustomStyle.setProp('transformOrigin', this.container, -(parentLeft + parentWidth) + 'px -' + parentElement.style.top);
  409. this.container.style.left = parentLeft + parentWidth + 'px';
  410. this.container.appendChild(popup.render());
  411. return this.container;
  412. }
  413. });
  414. return PopupAnnotationElement;
  415. }();
  416. var PopupElement = function PopupElementClosure() {
  417. var BACKGROUND_ENLIGHT = 0.7;
  418. function PopupElement(parameters) {
  419. this.container = parameters.container;
  420. this.trigger = parameters.trigger;
  421. this.color = parameters.color;
  422. this.title = parameters.title;
  423. this.contents = parameters.contents;
  424. this.hideWrapper = parameters.hideWrapper || false;
  425. this.pinned = false;
  426. }
  427. PopupElement.prototype = {
  428. render: function PopupElement_render() {
  429. var wrapper = document.createElement('div');
  430. wrapper.className = 'popupWrapper';
  431. this.hideElement = this.hideWrapper ? wrapper : this.container;
  432. this.hideElement.setAttribute('hidden', true);
  433. var popup = document.createElement('div');
  434. popup.className = 'popup';
  435. var color = this.color;
  436. if (color) {
  437. var r = BACKGROUND_ENLIGHT * (255 - color[0]) + color[0];
  438. var g = BACKGROUND_ENLIGHT * (255 - color[1]) + color[1];
  439. var b = BACKGROUND_ENLIGHT * (255 - color[2]) + color[2];
  440. popup.style.backgroundColor = Util.makeCssRgb(r | 0, g | 0, b | 0);
  441. }
  442. var contents = this._formatContents(this.contents);
  443. var title = document.createElement('h1');
  444. title.textContent = this.title;
  445. this.trigger.addEventListener('click', this._toggle.bind(this));
  446. this.trigger.addEventListener('mouseover', this._show.bind(this, false));
  447. this.trigger.addEventListener('mouseout', this._hide.bind(this, false));
  448. popup.addEventListener('click', this._hide.bind(this, true));
  449. popup.appendChild(title);
  450. popup.appendChild(contents);
  451. wrapper.appendChild(popup);
  452. return wrapper;
  453. },
  454. _formatContents: function PopupElement_formatContents(contents) {
  455. var p = document.createElement('p');
  456. var lines = contents.split(/(?:\r\n?|\n)/);
  457. for (var i = 0, ii = lines.length; i < ii; ++i) {
  458. var line = lines[i];
  459. p.appendChild(document.createTextNode(line));
  460. if (i < ii - 1) {
  461. p.appendChild(document.createElement('br'));
  462. }
  463. }
  464. return p;
  465. },
  466. _toggle: function PopupElement_toggle() {
  467. if (this.pinned) {
  468. this._hide(true);
  469. } else {
  470. this._show(true);
  471. }
  472. },
  473. _show: function PopupElement_show(pin) {
  474. if (pin) {
  475. this.pinned = true;
  476. }
  477. if (this.hideElement.hasAttribute('hidden')) {
  478. this.hideElement.removeAttribute('hidden');
  479. this.container.style.zIndex += 1;
  480. }
  481. },
  482. _hide: function PopupElement_hide(unpin) {
  483. if (unpin) {
  484. this.pinned = false;
  485. }
  486. if (!this.hideElement.hasAttribute('hidden') && !this.pinned) {
  487. this.hideElement.setAttribute('hidden', true);
  488. this.container.style.zIndex -= 1;
  489. }
  490. }
  491. };
  492. return PopupElement;
  493. }();
  494. var LineAnnotationElement = function LineAnnotationElementClosure() {
  495. var SVG_NS = 'http://www.w3.org/2000/svg';
  496. function LineAnnotationElement(parameters) {
  497. var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
  498. AnnotationElement.call(this, parameters, isRenderable, true);
  499. }
  500. Util.inherit(LineAnnotationElement, AnnotationElement, {
  501. render: function LineAnnotationElement_render() {
  502. this.container.className = 'lineAnnotation';
  503. var data = this.data;
  504. var width = data.rect[2] - data.rect[0];
  505. var height = data.rect[3] - data.rect[1];
  506. var svg = document.createElementNS(SVG_NS, 'svg:svg');
  507. svg.setAttributeNS(null, 'version', '1.1');
  508. svg.setAttributeNS(null, 'width', width + 'px');
  509. svg.setAttributeNS(null, 'height', height + 'px');
  510. svg.setAttributeNS(null, 'preserveAspectRatio', 'none');
  511. svg.setAttributeNS(null, 'viewBox', '0 0 ' + width + ' ' + height);
  512. var line = document.createElementNS(SVG_NS, 'svg:line');
  513. line.setAttributeNS(null, 'x1', data.rect[2] - data.lineCoordinates[0]);
  514. line.setAttributeNS(null, 'y1', data.rect[3] - data.lineCoordinates[1]);
  515. line.setAttributeNS(null, 'x2', data.rect[2] - data.lineCoordinates[2]);
  516. line.setAttributeNS(null, 'y2', data.rect[3] - data.lineCoordinates[3]);
  517. line.setAttributeNS(null, 'stroke-width', data.borderStyle.width);
  518. line.setAttributeNS(null, 'stroke', 'transparent');
  519. svg.appendChild(line);
  520. this.container.append(svg);
  521. this._createPopup(this.container, line, this.data);
  522. return this.container;
  523. }
  524. });
  525. return LineAnnotationElement;
  526. }();
  527. var HighlightAnnotationElement = function HighlightAnnotationElementClosure() {
  528. function HighlightAnnotationElement(parameters) {
  529. var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
  530. AnnotationElement.call(this, parameters, isRenderable, true);
  531. }
  532. Util.inherit(HighlightAnnotationElement, AnnotationElement, {
  533. render: function HighlightAnnotationElement_render() {
  534. this.container.className = 'highlightAnnotation';
  535. if (!this.data.hasPopup) {
  536. this._createPopup(this.container, null, this.data);
  537. }
  538. return this.container;
  539. }
  540. });
  541. return HighlightAnnotationElement;
  542. }();
  543. var UnderlineAnnotationElement = function UnderlineAnnotationElementClosure() {
  544. function UnderlineAnnotationElement(parameters) {
  545. var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
  546. AnnotationElement.call(this, parameters, isRenderable, true);
  547. }
  548. Util.inherit(UnderlineAnnotationElement, AnnotationElement, {
  549. render: function UnderlineAnnotationElement_render() {
  550. this.container.className = 'underlineAnnotation';
  551. if (!this.data.hasPopup) {
  552. this._createPopup(this.container, null, this.data);
  553. }
  554. return this.container;
  555. }
  556. });
  557. return UnderlineAnnotationElement;
  558. }();
  559. var SquigglyAnnotationElement = function SquigglyAnnotationElementClosure() {
  560. function SquigglyAnnotationElement(parameters) {
  561. var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
  562. AnnotationElement.call(this, parameters, isRenderable, true);
  563. }
  564. Util.inherit(SquigglyAnnotationElement, AnnotationElement, {
  565. render: function SquigglyAnnotationElement_render() {
  566. this.container.className = 'squigglyAnnotation';
  567. if (!this.data.hasPopup) {
  568. this._createPopup(this.container, null, this.data);
  569. }
  570. return this.container;
  571. }
  572. });
  573. return SquigglyAnnotationElement;
  574. }();
  575. var StrikeOutAnnotationElement = function StrikeOutAnnotationElementClosure() {
  576. function StrikeOutAnnotationElement(parameters) {
  577. var isRenderable = !!(parameters.data.hasPopup || parameters.data.title || parameters.data.contents);
  578. AnnotationElement.call(this, parameters, isRenderable, true);
  579. }
  580. Util.inherit(StrikeOutAnnotationElement, AnnotationElement, {
  581. render: function StrikeOutAnnotationElement_render() {
  582. this.container.className = 'strikeoutAnnotation';
  583. if (!this.data.hasPopup) {
  584. this._createPopup(this.container, null, this.data);
  585. }
  586. return this.container;
  587. }
  588. });
  589. return StrikeOutAnnotationElement;
  590. }();
  591. var FileAttachmentAnnotationElement = function FileAttachmentAnnotationElementClosure() {
  592. function FileAttachmentAnnotationElement(parameters) {
  593. AnnotationElement.call(this, parameters, true);
  594. var file = this.data.file;
  595. this.filename = getFilenameFromUrl(file.filename);
  596. this.content = file.content;
  597. this.linkService.onFileAttachmentAnnotation({
  598. id: stringToPDFString(file.filename),
  599. filename: file.filename,
  600. content: file.content
  601. });
  602. }
  603. Util.inherit(FileAttachmentAnnotationElement, AnnotationElement, {
  604. render: function FileAttachmentAnnotationElement_render() {
  605. this.container.className = 'fileAttachmentAnnotation';
  606. var trigger = document.createElement('div');
  607. trigger.style.height = this.container.style.height;
  608. trigger.style.width = this.container.style.width;
  609. trigger.addEventListener('dblclick', this._download.bind(this));
  610. if (!this.data.hasPopup && (this.data.title || this.data.contents)) {
  611. this._createPopup(this.container, trigger, this.data);
  612. }
  613. this.container.appendChild(trigger);
  614. return this.container;
  615. },
  616. _download: function FileAttachmentAnnotationElement_download() {
  617. if (!this.downloadManager) {
  618. warn('Download cannot be started due to unavailable download manager');
  619. return;
  620. }
  621. this.downloadManager.downloadData(this.content, this.filename, '');
  622. }
  623. });
  624. return FileAttachmentAnnotationElement;
  625. }();
  626. var AnnotationLayer = function AnnotationLayerClosure() {
  627. return {
  628. render: function AnnotationLayer_render(parameters) {
  629. var annotationElementFactory = new AnnotationElementFactory();
  630. for (var i = 0, ii = parameters.annotations.length; i < ii; i++) {
  631. var data = parameters.annotations[i];
  632. if (!data) {
  633. continue;
  634. }
  635. var element = annotationElementFactory.create({
  636. data: data,
  637. layer: parameters.div,
  638. page: parameters.page,
  639. viewport: parameters.viewport,
  640. linkService: parameters.linkService,
  641. downloadManager: parameters.downloadManager,
  642. imageResourcesPath: parameters.imageResourcesPath || getDefaultSetting('imageResourcesPath'),
  643. renderInteractiveForms: parameters.renderInteractiveForms || false
  644. });
  645. if (element.isRenderable) {
  646. parameters.div.appendChild(element.render());
  647. }
  648. }
  649. },
  650. update: function AnnotationLayer_update(parameters) {
  651. for (var i = 0, ii = parameters.annotations.length; i < ii; i++) {
  652. var data = parameters.annotations[i];
  653. var element = parameters.div.querySelector('[data-annotation-id="' + data.id + '"]');
  654. if (element) {
  655. CustomStyle.setProp('transform', element, 'matrix(' + parameters.viewport.transform.join(',') + ')');
  656. }
  657. }
  658. parameters.div.removeAttribute('hidden');
  659. }
  660. };
  661. }();
  662. exports.AnnotationLayer = AnnotationLayer;