mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge branch 'master' into ja-review-panel
This commit is contained in:
commit
e717caab7f
20 changed files with 44479 additions and 82967 deletions
|
@ -160,10 +160,10 @@ module.exports = (grunt) ->
|
|||
paths:
|
||||
"moment": "libs/#{PackageVersions.lib('moment')}"
|
||||
"mathjax": "/js/libs/mathjax/MathJax.js?config=TeX-AMS_HTML"
|
||||
"libs/pdf": "libs/#{PackageVersions.lib('pdfjs')}/pdf"
|
||||
"pdfjs-dist/build/pdf": "libs/#{PackageVersions.lib('pdfjs')}/pdf"
|
||||
"ace": "#{PackageVersions.lib('ace')}"
|
||||
shim:
|
||||
"libs/pdf":
|
||||
"pdfjs-dist/build/pdf":
|
||||
deps: ["libs/#{PackageVersions.lib('pdfjs')}/compatibility"]
|
||||
|
||||
skipDirOptimize: true
|
||||
|
@ -173,7 +173,7 @@ module.exports = (grunt) ->
|
|||
exclude: ["libs"]
|
||||
}, {
|
||||
name: "ide",
|
||||
exclude: ["libs", "libs/pdf"]
|
||||
exclude: ["libs", "pdfjs-dist/build/pdf"]
|
||||
}, {
|
||||
name: "libs"
|
||||
},{
|
||||
|
|
|
@ -101,7 +101,7 @@ Thank you
|
|||
#{settings.appName} - <%= siteUrl %>
|
||||
"""
|
||||
compiledTemplate: _.template """
|
||||
<p>Hi, <%= owner.email %> wants to share <a href="<%= project.url %>">'<%= project.name %>'</a> with you</p>
|
||||
<p>Hi, <%= owner.email %> wants to share <a href="<%= inviteUrl %>">'<%= project.name %>'</a> with you</p>
|
||||
<center>
|
||||
<a style="text-decoration: none; width: 200px; background-color: #a93629; border: 1px solid #e24b3b; border-radius: 3px; padding: 15px; margin: 24px; display: block;" href="<%= inviteUrl %>" style="text-decoration:none" target="_blank">
|
||||
<span style= "font-size:16px;font-family:Helvetica,Arial;font-weight:400;color:#fff;white-space:nowrap;display:block; text-align:center">
|
||||
|
|
|
@ -52,6 +52,8 @@ module.exports =
|
|||
text: options.text
|
||||
replyTo: options.replyTo || Settings.email.replyToAddress
|
||||
socketTimeout: 30 * 1000
|
||||
if Settings.email.textEncoding?
|
||||
opts.textEncoding = textEncoding
|
||||
client.sendMail options, (err, res)->
|
||||
if err?
|
||||
logger.err err:err, "error sending message"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
version = {
|
||||
"pdfjs": "1.3.91p1"
|
||||
"pdfjs": "1.6.210p1"
|
||||
"moment": "2.9.0"
|
||||
"ace": "1.2.5"
|
||||
}
|
||||
|
|
|
@ -87,6 +87,10 @@ block content
|
|||
|
||||
block requirejs
|
||||
script(type="text/javascript" src='/socket.io/socket.io.js')
|
||||
|
||||
//- don't use cdn for worker
|
||||
- var pdfWorkerPath = buildJsPath('/libs/' + lib('pdfjs') + '/pdf.worker', {cdn:false,fingerprint:false})
|
||||
|
||||
//- We need to do .replace(/\//g, '\\/') do that '</script>' -> '<\/script>'
|
||||
//- and doesn't prematurely end the script tag.
|
||||
script(type='text/javascript').
|
||||
|
@ -101,13 +105,14 @@ block requirejs
|
|||
"paths" : {
|
||||
"mathjax": "#{buildJsPath('/libs/mathjax/MathJax.js', {cdn:false, fingerprint:false, qs:{config:'TeX-AMS_HTML'}})}",
|
||||
"moment": "libs/#{lib('moment')}",
|
||||
"libs/pdf": "libs/#{lib('pdfjs')}/pdf",
|
||||
"pdfjs-dist/build/pdf": "libs/#{lib('pdfjs')}/pdf",
|
||||
"pdfjs-dist/build/pdf.worker": "#{pdfWorkerPath}",
|
||||
"ace": "#{lib('ace')}"
|
||||
},
|
||||
"urlArgs" : "fingerprint=#{fingerprint(jsPath + 'ide.js')}-#{fingerprint(jsPath + 'libs.js')}",
|
||||
"waitSeconds": 0,
|
||||
"shim": {
|
||||
"libs/pdf": {
|
||||
"pdfjs-dist/build/pdf": {
|
||||
"deps": ["libs/#{lib('pdfjs')}/compatibility"]
|
||||
},
|
||||
"ace/ext-searchbox": {
|
||||
|
@ -125,13 +130,9 @@ block requirejs
|
|||
};
|
||||
window.aceFingerprint = "#{fingerprint(jsPath + lib('ace') + '/ace.js')}"
|
||||
|
||||
- var pdfPath = "libs/" + lib('pdfjs') + "/pdf.worker.js"
|
||||
- var fingerprintedPath = fingerprint(jsPath+pdfPath)
|
||||
- var pdfJsWorkerPath = buildJsPath(pdfPath, {cdn:false,qs:{fingerprint:fingerprintedPath}}) // don't use worker for cdn
|
||||
- var aceWorkerPath = user.betaProgram ? buildJsPath(lib('ace'), {cdn:false,fingerprint:false}) : "" // don't use worker for cdn
|
||||
- var aceWorkerPath = user.betaProgram ? buildJsPath(lib('ace'), {cdn:false,fingerprint:false}) : "" // don't use cdn for worker
|
||||
|
||||
script(type='text/javascript').
|
||||
window.pdfJsWorkerPath = "#{pdfJsWorkerPath}";
|
||||
window.aceWorkerPath = "#{aceWorkerPath}";
|
||||
|
||||
script(
|
||||
|
|
|
@ -229,7 +229,7 @@ div.full-size.pdf(ng-controller="PdfController")
|
|||
|
||||
p.entry-content(ng-show="entry.content") {{ entry.content.trim() }}
|
||||
|
||||
p
|
||||
div
|
||||
.files-dropdown-container
|
||||
a.btn.btn-default.btn-sm(
|
||||
href,
|
||||
|
@ -344,7 +344,7 @@ div.full-size.pdf(ng-controller="PdfController")
|
|||
strong #{translate("ask_proj_owner_to_upgrade_for_faster_compiles")}
|
||||
p #{translate("free_accounts_have_timeout_upgrade_to_increase")}
|
||||
p Plus:
|
||||
p
|
||||
div
|
||||
ul.list-unstyled
|
||||
li
|
||||
i.fa.fa-check
|
||||
|
|
|
@ -47,130 +47,8 @@ block content
|
|||
div(ng-if="normalPrice")
|
||||
span.small Normally {{price.currency.symbol}}{{normalPrice}}
|
||||
.row
|
||||
div(sixpack-switch="subscription-form")
|
||||
.col-md-12(sixpack-default)
|
||||
form(ng-show="planName",novalidate)
|
||||
.row
|
||||
.col-md-12
|
||||
.form-group
|
||||
.row
|
||||
.col-md-6
|
||||
label.radio-inline
|
||||
input.paymentTypeOption(type="radio",value="credit_card", ng-model="paymentMethod.value")
|
||||
i.fa.fa-cc-mastercard.fa-3x
|
||||
span
|
||||
i.fa.fa-cc-visa.fa-3x
|
||||
.col-md-6
|
||||
label.radio-inline
|
||||
input.paymentTypeOption(type="radio", value="paypal", ng-model="paymentMethod.value")
|
||||
i.fa.fa-cc-paypal.fa-3x
|
||||
|
||||
.alert.alert-warning.small(ng-show="genericError")
|
||||
strong {{genericError}}
|
||||
|
||||
span(ng-hide="paymentMethod.value == 'paypal'")
|
||||
.row
|
||||
.col-md-12
|
||||
.form-group
|
||||
div.alert.alert-warning.small(ng-hide="validation.correctCvv") #{translate("invalid")} CVV
|
||||
div.alert.alert-warning.small(ng-hide="validation.correctCardNumber") #{translate("invalid")} #{translate("credit_card_number")}
|
||||
.row
|
||||
.col-md-6
|
||||
.form-group(ng-class="validation.number == false || validation.errorFields.number ? 'has-error' : ''")
|
||||
input.form-control(ng-model='data.number', ng-blur="validateCardNumber()", placeholder="#{translate('credit_card_number')}")
|
||||
.col-md-3
|
||||
.form-group(ng-class="validation.correctCvv == false || validation.errorFields.cvv ? 'has-error' : ''")
|
||||
input.form-control(ng-model='data.cvv', ng-blur="validateCvv()", placeholder="CVV")
|
||||
.row
|
||||
.col-md-12
|
||||
div.alert.alert-warning.small(ng-hide="validation.correctExpiry") #{translate("invalid")} #{translate("expiry")}
|
||||
.row
|
||||
.col-md-3
|
||||
.form-group(ng-class="validation.correctExpiry == false || validation.errorFields.month ? 'has-error' : ''")
|
||||
select.form-control(data-recurly='month', ng-change="validateExpiry()", ng-model='data.month')
|
||||
option(value="", disabled, selected) Month
|
||||
option(value="01") 01
|
||||
option(value="02") 02
|
||||
option(value="03") 03
|
||||
option(value="04") 04
|
||||
option(value="05") 05
|
||||
option(value="06") 06
|
||||
option(value="07") 07
|
||||
option(value="08") 08
|
||||
option(value="09") 09
|
||||
option(value="10") 10
|
||||
option(value="11") 11
|
||||
option(value="12") 12
|
||||
.col-md-4
|
||||
.form-group(ng-class="validation.correctExpiry == false || validation.errorFields.year ? 'has-error' : ''")
|
||||
select.form-control(data-recurly='year', ng-change="validateExpiry()", ng-model='data.year')
|
||||
option(value="", disabled, selected) Year
|
||||
option(value="2016") 2016
|
||||
option(value="2017") 2017
|
||||
option(value="2018") 2018
|
||||
option(value="2019") 2019
|
||||
option(value="2020") 2020
|
||||
option(value="2021") 2021
|
||||
option(value="2022") 2022
|
||||
option(value="2023") 2023
|
||||
option(value="2024") 2024
|
||||
option(value="2025") 2025
|
||||
option(value="2026") 2026
|
||||
.row
|
||||
.col-md-6
|
||||
.form-group(ng-class="validation.errorFields.first_name ? 'has-error' : ''")
|
||||
input.form-control(type='text', value='', maxlength='255', , onkeyup='', data-recurly="first_name", ng-model="data.first_name", required, placeholder="#{translate('first_name')}")
|
||||
.col-md-6
|
||||
.form-group(ng-class="validation.errorFields.last_name ? 'has-error' : ''")
|
||||
input.form-control(type='text', value='', maxlength='255', onkeyup='', data-recurly="last_name", ng-model="data.last_name", required, placeholder="#{translate('last_name')}")
|
||||
hr
|
||||
.row
|
||||
.col-md-12
|
||||
.form-group(ng-class="validation.errorFields.address1 ? 'has-error' : ''")
|
||||
label #{translate("billing_address")}
|
||||
input.form-control(type='text', value='', maxlength='255', onkeyup='', ng-model="data.address1", placeholder="#{translate('address')}")
|
||||
.form-group(ng-class="validation.errorFields.address2 ? 'has-error' : ''")
|
||||
input.form-control(type='text', value='', maxlength='255', onkeyup='', ng-model="data.address2", placeholder="#{translate('address')}")
|
||||
.form-group(ng-class="validation.errorFields.state ? 'has-error' : ''")
|
||||
input.form-control(type='text', value='', maxlength='255', onkeyup='', ng-model="data.state", placeholder="#{translate('state')}")
|
||||
.row
|
||||
.col-md-7
|
||||
.form-group(ng-class="validation.errorFields.city ? 'has-error' : ''")
|
||||
input.form-control(type='text', value='', maxlength='255', onkeyup='', data-recurly="city", ng-model="data.city", placeholder="#{translate('city')}")
|
||||
.col-md-5(ng-class="validation.errorFields.postal_code ? 'has-error' : ''")
|
||||
input.form-control(type='text', value='', maxlength='255', onkeyup='', data-recurly="postal_code", ng-model="data.postal_code", placeholder="#{translate('zip_post_code')}")
|
||||
.row
|
||||
.col-md-7
|
||||
.form-group(ng-class="validation.errorFields.country ? 'has-error' : ''")
|
||||
select.form-control(data-recurly="country", ng-model="data.country", ng-change="updateCountry()", required)
|
||||
mixin countries_options()
|
||||
.row
|
||||
.col-md-8
|
||||
if (showCouponField)
|
||||
.form-group
|
||||
input.form-control(type='text', ng-blur="applyCoupon()", ng-model="data.coupon", placeholder="#{translate('coupon')}")
|
||||
.row
|
||||
.col-md-8
|
||||
if (showVatField)
|
||||
.form-group
|
||||
input.form-control(type='text', ng-blur="applyVatNumber()", ng-model="data.vat_number", placeholder="#{translate('vat_number')}")
|
||||
.row
|
||||
.col-xs-7
|
||||
.form-group
|
||||
button.btn.btn-success(ng-click="submit()", ng-disabled="processing", sixpack-convert="payment-left-menu-bottom") #{translate("upgrade_now")}
|
||||
|
||||
.col-xs-3.pricingBreakdown
|
||||
div(ng-if="price.next.subtotal != price.next.total") Subtotal
|
||||
div(ng-if="price.next.tax!='0.00'") Tax
|
||||
div
|
||||
strong Total
|
||||
.col-xs-2
|
||||
div(ng-if="price.next.subtotal != price.next.total").pull-right {{price.currency.symbol}}{{price.next.subtotal}}
|
||||
div(ng-if="price.next.tax!='0.00'").pull-right {{price.currency.symbol}}{{price.next.tax}}
|
||||
div.pull-right
|
||||
strong {{price.currency.symbol}}{{price.next.total}}
|
||||
|
||||
.col-md-12(sixpack-when="simple")
|
||||
div()
|
||||
.col-md-12()
|
||||
form(
|
||||
ng-if="planName"
|
||||
name="simpleCCForm"
|
||||
|
@ -321,7 +199,6 @@ block content
|
|||
button.btn.btn-success.btn-block(
|
||||
ng-click="submit()"
|
||||
ng-disabled="processing || !isFormValid(simpleCCForm);"
|
||||
sixpack-convert="payment-left-menu-bottom"
|
||||
)
|
||||
span(ng-show="processing")
|
||||
i.fa.fa-spinner.fa-spin
|
||||
|
|
|
@ -166,6 +166,8 @@ module.exports = settings =
|
|||
price: 0
|
||||
features: defaultFeatures
|
||||
}]
|
||||
|
||||
enableSubscriptions:false
|
||||
|
||||
# i18n
|
||||
# ------
|
||||
|
|
|
@ -231,6 +231,12 @@ define [
|
|||
|
||||
_aceDeltaToSimpleDelta: (aceDelta, docLines) ->
|
||||
start = aceDelta.start
|
||||
if !start?
|
||||
error = new Error("aceDelta had no start event.")
|
||||
Raven?.captureException(error, {
|
||||
aceDelta: JSON.stringify(aceDelta)
|
||||
})
|
||||
throw error
|
||||
linesBefore = docLines.slice(0, start.row)
|
||||
position =
|
||||
linesBefore.join("").length + # full lines
|
||||
|
|
|
@ -6,9 +6,6 @@ define [
|
|||
pdfViewer
|
||||
|
||||
) ->
|
||||
if PDFJS?
|
||||
PDFJS.workerSrc = window.pdfJsWorkerPath
|
||||
|
||||
App.directive "pdfng", ["$timeout", "localStorage", ($timeout, localStorage) ->
|
||||
return {
|
||||
scope: {
|
||||
|
|
|
@ -1,26 +1,46 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
"pdfjs-dist/build/pdf"
|
||||
], (App, PDFJS) ->
|
||||
# App = angular.module 'PDFRenderer', ['pdfAnnotations', 'pdfTextLayer']
|
||||
|
||||
App.factory 'PDFRenderer', ['$q', '$timeout', 'pdfAnnotations', 'pdfTextLayer', 'pdfSpinner', ($q, $timeout, pdfAnnotations, pdfTextLayer, pdfSpinner) ->
|
||||
|
||||
# Have a single worker used by all rendering, to avoid reloading
|
||||
RenderThread = { worker: null, count: 0}
|
||||
|
||||
getRenderThread = () ->
|
||||
if RenderThread.count > 16 # recycle the worker periodically to avoid leaks
|
||||
RenderThread.readyToDestroy = true
|
||||
RenderThread = { worker: null, count: 0 }
|
||||
RenderThread.worker ||= new PDFJS.PDFWorker('pdfjsworker')
|
||||
RenderThread.count++
|
||||
return RenderThread
|
||||
|
||||
resetWorker = (thread) ->
|
||||
thread.worker.destroy() if thread.readyToDestroy
|
||||
|
||||
# The PDF page renderer
|
||||
|
||||
class PDFRenderer
|
||||
JOB_QUEUE_INTERVAL: 25
|
||||
PAGE_LOAD_TIMEOUT: 60*1000
|
||||
INDICATOR_DELAY1: 100 # time to delay before showing the indicator
|
||||
INDICATOR_DELAY2: 250 # time until the indicator starts animating
|
||||
TEXTLAYER_TIMEOUT: 100
|
||||
|
||||
constructor: (@url, @options) ->
|
||||
if navigator.userAgent?.indexOf("Edge/") >= 0 or navigator.userAgent?.indexOf("rv:11.0") >= 0 # IE 11
|
||||
# Microsoft Edge does not work well with font-face (Sept 2016)
|
||||
PDFJS.disableFontFace = true
|
||||
if window.location?.search?.indexOf("disable-font-face=true") >= 0
|
||||
window.PDFJS.disableFontFace = true
|
||||
else
|
||||
window.PDFJS.disableFontFace = false
|
||||
if @options.disableAutoFetch
|
||||
PDFJS.disableAutoFetch = true # prevent loading whole file
|
||||
window.PDFJS.disableAutoFetch = true # prevent loading whole file
|
||||
# PDFJS.disableStream
|
||||
# PDFJS.disableRange
|
||||
@scale = @options.scale || 1
|
||||
@pdfjs = PDFJS.getDocument {url: @url, rangeChunkSize: 2*65536}
|
||||
@thread = getRenderThread()
|
||||
@pdfjs = PDFJS.getDocument {url: @url, rangeChunkSize: 2*65536, worker: @thread.worker}
|
||||
@pdfjs.onProgress = @options.progressCallback
|
||||
@document = $q.when(@pdfjs)
|
||||
@navigateFn = @options.navigateFn
|
||||
|
@ -245,6 +265,12 @@ define [
|
|||
return
|
||||
|
||||
canvas = $('<canvas class="pdf-canvas pdfng-rendering"></canvas>')
|
||||
# In Windows+IE we must have the canvas in the DOM during
|
||||
# rendering to see the fonts defined in the DOM. If we try to
|
||||
# render 'offscreen' then all the text will be sans-serif.
|
||||
# Previously we rendered offscreen and added in the canvas
|
||||
# when rendering was complete.
|
||||
element.canvas.replaceWith(canvas)
|
||||
|
||||
viewport = page.getViewport (scale)
|
||||
|
||||
|
@ -282,6 +308,7 @@ define [
|
|||
textLayer = new pdfTextLayer({
|
||||
textLayerDiv: element.text[0]
|
||||
viewport: viewport
|
||||
renderer: PDFJS.renderTextLayer
|
||||
})
|
||||
|
||||
annotationsLayer = new pdfAnnotations({
|
||||
|
@ -296,12 +323,14 @@ define [
|
|||
transform: [pixelRatio, 0, 0, pixelRatio, 0, 0]
|
||||
}
|
||||
|
||||
textLayerTimeout = @TEXTLAYER_TIMEOUT
|
||||
|
||||
result.then () ->
|
||||
# page render success
|
||||
element.canvas.replaceWith(canvas)
|
||||
canvas.removeClass('pdfng-rendering')
|
||||
page.getTextContent().then (textContent) ->
|
||||
page.getTextContent({normalizeWhitespace: true}).then (textContent) ->
|
||||
textLayer.setTextContent textContent
|
||||
textLayer.render(textLayerTimeout)
|
||||
, (error) ->
|
||||
self.errorCallback?(error)
|
||||
page.getAnnotations().then (annotations) ->
|
||||
|
@ -320,8 +349,9 @@ define [
|
|||
destroy: () ->
|
||||
@shuttingDown = true
|
||||
@resetState()
|
||||
@pdfjs.then (document) ->
|
||||
@pdfjs.then (document) =>
|
||||
document.cleanup()
|
||||
document.destroy()
|
||||
resetWorker(@thread)
|
||||
|
||||
]
|
||||
|
|
|
@ -1,225 +1,57 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
# App = angular.module 'pdfTextLayer', []
|
||||
|
||||
# uses the PDFJS text layer renderer to provide invisible overlayed
|
||||
# text for searching
|
||||
|
||||
App.factory 'pdfTextLayer', [ () ->
|
||||
|
||||
# TRANSLATED FROM pdf.js-1.0.712
|
||||
# pdf.js-1.0.712/web/ui_utils.js
|
||||
# pdf.js-1.0.712/web/text_layer_builder.js
|
||||
|
||||
# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
|
||||
# Copyright 2012 Mozilla Foundation
|
||||
# *
|
||||
# * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# * you may not use this file except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.apache.org/licenses/LICENSE-2.0
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
#
|
||||
|
||||
# globals CustomStyle, scrollIntoView, PDFJS
|
||||
# ms
|
||||
|
||||
# optimised CSS custom property getter/setter
|
||||
|
||||
CustomStyle = (CustomStyleClosure = ->
|
||||
|
||||
# As noted on: http://www.zachstronaut.com/posts/2009/02/17/
|
||||
# animate-css-transforms-firefox-webkit.html
|
||||
# in some versions of IE9 it is critical that ms appear in this list
|
||||
# before Moz
|
||||
CustomStyle = ->
|
||||
prefixes = [
|
||||
'ms'
|
||||
'Moz'
|
||||
'Webkit'
|
||||
'O'
|
||||
]
|
||||
_cache = {}
|
||||
CustomStyle.getProp = get = (propName, element) ->
|
||||
|
||||
# check cache only when no element is given
|
||||
return _cache[propName] if arguments.length is 1 and typeof _cache[propName] is 'string'
|
||||
element = element or document.documentElement
|
||||
style = element.style
|
||||
prefixed = undefined
|
||||
uPropName = undefined
|
||||
|
||||
# test standard property first
|
||||
return (_cache[propName] = propName) if typeof style[propName] is 'string'
|
||||
|
||||
# capitalize
|
||||
uPropName = propName.charAt(0).toUpperCase() + propName.slice(1)
|
||||
|
||||
# test vendor specific properties
|
||||
i = 0
|
||||
l = prefixes.length
|
||||
|
||||
while i < l
|
||||
prefixed = prefixes[i] + uPropName
|
||||
return (_cache[propName] = prefixed) if typeof style[prefixed] is 'string'
|
||||
i++
|
||||
|
||||
#if all fails then set to undefined
|
||||
_cache[propName] = 'undefined'
|
||||
|
||||
CustomStyle.setProp = set = (propName, element, str) ->
|
||||
prop = @getProp(propName)
|
||||
element.style[prop] = str if prop isnt 'undefined'
|
||||
return
|
||||
|
||||
CustomStyle
|
||||
)()
|
||||
|
||||
#################################
|
||||
|
||||
isAllWhitespace = (str) ->
|
||||
not NonWhitespaceRegexp.test(str)
|
||||
'use strict'
|
||||
FIND_SCROLL_OFFSET_TOP = -50
|
||||
FIND_SCROLL_OFFSET_LEFT = -400
|
||||
MAX_TEXT_DIVS_TO_RENDER = 100000
|
||||
RENDER_DELAY = 200
|
||||
NonWhitespaceRegexp = /\S/
|
||||
|
||||
###*
|
||||
TextLayerBuilder provides text-selection functionality for the PDF.
|
||||
It does this by creating overlay divs over the PDF text. These divs
|
||||
contain text that matches the PDF text they are overlaying. This object
|
||||
also provides a way to highlight text that is being searched for.
|
||||
###
|
||||
|
||||
class pdfTextLayer
|
||||
|
||||
constructor: (options) ->
|
||||
@textLayerDiv = options.textLayerDiv
|
||||
@layoutDone = false
|
||||
@divContentDone = false
|
||||
@pageIdx = options.pageIndex
|
||||
@matches = []
|
||||
@lastScrollSource = options.lastScrollSource or null
|
||||
@viewport = options.viewport
|
||||
@isViewerInPresentationMode = options.isViewerInPresentationMode
|
||||
@textDivs = []
|
||||
@findController = options.findController or null
|
||||
@renderer = options.renderer
|
||||
@renderingDone = false
|
||||
|
||||
renderLayer: () ->
|
||||
render: (timeout) ->
|
||||
if @renderingDone or not @divContentDone
|
||||
return
|
||||
|
||||
if @textLayerRenderTask?
|
||||
@textLayerRenderTask.cancel()
|
||||
@textLayerRenderTask = null
|
||||
|
||||
@textDivs = []
|
||||
textLayerFrag = document.createDocumentFragment()
|
||||
textDivs = @textDivs
|
||||
textDivsLength = textDivs.length
|
||||
canvas = document.createElement('canvas')
|
||||
ctx = canvas.getContext('2d')
|
||||
|
||||
# No point in rendering many divs as it would make the browser
|
||||
# unusable even after the divs are rendered.
|
||||
return if textDivsLength > MAX_TEXT_DIVS_TO_RENDER
|
||||
lastFontSize = undefined
|
||||
lastFontFamily = undefined
|
||||
i = 0
|
||||
while i < textDivsLength
|
||||
textDiv = textDivs[i]
|
||||
if textDiv.dataset.isWhitespace
|
||||
i++
|
||||
continue
|
||||
fontSize = textDiv.style.fontSize
|
||||
fontFamily = textDiv.style.fontFamily
|
||||
@textLayerRenderTask = @renderer {
|
||||
textContent: this.textContent,
|
||||
container: textLayerFrag,
|
||||
viewport: this.viewport,
|
||||
textDivs: this.textDivs,
|
||||
timeout: timeout,
|
||||
enhanceTextSelection: this.enhanceTextSelection,
|
||||
}
|
||||
|
||||
# Only build font string and set to context if different from last.
|
||||
if fontSize isnt lastFontSize or fontFamily isnt lastFontFamily
|
||||
ctx.font = fontSize + ' ' + fontFamily
|
||||
lastFontSize = fontSize
|
||||
lastFontFamily = fontFamily
|
||||
width = ctx.measureText(textDiv.textContent).width
|
||||
if width > 0
|
||||
textLayerFrag.appendChild textDiv
|
||||
textLayerSuccess = () =>
|
||||
@textLayerDiv.appendChild(textLayerFrag)
|
||||
@renderingDone = true
|
||||
|
||||
if textDiv.dataset.canvasWidth?
|
||||
# Dataset values come of type string.
|
||||
textScale = textDiv.dataset.canvasWidth / width;
|
||||
transform = 'scaleX(' + textScale + ')'
|
||||
else
|
||||
transform = ''
|
||||
rotation = textDiv.dataset.angle
|
||||
if rotation
|
||||
transform = 'rotate(' + rotation + 'deg) ' + transform
|
||||
if transform
|
||||
CustomStyle.setProp 'transform', textDiv, transform
|
||||
i++
|
||||
@textLayerDiv.appendChild textLayerFrag
|
||||
return
|
||||
textLayerFailure = () ->
|
||||
return # canceled or failed to render text layer -- skipping errors
|
||||
|
||||
appendText: (geom, styles) ->
|
||||
style = styles[geom.fontName]
|
||||
textDiv = document.createElement('div')
|
||||
@textDivs.push textDiv
|
||||
if isAllWhitespace(geom.str)
|
||||
textDiv.dataset.isWhitespace = true
|
||||
return
|
||||
tx = PDFJS.Util.transform(@viewport.transform, geom.transform)
|
||||
angle = Math.atan2(tx[1], tx[0])
|
||||
angle += Math.PI / 2 if style.vertical
|
||||
fontHeight = Math.sqrt((tx[2] * tx[2]) + (tx[3] * tx[3]))
|
||||
fontAscent = fontHeight
|
||||
if style.ascent
|
||||
fontAscent = style.ascent * fontAscent
|
||||
else fontAscent = (1 + style.descent) * fontAscent if style.descent
|
||||
left = undefined
|
||||
top = undefined
|
||||
if angle is 0
|
||||
left = tx[4]
|
||||
top = tx[5] - fontAscent
|
||||
else
|
||||
left = tx[4] + (fontAscent * Math.sin(angle))
|
||||
top = tx[5] - (fontAscent * Math.cos(angle))
|
||||
textDiv.style.left = left + 'px'
|
||||
textDiv.style.top = top + 'px'
|
||||
textDiv.style.fontSize = fontHeight + 'px'
|
||||
textDiv.style.fontFamily = style.fontFamily
|
||||
textDiv.textContent = geom.str
|
||||
|
||||
textDiv.ondblclick = (e) ->
|
||||
if (window.getSelection)
|
||||
window.getSelection().removeAllRanges();
|
||||
else if (document.selection)
|
||||
document.selection.empty();
|
||||
|
||||
# |fontName| is only used by the Font Inspector. This test will succeed
|
||||
# when e.g. the Font Inspector is off but the Stepper is on, but it's
|
||||
# not worth the effort to do a more accurate test.
|
||||
textDiv.dataset.fontName = geom.fontName if PDFJS.pdfBug
|
||||
|
||||
# Storing into dataset will convert number into string.
|
||||
textDiv.dataset.angle = angle * (180 / Math.PI) if angle isnt 0
|
||||
# We don't bother scaling single-char text divs, because it has very
|
||||
# little effect on text highlighting. This makes scrolling on docs with
|
||||
# lots of such divs a lot faster.
|
||||
if textDiv.textContent.length > 1
|
||||
if style.vertical
|
||||
textDiv.dataset.canvasWidth = geom.height * @viewport.scale
|
||||
else
|
||||
textDiv.dataset.canvasWidth = geom.width * @viewport.scale
|
||||
return
|
||||
@textLayerRenderTask.promise.then(textLayerSuccess, textLayerFailure)
|
||||
|
||||
setTextContent: (textContent) ->
|
||||
@textContent = textContent
|
||||
textItems = textContent.items
|
||||
i = 0
|
||||
len = textItems.length
|
||||
if (@textLayerRenderTask)
|
||||
@textLayerRenderTask.cancel();
|
||||
@textLayerRenderTask = null;
|
||||
|
||||
while i < len
|
||||
@appendText textItems[i], textContent.styles
|
||||
i++
|
||||
@divContentDone = true
|
||||
@renderLayer()
|
||||
return
|
||||
@textContent = textContent;
|
||||
@divContentDone = true;
|
||||
|
||||
]
|
||||
|
|
|
@ -6,7 +6,6 @@ define [
|
|||
"ide/pdfng/directives/pdfRenderer"
|
||||
"ide/pdfng/directives/pdfPage"
|
||||
"ide/pdfng/directives/pdfSpinner"
|
||||
"libs/pdf"
|
||||
], (
|
||||
App
|
||||
pdfTextLayer
|
||||
|
|
|
@ -157,13 +157,11 @@ define [
|
|||
isPaypal : postData.subscriptionDetails.isPaypal
|
||||
}
|
||||
|
||||
sixpack.convert "subscription-form"
|
||||
|
||||
$http.post("/user/subscription/create", postData)
|
||||
.success (data, status, headers)->
|
||||
sixpack.convert "in-editor-free-trial-plan", pricing.items.plan.code, (err)->
|
||||
event_tracking.sendMB "subscription-submission-success"
|
||||
window.location.href = "/user/subscription/thank-you"
|
||||
event_tracking.sendMB "subscription-submission-success"
|
||||
window.location.href = "/user/subscription/thank-you"
|
||||
.error (data, status, headers)->
|
||||
$scope.processing = false
|
||||
$scope.genericError = "Something went wrong processing the request"
|
||||
|
|
|
@ -1,563 +0,0 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/* Copyright 2012 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* globals VBArray, PDFJS */
|
||||
|
||||
'use strict';
|
||||
|
||||
// Initializing PDFJS global object here, it case if we need to change/disable
|
||||
// some PDF.js features, e.g. range requests
|
||||
if (typeof PDFJS === 'undefined') {
|
||||
(typeof window !== 'undefined' ? window : this).PDFJS = {};
|
||||
}
|
||||
|
||||
// Checking if the typed arrays are supported
|
||||
// Support: iOS<6.0 (subarray), IE<10, Android<4.0
|
||||
(function checkTypedArrayCompatibility() {
|
||||
if (typeof Uint8Array !== 'undefined') {
|
||||
// Support: iOS<6.0
|
||||
if (typeof Uint8Array.prototype.subarray === 'undefined') {
|
||||
Uint8Array.prototype.subarray = function subarray(start, end) {
|
||||
return new Uint8Array(this.slice(start, end));
|
||||
};
|
||||
Float32Array.prototype.subarray = function subarray(start, end) {
|
||||
return new Float32Array(this.slice(start, end));
|
||||
};
|
||||
}
|
||||
|
||||
// Support: Android<4.1
|
||||
if (typeof Float64Array === 'undefined') {
|
||||
window.Float64Array = Float32Array;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
function subarray(start, end) {
|
||||
return new TypedArray(this.slice(start, end));
|
||||
}
|
||||
|
||||
function setArrayOffset(array, offset) {
|
||||
if (arguments.length < 2) {
|
||||
offset = 0;
|
||||
}
|
||||
for (var i = 0, n = array.length; i < n; ++i, ++offset) {
|
||||
this[offset] = array[i] & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
function TypedArray(arg1) {
|
||||
var result, i, n;
|
||||
if (typeof arg1 === 'number') {
|
||||
result = [];
|
||||
for (i = 0; i < arg1; ++i) {
|
||||
result[i] = 0;
|
||||
}
|
||||
} else if ('slice' in arg1) {
|
||||
result = arg1.slice(0);
|
||||
} else {
|
||||
result = [];
|
||||
for (i = 0, n = arg1.length; i < n; ++i) {
|
||||
result[i] = arg1[i];
|
||||
}
|
||||
}
|
||||
|
||||
result.subarray = subarray;
|
||||
result.buffer = result;
|
||||
result.byteLength = result.length;
|
||||
result.set = setArrayOffset;
|
||||
|
||||
if (typeof arg1 === 'object' && arg1.buffer) {
|
||||
result.buffer = arg1.buffer;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
window.Uint8Array = TypedArray;
|
||||
window.Int8Array = TypedArray;
|
||||
|
||||
// we don't need support for set, byteLength for 32-bit array
|
||||
// so we can use the TypedArray as well
|
||||
window.Uint32Array = TypedArray;
|
||||
window.Int32Array = TypedArray;
|
||||
window.Uint16Array = TypedArray;
|
||||
window.Float32Array = TypedArray;
|
||||
window.Float64Array = TypedArray;
|
||||
})();
|
||||
|
||||
// URL = URL || webkitURL
|
||||
// Support: Safari<7, Android 4.2+
|
||||
(function normalizeURLObject() {
|
||||
if (!window.URL) {
|
||||
window.URL = window.webkitURL;
|
||||
}
|
||||
})();
|
||||
|
||||
// Object.defineProperty()?
|
||||
// Support: Android<4.0, Safari<5.1
|
||||
(function checkObjectDefinePropertyCompatibility() {
|
||||
if (typeof Object.defineProperty !== 'undefined') {
|
||||
var definePropertyPossible = true;
|
||||
try {
|
||||
// some browsers (e.g. safari) cannot use defineProperty() on DOM objects
|
||||
// and thus the native version is not sufficient
|
||||
Object.defineProperty(new Image(), 'id', { value: 'test' });
|
||||
// ... another test for android gb browser for non-DOM objects
|
||||
var Test = function Test() {};
|
||||
Test.prototype = { get id() { } };
|
||||
Object.defineProperty(new Test(), 'id',
|
||||
{ value: '', configurable: true, enumerable: true, writable: false });
|
||||
} catch (e) {
|
||||
definePropertyPossible = false;
|
||||
}
|
||||
if (definePropertyPossible) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty = function objectDefineProperty(obj, name, def) {
|
||||
delete obj[name];
|
||||
if ('get' in def) {
|
||||
obj.__defineGetter__(name, def['get']);
|
||||
}
|
||||
if ('set' in def) {
|
||||
obj.__defineSetter__(name, def['set']);
|
||||
}
|
||||
if ('value' in def) {
|
||||
obj.__defineSetter__(name, function objectDefinePropertySetter(value) {
|
||||
this.__defineGetter__(name, function objectDefinePropertyGetter() {
|
||||
return value;
|
||||
});
|
||||
return value;
|
||||
});
|
||||
obj[name] = def.value;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
// No XMLHttpRequest#response?
|
||||
// Support: IE<11, Android <4.0
|
||||
(function checkXMLHttpRequestResponseCompatibility() {
|
||||
var xhrPrototype = XMLHttpRequest.prototype;
|
||||
var xhr = new XMLHttpRequest();
|
||||
if (!('overrideMimeType' in xhr)) {
|
||||
// IE10 might have response, but not overrideMimeType
|
||||
// Support: IE10
|
||||
Object.defineProperty(xhrPrototype, 'overrideMimeType', {
|
||||
value: function xmlHttpRequestOverrideMimeType(mimeType) {}
|
||||
});
|
||||
}
|
||||
if ('responseType' in xhr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The worker will be using XHR, so we can save time and disable worker.
|
||||
PDFJS.disableWorker = true;
|
||||
|
||||
// Support: IE9
|
||||
if (typeof VBArray !== 'undefined') {
|
||||
Object.defineProperty(xhrPrototype, 'response', {
|
||||
get: function xmlHttpRequestResponseGet() {
|
||||
if (this.responseType === 'arraybuffer') {
|
||||
return new Uint8Array(new VBArray(this.responseBody).toArray());
|
||||
} else {
|
||||
return this.responseText;
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// other browsers
|
||||
function responseTypeSetter() {
|
||||
// will be only called to set "arraybuffer"
|
||||
this.overrideMimeType('text/plain; charset=x-user-defined');
|
||||
}
|
||||
if (typeof xhr.overrideMimeType === 'function') {
|
||||
Object.defineProperty(xhrPrototype, 'responseType',
|
||||
{ set: responseTypeSetter });
|
||||
}
|
||||
function responseGetter() {
|
||||
var text = this.responseText;
|
||||
var i, n = text.length;
|
||||
var result = new Uint8Array(n);
|
||||
for (i = 0; i < n; ++i) {
|
||||
result[i] = text.charCodeAt(i) & 0xFF;
|
||||
}
|
||||
return result.buffer;
|
||||
}
|
||||
Object.defineProperty(xhrPrototype, 'response', { get: responseGetter });
|
||||
})();
|
||||
|
||||
// window.btoa (base64 encode function) ?
|
||||
// Support: IE<10
|
||||
(function checkWindowBtoaCompatibility() {
|
||||
if ('btoa' in window) {
|
||||
return;
|
||||
}
|
||||
|
||||
var digits =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
|
||||
window.btoa = function windowBtoa(chars) {
|
||||
var buffer = '';
|
||||
var i, n;
|
||||
for (i = 0, n = chars.length; i < n; i += 3) {
|
||||
var b1 = chars.charCodeAt(i) & 0xFF;
|
||||
var b2 = chars.charCodeAt(i + 1) & 0xFF;
|
||||
var b3 = chars.charCodeAt(i + 2) & 0xFF;
|
||||
var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
|
||||
var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
|
||||
var d4 = i + 2 < n ? (b3 & 0x3F) : 64;
|
||||
buffer += (digits.charAt(d1) + digits.charAt(d2) +
|
||||
digits.charAt(d3) + digits.charAt(d4));
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
})();
|
||||
|
||||
// window.atob (base64 encode function)?
|
||||
// Support: IE<10
|
||||
(function checkWindowAtobCompatibility() {
|
||||
if ('atob' in window) {
|
||||
return;
|
||||
}
|
||||
|
||||
// https://github.com/davidchambers/Base64.js
|
||||
var digits =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
window.atob = function (input) {
|
||||
input = input.replace(/=+$/, '');
|
||||
if (input.length % 4 === 1) {
|
||||
throw new Error('bad atob input');
|
||||
}
|
||||
for (
|
||||
// initialize result and counters
|
||||
var bc = 0, bs, buffer, idx = 0, output = '';
|
||||
// get next character
|
||||
buffer = input.charAt(idx++);
|
||||
// character found in table?
|
||||
// initialize bit storage and add its ascii value
|
||||
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
|
||||
// and if not first of each 4 characters,
|
||||
// convert the first 8 bits to one ascii character
|
||||
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
|
||||
) {
|
||||
// try to find character in table (0-63, not found => -1)
|
||||
buffer = digits.indexOf(buffer);
|
||||
}
|
||||
return output;
|
||||
};
|
||||
})();
|
||||
|
||||
// Function.prototype.bind?
|
||||
// Support: Android<4.0, iOS<6.0
|
||||
(function checkFunctionPrototypeBindCompatibility() {
|
||||
if (typeof Function.prototype.bind !== 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
Function.prototype.bind = function functionPrototypeBind(obj) {
|
||||
var fn = this, headArgs = Array.prototype.slice.call(arguments, 1);
|
||||
var bound = function functionPrototypeBindBound() {
|
||||
var args = headArgs.concat(Array.prototype.slice.call(arguments));
|
||||
return fn.apply(obj, args);
|
||||
};
|
||||
return bound;
|
||||
};
|
||||
})();
|
||||
|
||||
// HTMLElement dataset property
|
||||
// Support: IE<11, Safari<5.1, Android<4.0
|
||||
(function checkDatasetProperty() {
|
||||
var div = document.createElement('div');
|
||||
if ('dataset' in div) {
|
||||
return; // dataset property exists
|
||||
}
|
||||
|
||||
Object.defineProperty(HTMLElement.prototype, 'dataset', {
|
||||
get: function() {
|
||||
if (this._dataset) {
|
||||
return this._dataset;
|
||||
}
|
||||
|
||||
var dataset = {};
|
||||
for (var j = 0, jj = this.attributes.length; j < jj; j++) {
|
||||
var attribute = this.attributes[j];
|
||||
if (attribute.name.substring(0, 5) !== 'data-') {
|
||||
continue;
|
||||
}
|
||||
var key = attribute.name.substring(5).replace(/\-([a-z])/g,
|
||||
function(all, ch) {
|
||||
return ch.toUpperCase();
|
||||
});
|
||||
dataset[key] = attribute.value;
|
||||
}
|
||||
|
||||
Object.defineProperty(this, '_dataset', {
|
||||
value: dataset,
|
||||
writable: false,
|
||||
enumerable: false
|
||||
});
|
||||
return dataset;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
})();
|
||||
|
||||
// HTMLElement classList property
|
||||
// Support: IE<10, Android<4.0, iOS<5.0
|
||||
(function checkClassListProperty() {
|
||||
var div = document.createElement('div');
|
||||
if ('classList' in div) {
|
||||
return; // classList property exists
|
||||
}
|
||||
|
||||
function changeList(element, itemName, add, remove) {
|
||||
var s = element.className || '';
|
||||
var list = s.split(/\s+/g);
|
||||
if (list[0] === '') {
|
||||
list.shift();
|
||||
}
|
||||
var index = list.indexOf(itemName);
|
||||
if (index < 0 && add) {
|
||||
list.push(itemName);
|
||||
}
|
||||
if (index >= 0 && remove) {
|
||||
list.splice(index, 1);
|
||||
}
|
||||
element.className = list.join(' ');
|
||||
return (index >= 0);
|
||||
}
|
||||
|
||||
var classListPrototype = {
|
||||
add: function(name) {
|
||||
changeList(this.element, name, true, false);
|
||||
},
|
||||
contains: function(name) {
|
||||
return changeList(this.element, name, false, false);
|
||||
},
|
||||
remove: function(name) {
|
||||
changeList(this.element, name, false, true);
|
||||
},
|
||||
toggle: function(name) {
|
||||
changeList(this.element, name, true, true);
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(HTMLElement.prototype, 'classList', {
|
||||
get: function() {
|
||||
if (this._classList) {
|
||||
return this._classList;
|
||||
}
|
||||
|
||||
var classList = Object.create(classListPrototype, {
|
||||
element: {
|
||||
value: this,
|
||||
writable: false,
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, '_classList', {
|
||||
value: classList,
|
||||
writable: false,
|
||||
enumerable: false
|
||||
});
|
||||
return classList;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
})();
|
||||
|
||||
// Check console compatibility
|
||||
// In older IE versions the console object is not available
|
||||
// unless console is open.
|
||||
// Support: IE<10
|
||||
(function checkConsoleCompatibility() {
|
||||
if (!('console' in window)) {
|
||||
window.console = {
|
||||
log: function() {},
|
||||
error: function() {},
|
||||
warn: function() {}
|
||||
};
|
||||
} else if (!('bind' in console.log)) {
|
||||
// native functions in IE9 might not have bind
|
||||
console.log = (function(fn) {
|
||||
return function(msg) { return fn(msg); };
|
||||
})(console.log);
|
||||
console.error = (function(fn) {
|
||||
return function(msg) { return fn(msg); };
|
||||
})(console.error);
|
||||
console.warn = (function(fn) {
|
||||
return function(msg) { return fn(msg); };
|
||||
})(console.warn);
|
||||
}
|
||||
})();
|
||||
|
||||
// Check onclick compatibility in Opera
|
||||
// Support: Opera<15
|
||||
(function checkOnClickCompatibility() {
|
||||
// workaround for reported Opera bug DSK-354448:
|
||||
// onclick fires on disabled buttons with opaque content
|
||||
function ignoreIfTargetDisabled(event) {
|
||||
if (isDisabled(event.target)) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
function isDisabled(node) {
|
||||
return node.disabled || (node.parentNode && isDisabled(node.parentNode));
|
||||
}
|
||||
if (navigator.userAgent.indexOf('Opera') !== -1) {
|
||||
// use browser detection since we cannot feature-check this bug
|
||||
document.addEventListener('click', ignoreIfTargetDisabled, true);
|
||||
}
|
||||
})();
|
||||
|
||||
// Checks if possible to use URL.createObjectURL()
|
||||
// Support: IE
|
||||
(function checkOnBlobSupport() {
|
||||
// sometimes IE loosing the data created with createObjectURL(), see #3977
|
||||
if (navigator.userAgent.indexOf('Trident') >= 0) {
|
||||
PDFJS.disableCreateObjectURL = true;
|
||||
}
|
||||
})();
|
||||
|
||||
// Checks if navigator.language is supported
|
||||
(function checkNavigatorLanguage() {
|
||||
if ('language' in navigator &&
|
||||
/^[a-z]+(-[A-Z]+)?$/.test(navigator.language)) {
|
||||
return;
|
||||
}
|
||||
function formatLocale(locale) {
|
||||
var split = locale.split(/[-_]/);
|
||||
split[0] = split[0].toLowerCase();
|
||||
if (split.length > 1) {
|
||||
split[1] = split[1].toUpperCase();
|
||||
}
|
||||
return split.join('-');
|
||||
}
|
||||
var language = navigator.language || navigator.userLanguage || 'en-US';
|
||||
PDFJS.locale = formatLocale(language);
|
||||
})();
|
||||
|
||||
(function checkRangeRequests() {
|
||||
// Safari has issues with cached range requests see:
|
||||
// https://github.com/mozilla/pdf.js/issues/3260
|
||||
// Last tested with version 6.0.4.
|
||||
// Support: Safari 6.0+
|
||||
var isSafari = Object.prototype.toString.call(
|
||||
window.HTMLElement).indexOf('Constructor') > 0;
|
||||
|
||||
// Older versions of Android (pre 3.0) has issues with range requests, see:
|
||||
// https://github.com/mozilla/pdf.js/issues/3381.
|
||||
// Make sure that we only match webkit-based Android browsers,
|
||||
// since Firefox/Fennec works as expected.
|
||||
// Support: Android<3.0
|
||||
var regex = /Android\s[0-2][^\d]/;
|
||||
var isOldAndroid = regex.test(navigator.userAgent);
|
||||
|
||||
if (isSafari || isOldAndroid) {
|
||||
PDFJS.disableRange = true;
|
||||
}
|
||||
})();
|
||||
|
||||
// Check if the browser supports manipulation of the history.
|
||||
// Support: IE<10, Android<4.2
|
||||
(function checkHistoryManipulation() {
|
||||
// Android 2.x has so buggy pushState support that it was removed in
|
||||
// Android 3.0 and restored as late as in Android 4.2.
|
||||
// Support: Android 2.x
|
||||
if (!history.pushState || navigator.userAgent.indexOf('Android 2.') >= 0) {
|
||||
PDFJS.disableHistory = true;
|
||||
}
|
||||
})();
|
||||
|
||||
// Support: IE<11, Chrome<21, Android<4.4, Safari<6
|
||||
(function checkSetPresenceInImageData() {
|
||||
// IE < 11 will use window.CanvasPixelArray which lacks set function.
|
||||
if (window.CanvasPixelArray) {
|
||||
if (typeof window.CanvasPixelArray.prototype.set !== 'function') {
|
||||
window.CanvasPixelArray.prototype.set = function(arr) {
|
||||
for (var i = 0, ii = this.length; i < ii; i++) {
|
||||
this[i] = arr[i];
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// Old Chrome and Android use an inaccessible CanvasPixelArray prototype.
|
||||
// Because we cannot feature detect it, we rely on user agent parsing.
|
||||
var polyfill = false, versionMatch;
|
||||
if (navigator.userAgent.indexOf('Chrom') >= 0) {
|
||||
versionMatch = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
|
||||
// Chrome < 21 lacks the set function.
|
||||
polyfill = versionMatch && parseInt(versionMatch[2]) < 21;
|
||||
} else if (navigator.userAgent.indexOf('Android') >= 0) {
|
||||
// Android < 4.4 lacks the set function.
|
||||
// Android >= 4.4 will contain Chrome in the user agent,
|
||||
// thus pass the Chrome check above and not reach this block.
|
||||
polyfill = /Android\s[0-4][^\d]/g.test(navigator.userAgent);
|
||||
} else if (navigator.userAgent.indexOf('Safari') >= 0) {
|
||||
versionMatch = navigator.userAgent.
|
||||
match(/Version\/([0-9]+)\.([0-9]+)\.([0-9]+) Safari\//);
|
||||
// Safari < 6 lacks the set function.
|
||||
polyfill = versionMatch && parseInt(versionMatch[1]) < 6;
|
||||
}
|
||||
|
||||
if (polyfill) {
|
||||
var contextPrototype = window.CanvasRenderingContext2D.prototype;
|
||||
contextPrototype._createImageData = contextPrototype.createImageData;
|
||||
contextPrototype.createImageData = function(w, h) {
|
||||
var imageData = this._createImageData(w, h);
|
||||
imageData.data.set = function(arr) {
|
||||
for (var i = 0, ii = this.length; i < ii; i++) {
|
||||
this[i] = arr[i];
|
||||
}
|
||||
};
|
||||
return imageData;
|
||||
};
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
// Support: IE<10, Android<4.0, iOS
|
||||
(function checkRequestAnimationFrame() {
|
||||
function fakeRequestAnimationFrame(callback) {
|
||||
window.setTimeout(callback, 20);
|
||||
}
|
||||
|
||||
var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
|
||||
if (isIOS) {
|
||||
// requestAnimationFrame on iOS is broken, replacing with fake one.
|
||||
window.requestAnimationFrame = fakeRequestAnimationFrame;
|
||||
return;
|
||||
}
|
||||
if ('requestAnimationFrame' in window) {
|
||||
return;
|
||||
}
|
||||
window.requestAnimationFrame =
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
fakeRequestAnimationFrame;
|
||||
})();
|
||||
|
||||
(function checkCanvasSizeLimitation() {
|
||||
var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
|
||||
var isAndroid = /Android/g.test(navigator.userAgent);
|
||||
if (isIOS || isAndroid) {
|
||||
// 5MP
|
||||
PDFJS.maxCanvasPixels = 5242880;
|
||||
}
|
||||
})();
|
File diff suppressed because it is too large
Load diff
38151
services/web/public/js/libs/pdfjs-1.0.712/pdf.worker.js
vendored
38151
services/web/public/js/libs/pdfjs-1.0.712/pdf.worker.js
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,3 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
/* Copyright 2012 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -16,7 +14,8 @@
|
|||
*/
|
||||
/* globals VBArray, PDFJS */
|
||||
|
||||
'use strict';
|
||||
(function compatibilityWrapper() {
|
||||
'use strict';
|
||||
|
||||
// Initializing PDFJS global object here, it case if we need to change/disable
|
||||
// some PDF.js features, e.g. range requests
|
||||
|
@ -447,20 +446,10 @@ if (typeof PDFJS === 'undefined') {
|
|||
|
||||
// Checks if navigator.language is supported
|
||||
(function checkNavigatorLanguage() {
|
||||
if ('language' in navigator &&
|
||||
/^[a-z]+(-[A-Z]+)?$/.test(navigator.language)) {
|
||||
if ('language' in navigator) {
|
||||
return;
|
||||
}
|
||||
function formatLocale(locale) {
|
||||
var split = locale.split(/[-_]/);
|
||||
split[0] = split[0].toLowerCase();
|
||||
if (split.length > 1) {
|
||||
split[1] = split[1].toUpperCase();
|
||||
}
|
||||
return split.join('-');
|
||||
}
|
||||
var language = navigator.language || navigator.userLanguage || 'en-US';
|
||||
PDFJS.locale = formatLocale(language);
|
||||
PDFJS.locale = navigator.userLanguage || 'en-US';
|
||||
})();
|
||||
|
||||
(function checkRangeRequests() {
|
||||
|
@ -479,7 +468,10 @@ if (typeof PDFJS === 'undefined') {
|
|||
var regex = /Android\s[0-2][^\d]/;
|
||||
var isOldAndroid = regex.test(navigator.userAgent);
|
||||
|
||||
if (isSafari || isOldAndroid) {
|
||||
// Range requests are broken in Chrome 39 and 40, https://crbug.com/442318
|
||||
var isChromeWithRangeBug = /Chrome\/(39|40)\./.test(navigator.userAgent);
|
||||
|
||||
if (isSafari || isOldAndroid || isChromeWithRangeBug) {
|
||||
PDFJS.disableRange = true;
|
||||
PDFJS.disableStream = true;
|
||||
}
|
||||
|
@ -529,9 +521,9 @@ if (typeof PDFJS === 'undefined') {
|
|||
|
||||
if (polyfill) {
|
||||
var contextPrototype = window.CanvasRenderingContext2D.prototype;
|
||||
contextPrototype._createImageData = contextPrototype.createImageData;
|
||||
var createImageData = contextPrototype.createImageData;
|
||||
contextPrototype.createImageData = function(w, h) {
|
||||
var imageData = this._createImageData(w, h);
|
||||
var imageData = createImageData.call(this, w, h);
|
||||
imageData.data.set = function(arr) {
|
||||
for (var i = 0, ii = this.length; i < ii; i++) {
|
||||
this[i] = arr[i];
|
||||
|
@ -539,6 +531,8 @@ if (typeof PDFJS === 'undefined') {
|
|||
};
|
||||
return imageData;
|
||||
};
|
||||
// this closure will be kept referenced, so clear its vars
|
||||
contextPrototype = null;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
@ -572,3 +566,31 @@ if (typeof PDFJS === 'undefined') {
|
|||
PDFJS.maxCanvasPixels = 5242880;
|
||||
}
|
||||
})();
|
||||
|
||||
// Disable fullscreen support for certain problematic configurations.
|
||||
// Support: IE11+ (when embedded).
|
||||
(function checkFullscreenSupport() {
|
||||
var isEmbeddedIE = (navigator.userAgent.indexOf('Trident') >= 0 &&
|
||||
window.parent !== window);
|
||||
if (isEmbeddedIE) {
|
||||
PDFJS.disableFullscreen = true;
|
||||
}
|
||||
})();
|
||||
|
||||
// Provides document.currentScript support
|
||||
// Support: IE, Chrome<29.
|
||||
(function checkCurrentScript() {
|
||||
if ('currentScript' in document) {
|
||||
return;
|
||||
}
|
||||
Object.defineProperty(document, 'currentScript', {
|
||||
get: function () {
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
return scripts[scripts.length - 1];
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
})();
|
||||
|
||||
}).call((typeof window === 'undefined') ? this : window);
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue