diff --git a/src/core/core.js b/src/core/core.js index 13f64454c..ab17644c7 100644 --- a/src/core/core.js +++ b/src/core/core.js @@ -134,7 +134,7 @@ var Page = (function PageClosure() { }.bind(this)); return promise; }, - getOperatorList: function Page_getOperatorList(handler) { + getOperatorList: function Page_getOperatorList(handler, intent) { var self = this; var promise = new LegacyPromise(); @@ -169,11 +169,12 @@ var Page = (function PageClosure() { var contentStream = data[0]; - var opList = new OperatorList(handler, self.pageIndex); + var opList = new OperatorList(intent, handler, self.pageIndex); handler.send('StartRenderPage', { transparency: partialEvaluator.hasBlendModes(self.resources), - pageIndex: self.pageIndex + pageIndex: self.pageIndex, + intent: intent }); partialEvaluator.getOperatorList(contentStream, self.resources, opList); pageListPromise.resolve(opList); @@ -191,7 +192,7 @@ var Page = (function PageClosure() { } var annotationsReadyPromise = Annotation.appendToOperatorList( - annotations, pageOpList, pdfManager, partialEvaluator); + annotations, pageOpList, pdfManager, partialEvaluator, intent); annotationsReadyPromise.then(function () { pageOpList.flush(true); promise.resolve(pageOpList); diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 288a7299b..f1d835eda 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -1376,7 +1376,7 @@ var OperatorList = (function OperatorListClosure() { } - function OperatorList(messageHandler, pageIndex) { + function OperatorList(intent, messageHandler, pageIndex) { this.messageHandler = messageHandler; // When there isn't a message handler the fn array needs to be able to grow // since we can't flush the operators. @@ -1389,6 +1389,7 @@ var OperatorList = (function OperatorListClosure() { this.dependencies = {}; this.pageIndex = pageIndex; this.fnIndex = 0; + this.intent = intent; } OperatorList.prototype = { @@ -1449,7 +1450,8 @@ var OperatorList = (function OperatorListClosure() { lastChunk: lastChunk, length: this.length }, - pageIndex: this.pageIndex + pageIndex: this.pageIndex, + intent: this.intent }, null, transfers); this.dependencies = []; this.fnIndex = 0; diff --git a/src/core/worker.js b/src/core/worker.js index b1d86a116..c31bf8c6d 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -334,7 +334,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { var pageNum = data.pageIndex + 1; var start = Date.now(); // Pre compile the pdf page and fetch the fonts/images. - page.getOperatorList(handler).then(function(operatorList) { + page.getOperatorList(handler, data.intent).then(function(operatorList) { info('page=' + pageNum + ' - getOperatorList: time=' + (Date.now() - start) + 'ms, len=' + operatorList.fnArray.length); @@ -366,7 +366,8 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = { handler.send('PageError', { pageNum: pageNum, - error: wrappedException + error: wrappedException, + intent: data.intent }); }); }); diff --git a/src/display/api.js b/src/display/api.js index 63a312da7..d34d2426b 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -341,10 +341,9 @@ var PDFPageProxy = (function PDFPageProxyClosure() { this.stats.enabled = !!globalScope.PDFJS.enableStats; this.commonObjs = transport.commonObjs; this.objs = new PDFObjects(); - this.receivingOperatorList = false; this.cleanupAfterRender = false; this.pendingDestroy = false; - this.renderTasks = []; + this.intentStates = {}; } PDFPageProxy.prototype = /** @lends PDFPageProxy.prototype */ { /** @@ -423,12 +422,21 @@ var PDFPageProxy = (function PDFPageProxyClosure() { // this call to render. this.pendingDestroy = false; + var renderingIntent = 'intent' in params ? + (params.intent == 'print' ? 'print' : 'display') : + 'display'; + + if (!this.intentStates[renderingIntent]) { + this.intentStates[renderingIntent] = {}; + } + var intentState = this.intentStates[renderingIntent]; + // If there is no displayReadyPromise yet, then the operatorList was never // requested before. Make the request and create the promise. - if (!this.displayReadyPromise) { - this.receivingOperatorList = true; - this.displayReadyPromise = new LegacyPromise(); - this.operatorList = { + if (!intentState.displayReadyPromise) { + intentState.receivingOperatorList = true; + intentState.displayReadyPromise = new LegacyPromise(); + intentState.operatorList = { fnArray: [], argsArray: [], lastChunk: false @@ -436,18 +444,23 @@ var PDFPageProxy = (function PDFPageProxyClosure() { this.stats.time('Page Request'); this.transport.messageHandler.send('RenderPageRequest', { - pageIndex: this.pageNumber - 1 + pageIndex: this.pageNumber - 1, + intent: renderingIntent }); } var internalRenderTask = new InternalRenderTask(complete, params, this.objs, this.commonObjs, - this.operatorList, this.pageNumber); - this.renderTasks.push(internalRenderTask); + intentState.operatorList, + this.pageNumber); + if (!intentState.renderTasks) { + intentState.renderTasks = []; + } + intentState.renderTasks.push(internalRenderTask); var renderTask = new RenderTask(internalRenderTask); var self = this; - this.displayReadyPromise.then( + intentState.displayReadyPromise.then( function pageDisplayReadyPromise(transparency) { if (self.pendingDestroy) { complete(); @@ -463,9 +476,9 @@ var PDFPageProxy = (function PDFPageProxyClosure() { ); function complete(error) { - var i = self.renderTasks.indexOf(internalRenderTask); + var i = intentState.renderTasks.indexOf(internalRenderTask); if (i >= 0) { - self.renderTasks.splice(i, 1); + intentState.renderTasks.splice(i, 1); } if (self.cleanupAfterRender) { @@ -513,14 +526,17 @@ var PDFPageProxy = (function PDFPageProxyClosure() { */ _tryDestroy: function PDFPageProxy__destroy() { if (!this.pendingDestroy || - this.renderTasks.length !== 0 || - this.receivingOperatorList) { + Object.keys(this.intentStates).some(function(intent) { + var intentState = this.intentStates[intent]; + return intentState.renderTasks.length !== 0 || + intentState.receivingOperatorList; + }, this)) { return; } - delete this.operatorList; - delete this.displayReadyPromise; - delete this.annotationsPromise; + Object.keys(this.intentStates).forEach(function(intent) { + delete this.intentStates[intent]; + }, this); this.objs.clear(); this.pendingDestroy = false; }, @@ -528,28 +544,33 @@ var PDFPageProxy = (function PDFPageProxyClosure() { * For internal use only. * @ignore */ - _startRenderPage: function PDFPageProxy_startRenderPage(transparency) { - this.displayReadyPromise.resolve(transparency); + _startRenderPage: function PDFPageProxy_startRenderPage(transparency, + intent) { + var intentState = this.intentStates[intent]; + intentState.displayReadyPromise.resolve(transparency); }, /** * For internal use only. * @ignore */ - _renderPageChunk: function PDFPageProxy_renderPageChunk(operatorListChunk) { + _renderPageChunk: function PDFPageProxy_renderPageChunk(operatorListChunk, + intent) { + var intentState = this.intentStates[intent]; // Add the new chunk to the current operator list. for (var i = 0, ii = operatorListChunk.length; i < ii; i++) { - this.operatorList.fnArray.push(operatorListChunk.fnArray[i]); - this.operatorList.argsArray.push(operatorListChunk.argsArray[i]); + intentState.operatorList.fnArray.push(operatorListChunk.fnArray[i]); + intentState.operatorList.argsArray.push( + operatorListChunk.argsArray[i]); } - this.operatorList.lastChunk = operatorListChunk.lastChunk; + intentState.operatorList.lastChunk = operatorListChunk.lastChunk; // Notify all the rendering tasks there are more operators to be consumed. - for (var i = 0; i < this.renderTasks.length; i++) { - this.renderTasks[i].operatorListChanged(); + for (var i = 0; i < intentState.renderTasks.length; i++) { + intentState.renderTasks[i].operatorListChanged(); } if (operatorListChunk.lastChunk) { - this.receivingOperatorList = false; + intentState.receivingOperatorList = false; this._tryDestroy(); } } @@ -775,13 +796,13 @@ var WorkerTransport = (function WorkerTransportClosure() { var page = this.pageCache[data.pageIndex]; page.stats.timeEnd('Page Request'); - page._startRenderPage(data.transparency); + page._startRenderPage(data.transparency, data.intent); }, this); messageHandler.on('RenderPageChunk', function transportRender(data) { var page = this.pageCache[data.pageIndex]; - page._renderPageChunk(data.operatorList); + page._renderPageChunk(data.operatorList, data.intent); }, this); messageHandler.on('commonobj', function transportObj(data) { @@ -824,8 +845,9 @@ var WorkerTransport = (function WorkerTransportClosure() { var pageIndex = data[1]; var type = data[2]; var pageProxy = this.pageCache[pageIndex]; - if (pageProxy.objs.hasData(id)) + if (pageProxy.objs.hasData(id)) { return; + } switch (type) { case 'JpegStream': @@ -861,10 +883,11 @@ var WorkerTransport = (function WorkerTransportClosure() { this.workerReadyPromise.reject(data); }, this); - messageHandler.on('PageError', function transportError(data) { + messageHandler.on('PageError', function transportError(data, intent) { var page = this.pageCache[data.pageNum - 1]; - if (page.displayReadyPromise) - page.displayReadyPromise.reject(data.error); + var intentState = page.intentStates[intent]; + if (intentState.displayReadyPromise) + intentState.displayReadyPromise.reject(data.error); else error(data.error); }, this); diff --git a/src/shared/annotation.js b/src/shared/annotation.js index 631aaf865..67587b91c 100644 --- a/src/shared/annotation.js +++ b/src/shared/annotation.js @@ -21,6 +21,9 @@ 'use strict'; +var HIGHLIGHT_OFFSET = 4; // px +var SUPPORTED_TYPES = ['Link', 'Text', 'Widget']; + var Annotation = (function AnnotationClosure() { // 12.5.5: Algorithm: Appearance streams function getTransformMatrix(rect, bbox, matrix) { @@ -143,25 +146,50 @@ var Annotation = (function AnnotationClosure() { }, // TODO(mack): Remove this, it's not really that helpful. - getEmptyContainer: function Annotation_getEmptyContainer(tagName, rect) { + getEmptyContainer: function Annotation_getEmptyContainer(tagName, rect, + borderWidth) { assert(!isWorker, 'getEmptyContainer() should be called from main thread'); + var bWidth = borderWidth || 0; + rect = rect || this.data.rect; var element = document.createElement(tagName); - element.style.width = Math.ceil(rect[2] - rect[0]) + 'px'; - element.style.height = Math.ceil(rect[3] - rect[1]) + 'px'; + element.style.borderWidth = bWidth + 'px'; + var width = rect[2] - rect[0] - 2 * bWidth; + var height = rect[3] - rect[1] - 2 * bWidth; + element.style.width = width + 'px'; + element.style.height = height + 'px'; return element; }, + isInvisible: function Annotation_isInvisible() { + var data = this.data; + if (data && SUPPORTED_TYPES.indexOf(data.subtype) !== -1) { + return false; + } else { + return !!(data && + data.annotationFlags && // Default: not invisible + data.annotationFlags & 0x1); // Invisible + } + }, + isViewable: function Annotation_isViewable() { var data = this.data; - return !!( - data && - (!data.annotationFlags || - !(data.annotationFlags & 0x22)) && // Hidden or NoView - data.rect // rectangle is nessessary - ); + return !!(!this.isInvisible() && + data && + (!data.annotationFlags || + !(data.annotationFlags & 0x22)) && // Hidden or NoView + data.rect); // rectangle is nessessary + }, + + isPrintable: function Annotation_isPrintable() { + var data = this.data; + return !!(!this.isInvisible() && + data && + data.annotationFlags && // Default: not printable + data.annotationFlags & 0x4 && // Print + data.rect); // rectangle is nessessary }, loadResources: function(keys) { @@ -182,7 +210,7 @@ var Annotation = (function AnnotationClosure() { return promise; }, - getOperatorList: function Annotation_getToOperatorList(evaluator) { + getOperatorList: function Annotation_getOperatorList(evaluator) { var promise = new LegacyPromise(); @@ -289,7 +317,7 @@ var Annotation = (function AnnotationClosure() { var annotation = new Constructor(params); - if (annotation.isViewable()) { + if (annotation.isViewable() || annotation.isPrintable()) { return annotation; } else { warn('unimplemented annotation type: ' + subtype); @@ -297,7 +325,7 @@ var Annotation = (function AnnotationClosure() { }; Annotation.appendToOperatorList = function Annotation_appendToOperatorList( - annotations, opList, pdfManager, partialEvaluator) { + annotations, opList, pdfManager, partialEvaluator, intent) { function reject(e) { annotationsReadyPromise.reject(e); @@ -307,7 +335,11 @@ var Annotation = (function AnnotationClosure() { var annotationPromises = []; for (var i = 0, n = annotations.length; i < n; ++i) { - annotationPromises.push(annotations[i].getOperatorList(partialEvaluator)); + if (intent === 'display' && annotations[i].isViewable() || + intent === 'print' && annotations[i].isPrintable()) { + annotationPromises.push( + annotations[i].getOperatorList(partialEvaluator)); + } } Promise.all(annotationPromises).then(function(datas) { opList.addOp(OPS.beginAnnotations, []); @@ -519,9 +551,64 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() { return TextWidgetAnnotation; })(); +var InteractiveAnnotation = (function InteractiveAnnotationClosure() { + function InteractiveAnnotation(params) { + Annotation.call(this, params); + } + + Util.inherit(InteractiveAnnotation, Annotation, { + hasHtml: function InteractiveAnnotation_hasHtml() { + return true; + }, + + highlight: function InteractiveAnnotation_highlight() { + if (this.highlightElement && + this.highlightElement.hasAttribute('hidden')) { + this.highlightElement.removeAttribute('hidden'); + } + }, + + unhighlight: function InteractiveAnnotation_unhighlight() { + if (this.highlightElement && + !this.highlightElement.hasAttribute('hidden')) { + this.highlightElement.setAttribute('hidden', true); + } + }, + + initContainer: function InteractiveAnnotation_initContainer() { + + var item = this.data; + var rect = item.rect; + + var container = this.getEmptyContainer('section', rect, item.borderWidth); + container.style.backgroundColor = item.color; + + var color = item.color; + var rgb = []; + for (var i = 0; i < 3; ++i) { + rgb[i] = Math.round(color[i] * 255); + } + item.colorCssRgb = Util.makeCssRgb(rgb); + + var highlight = document.createElement('div'); + highlight.className = 'annotationHighlight'; + highlight.style.left = highlight.style.top = -HIGHLIGHT_OFFSET + 'px'; + highlight.style.right = highlight.style.bottom = -HIGHLIGHT_OFFSET + 'px'; + highlight.setAttribute('hidden', true); + + this.highlightElement = highlight; + container.appendChild(this.highlightElement); + + return container; + } + }); + + return InteractiveAnnotation; +})(); + var TextAnnotation = (function TextAnnotationClosure() { function TextAnnotation(params) { - Annotation.call(this, params); + InteractiveAnnotation.call(this, params); if (params.data) { return; @@ -534,22 +621,21 @@ var TextAnnotation = (function TextAnnotationClosure() { var title = dict.get('T'); data.content = stringToPDFString(content || ''); data.title = stringToPDFString(title || ''); - data.name = !dict.has('Name') ? 'Note' : dict.get('Name').name; + + if (data.hasAppearance) { + data.name = 'NoIcon'; + } else { + data.name = dict.has('Name') ? dict.get('Name').name : 'Note'; + } + + if (dict.has('C')) { + data.hasBgColor = true; + } } var ANNOT_MIN_SIZE = 10; - Util.inherit(TextAnnotation, Annotation, { - - getOperatorList: function TextAnnotation_getOperatorList(evaluator) { - var promise = new LegacyPromise(); - promise.resolve(new OperatorList()); - return promise; - }, - - hasHtml: function TextAnnotation_hasHtml() { - return true; - }, + Util.inherit(TextAnnotation, InteractiveAnnotation, { getHtmlElement: function TextAnnotation_getHtmlElement(commonObjs) { assert(!isWorker, 'getHtmlElement() shall be called from main thread'); @@ -565,23 +651,40 @@ var TextAnnotation = (function TextAnnotationClosure() { rect[2] = rect[0] + (rect[3] - rect[1]); // make it square } - var container = this.getEmptyContainer('section', rect); + var container = this.initContainer(); container.className = 'annotText'; - var image = document.createElement('img'); + var image = document.createElement('img'); image.style.height = container.style.height; + image.style.width = container.style.width; var iconName = item.name; image.src = PDFJS.imageResourcesPath + 'annotation-' + iconName.toLowerCase() + '.svg'; image.alt = '[{{type}} Annotation]'; image.dataset.l10nId = 'text_annotation_type'; image.dataset.l10nArgs = JSON.stringify({type: iconName}); + + var contentWrapper = document.createElement('div'); + contentWrapper.className = 'annotTextContentWrapper'; + contentWrapper.style.left = Math.floor(rect[2] - rect[0] + 5) + 'px'; + contentWrapper.style.top = '-10px'; + var content = document.createElement('div'); + content.className = 'annotTextContent'; content.setAttribute('hidden', true); + if (item.hasBgColor) { + var color = item.color; + var rgb = []; + for (var i = 0; i < 3; ++i) { + // Enlighten the color (70%) + var c = Math.round(color[i] * 255); + rgb[i] = Math.round((255 - c) * 0.7) + c; + } + content.style.backgroundColor = Util.makeCssRgb(rgb); + } + var title = document.createElement('h1'); var text = document.createElement('p'); - content.style.left = Math.floor(rect[2] - rect[0]) + 'px'; - content.style.top = '0px'; title.textContent = item.title; if (!item.content && !item.title) { @@ -597,28 +700,57 @@ var TextAnnotation = (function TextAnnotationClosure() { } text.appendChild(e); - var showAnnotation = function showAnnotation() { - container.style.zIndex += 1; - content.removeAttribute('hidden'); + var pinned = false; + + var showAnnotation = function showAnnotation(pin) { + if (pin) { + pinned = true; + } + if (content.hasAttribute('hidden')) { + container.style.zIndex += 1; + content.removeAttribute('hidden'); + } }; - var hideAnnotation = function hideAnnotation(e) { - if (e.toElement || e.relatedTarget) { // No context menu is used + var hideAnnotation = function hideAnnotation(unpin) { + if (unpin) { + pinned = false; + } + if (!content.hasAttribute('hidden') && !pinned) { container.style.zIndex -= 1; content.setAttribute('hidden', true); } }; - content.addEventListener('mouseover', showAnnotation, false); - content.addEventListener('mouseout', hideAnnotation, false); - image.addEventListener('mouseover', showAnnotation, false); - image.addEventListener('mouseout', hideAnnotation, false); + var toggleAnnotation = function toggleAnnotation() { + if (pinned) { + hideAnnotation(true); + } else { + showAnnotation(true); + } + }; + + var self = this; + image.addEventListener('click', function image_clickHandler() { + toggleAnnotation(); + }, false); + image.addEventListener('mouseover', function image_mouseOverHandler() { + showAnnotation(); + }, false); + image.addEventListener('mouseout', function image_mouseOutHandler() { + hideAnnotation(); + }, false); + + content.addEventListener('click', function content_clickHandler() { + hideAnnotation(true); + }, false); } content.appendChild(title); content.appendChild(text); + contentWrapper.appendChild(content); container.appendChild(image); - container.appendChild(content); + container.appendChild(contentWrapper); return container; } @@ -629,7 +761,7 @@ var TextAnnotation = (function TextAnnotationClosure() { var LinkAnnotation = (function LinkAnnotationClosure() { function LinkAnnotation(params) { - Annotation.call(this, params); + InteractiveAnnotation.call(this, params); if (params.data) { return; @@ -692,36 +824,28 @@ var LinkAnnotation = (function LinkAnnotationClosure() { return url; } - Util.inherit(LinkAnnotation, Annotation, { + Util.inherit(LinkAnnotation, InteractiveAnnotation, { hasOperatorList: function LinkAnnotation_hasOperatorList() { return false; }, - hasHtml: function LinkAnnotation_hasHtml() { - return true; - }, - getHtmlElement: function LinkAnnotation_getHtmlElement(commonObjs) { - var rect = this.data.rect; - var element = document.createElement('a'); - var borderWidth = this.data.borderWidth; - element.style.borderWidth = borderWidth + 'px'; - var color = this.data.color; - var rgb = []; - for (var i = 0; i < 3; ++i) { - rgb[i] = Math.round(color[i] * 255); - } - element.style.borderColor = Util.makeCssRgb(rgb); - element.style.borderStyle = 'solid'; + var container = this.initContainer(); + container.className = 'annotLink'; - var width = rect[2] - rect[0] - 2 * borderWidth; - var height = rect[3] - rect[1] - 2 * borderWidth; - element.style.width = width + 'px'; - element.style.height = height + 'px'; + var item = this.data; + var rect = item.rect; - element.href = this.data.url || ''; - return element; + container.style.borderColor = item.colorCssRgb; + container.style.borderStyle = 'solid'; + + var link = document.createElement('a'); + link.href = link.title = this.data.url || ''; + + container.appendChild(link); + + return container; } }); diff --git a/web/images/annotation-noicon.svg b/web/images/annotation-noicon.svg new file mode 100644 index 000000000..c07d10808 --- /dev/null +++ b/web/images/annotation-noicon.svg @@ -0,0 +1,7 @@ + + + diff --git a/web/page_view.js b/web/page_view.js index 1e4efbad4..ac693078a 100644 --- a/web/page_view.js +++ b/web/page_view.js @@ -306,10 +306,13 @@ var PageView = function pageView(container, id, scale, CustomStyle.setProp('transformOrigin', element, transformOriginStr); if (data.subtype === 'Link' && !data.url) { - if (data.action) { - bindNamedAction(element, data.action); - } else { - bindLink(element, ('dest' in data) ? data.dest : null); + var link = element.getElementsByTagName('a')[0]; + if (link) { + if (data.action) { + bindNamedAction(link, data.action); + } else { + bindLink(link, ('dest' in data) ? data.dest : null); + } } } @@ -579,6 +582,7 @@ var PageView = function pageView(container, id, scale, canvasContext: ctx, viewport: this.viewport, textLayer: textLayer, + // intent: 'default', // === 'display' continueCallback: function pdfViewcContinueCallback(cont) { if (PDFView.highestPriorityPage !== 'page' + self.id) { self.renderingState = RenderingStates.PAUSED; @@ -650,13 +654,13 @@ var PageView = function pageView(container, id, scale, var renderContext = { canvasContext: ctx, - viewport: viewport + viewport: viewport, + intent: 'print' }; pdfPage.render(renderContext).promise.then(function() { // Tell the printEngine that rendering this canvas/page has finished. obj.done(); - self.pdfPage.destroy(); }, function(error) { console.error(error); // Tell the printEngine that rendering this canvas/page has failed. @@ -666,7 +670,6 @@ var PageView = function pageView(container, id, scale, } else { obj.done(); } - self.pdfPage.destroy(); }); }; }; diff --git a/web/viewer.css b/web/viewer.css index d07521705..a7008d84d 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -1247,14 +1247,7 @@ canvas { background-color: white; } -.page > a, -.annotationLayer > a { - display: block; - position: absolute; -} - -.page > a:hover, -.annotationLayer > a:hover { +.annotLink > a:hover { opacity: 0.2; background: #ff0; box-shadow: 0px 2px 10px #ff0; @@ -1319,29 +1312,49 @@ canvas { ::selection { background:rgba(0,0,255,0.3); } ::-moz-selection { background:rgba(0,0,255,0.3); } -.annotText > div { - z-index: 200; +.annotationHighlight { position: absolute; - padding: 0.6em; - max-width: 20em; - background-color: #FFFF99; - box-shadow: 0px 2px 10px #333; - border-radius: 7px; + border: 2px #FFFF99 solid; } .annotText > img { position: absolute; - opacity: 0.6; + cursor: pointer; } -.annotText > img:hover { - opacity: 1; +.annotTextContentWrapper { + position: absolute; + width: 20em; } -.annotText > div > h1 { - font-size: 1.2em; +.annotTextContent { + z-index: 200; + float: left; + max-width: 20em; + background-color: #FFFF99; + box-shadow: 0px 2px 5px #333; + border-radius: 2px; + padding: 0.6em; + cursor: pointer; +} + +.annotTextContent > h1 { + font-size: 1em; border-bottom: 1px solid #000000; - margin: 0px; + padding-bottom: 0.2em; +} + +.annotTextContent > p { + padding-top: 0.2em; +} + +.annotLink > a { + position: absolute; + font-size: 1em; + top: 0; + left: 0; + width: 100%; + height: 100%; } #errorWrapper {