Workaround for document.body.scrollWidth being incorrect on Safari

This commit is contained in:
Kovid Goyal 2017-05-28 00:10:16 +05:30
parent 6f384dd00a
commit 9d1075e761
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 18 additions and 12 deletions

View File

@ -83,10 +83,11 @@ if is_ios:
raw = document.documentElement.style.transform raw = document.documentElement.style.transform
if not raw or raw is 'none': if not raw or raw is 'none':
return 0 return 0
raw = raw[12:] raw = raw[raw.indexOf('(') + 1:]
ans = parseInt(raw) ans = parseInt(raw)
if isNaN(ans): if isNaN(ans):
return 0 return 0
ans *= -1
return ans return ans
paged_viewport_scroll_into_view = def(elem): paged_viewport_scroll_into_view = def(elem):
left = elem.offsetLeft left = elem.offsetLeft
@ -102,6 +103,8 @@ if is_ios:
paged_viewport_scroll_to(max(0, left), 0) paged_viewport_scroll_to(max(0, left), 0)
paged_reset_globals = def(): paged_reset_globals = def():
document.documentElement.style.transform = 'none' document.documentElement.style.transform = 'none'
paged_content_width = def():
return document.documentElement.scrollWidth
else: else:
window_width = def(): window_width = def():
@ -112,9 +115,12 @@ else:
paged_viewport_x = flow_viewport_x paged_viewport_x = flow_viewport_x
paged_viewport_scroll_into_view = flow_viewport_scroll_into_view paged_viewport_scroll_into_view = flow_viewport_scroll_into_view
paged_reset_globals = flow_reset_globals paged_reset_globals = flow_reset_globals
paged_content_width = def():
return document.documentElement.scrollWidth
scroll_viewport.width = window_width scroll_viewport.width = window_width
scroll_viewport.height = window_height scroll_viewport.height = window_height
scroll_viewport.paged_content_width = paged_content_width
def current_layout_mode(): def current_layout_mode():

View File

