2
0

annotation_layer.js 23 KB

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