@ -60,7 +60,7 @@ def reset_paged_mode_globals():
def column_at(xpos): def column_at(xpos):
# Return the (zero-based) number of the column that contains xpos # Return the (zero-based) number of the column that contains xpos
sw = document.body.scrollWidth sw = scroll_viewport.paged_content_width()
if xpos >= sw - col_and_gap: if xpos >= sw - col_and_gap:
xpos = sw - col_width + 10 xpos = sw - col_width + 10
return (xpos + gap) // col_and_gap return (xpos + gap) // col_and_gap
@ -190,7 +190,7 @@ def layout(is_single_page):
# width 100% are wider than body and lead to a blank page after the # width 100% are wider than body and lead to a blank page after the
# current page (when cols_per_screen == 1). Similarly img elements # current page (when cols_per_screen == 1). Similarly img elements
# with height=100% overflow the first column # with height=100% overflow the first column
is_full_screen_layout = (only_img or has_svg) and single_screen and (document.body.scrollWidth < 2*ww + 10) is_full_screen_layout = (only_img or has_svg) and single_screen and (scroll_viewport.paged_content_width() < 2*ww + 10)
if is_single_page: if is_single_page:
is_full_screen_layout = True is_full_screen_layout = True
@ -204,11 +204,11 @@ def layout(is_single_page):
# themselves, unless the container width is an exact multiple, so we check # themselves, unless the container width is an exact multiple, so we check
# for that and manually set the container widths. # for that and manually set the container widths.
def check_column_widths(): def check_column_widths():
ncols = (document.body.scrollWidth + gap) / col_and_gap ncols = (scroll_viewport.paged_content_width() + gap) / col_and_gap
if ncols is not Math.floor(ncols): if ncols is not Math.floor(ncols):
n = Math.floor(ncols) n = Math.floor(ncols)
dw = n*col_width + (n-1)*gap dw = n*col_width + (n-1)*gap
data = {'col_width':col_width, 'gap':gap, 'scrollWidth':document.body.scrollWidth, 'ncols':ncols, 'desired_width':dw} data = {'col_width':col_width, 'gap':gap, 'scrollWidth':scroll_viewport.paged_content_width(), 'ncols':ncols, 'desired_width':dw}
return data return data
data = check_column_widths() data = check_column_widths()
if data: if data:
@ -233,7 +233,7 @@ def scroll_to_offset(x):
def scroll_to_column(number, notify=False, duration=1000): def scroll_to_column(number, notify=False, duration=1000):
pos = number * col_and_gap pos = number * col_and_gap
limit = document.body.scrollWidth - screen_width limit = scroll_viewport.paged_content_width() - screen_width
pos = min(pos, limit) pos = min(pos, limit)
scroll_to_offset(pos) scroll_to_offset(pos)
@ -250,7 +250,7 @@ def scroll_to_xpos(xpos, notify=False, duration=1000):
def scroll_to_fraction(frac): def scroll_to_fraction(frac):
# Scroll to the position represented by frac (number between 0 and 1) # Scroll to the position represented by frac (number between 0 and 1)
xpos = Math.floor(document.body.scrollWidth * frac) xpos = Math.floor(scroll_viewport.paged_content_width() * frac)
scroll_to_xpos(xpos) scroll_to_xpos(xpos)
@ -277,11 +277,11 @@ def next_screen_location():
ans = cc + screen_width ans = cc + screen_width
if cols_per_screen > 1: if cols_per_screen > 1:
current_col = column_at(current_scroll_offset() + 10) current_col = column_at(current_scroll_offset() + 10)
ncols = (document.body.scrollWidth + gap) // col_and_gap ncols = (scroll_viewport.paged_content_width() + gap) // col_and_gap
cols_left = ncols - (current_col + cols_per_screen) cols_left = ncols - (current_col + cols_per_screen)
if cols_left < cols_per_screen: if cols_left < cols_per_screen:
return -1 # Only blank, dummy pages left return -1 # Only blank, dummy pages left
limit = document.body.scrollWidth - scroll_viewport.width() limit = scroll_viewport.paged_content_width() - scroll_viewport.width()
if limit < col_and_gap: if limit < col_and_gap:
return -1 return -1
if ans > limit: if ans > limit:
@ -309,7 +309,7 @@ def next_col_location():
return -1 return -1
cc = current_column_location() cc = current_column_location()
ans = cc + col_and_gap ans = cc + col_and_gap
limit = document.body.scrollWidth - scroll_viewport.width() limit = scroll_viewport.paged_content_width() - scroll_viewport.width()
if ans > limit: if ans > limit:
ans = limit if current_scroll_offset() < limit else -1 ans = limit if current_scroll_offset() < limit else -1
return ans return ans
@ -396,7 +396,7 @@ def current_cfi():
# Try the current column, the previous column and the next # Try the current column, the previous column and the next
# column. Each column is tried from top to bottom. # column. Each column is tried from top to bottom.
left, right = x, x + col_and_gap left, right = x, x + col_and_gap
if left < 0 or right > document.body.scrollWidth: if left < 0 or right > scroll_viewport.paged_content_width():
continue continue
deltax = col_and_gap // 25 deltax = col_and_gap // 25
deltay = scroll_viewport.height() // 25 deltay = scroll_viewport.height() // 25
@ -423,7 +423,7 @@ def current_cfi():
def progress_frac(frac): def progress_frac(frac):
# The current scroll position as a fraction between 0 and 1 # The current scroll position as a fraction between 0 and 1
if in_paged_mode: if in_paged_mode:
limit = document.body.scrollWidth - scroll_viewport.width() limit = scroll_viewport.paged_content_width() - scroll_viewport.width()
if limit <= 0: if limit <= 0:
return 0.0 return 0.0
return current_scroll_offset() / limit return current_scroll_offset() / limit