2016-11-23 23:48:47 +11:00
|
|
|
/*
|
|
|
|
|
* Copyright 2016 Michael Gratton <mike@vee.net>
|
|
|
|
|
*
|
|
|
|
|
* This software is licensed under the GNU Lesser General Public License
|
|
|
|
|
* (version 2.1 or later). See the COPYING file in this distribution.
|
|
|
|
|
*/
|
|
|
|
|
|
2016-11-24 23:42:28 +11:00
|
|
|
/**
|
|
|
|
|
* Application logic for ClientWebView and subclasses.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-01-04 01:15:08 +11:00
|
|
|
let PageState = function() {
|
2016-11-25 22:00:06 +11:00
|
|
|
this.init.apply(this, arguments);
|
|
|
|
|
};
|
2016-11-25 16:30:50 +11:00
|
|
|
PageState.prototype = {
|
2016-11-25 22:00:06 +11:00
|
|
|
init: function() {
|
|
|
|
|
this.allowRemoteImages = false;
|
2017-01-17 23:40:40 +11:00
|
|
|
this.isLoaded = false;
|
2017-01-19 01:58:26 +11:00
|
|
|
this.hasSelection = false;
|
2017-01-24 19:30:12 +11:00
|
|
|
this.lastPreferredHeight = 0;
|
2016-11-25 22:00:06 +11:00
|
|
|
|
2017-01-04 01:15:08 +11:00
|
|
|
let state = this;
|
2017-01-24 19:30:12 +11:00
|
|
|
|
|
|
|
|
// Coalesce multiple calls to updatePreferredHeight using a
|
|
|
|
|
// timeout to avoid the overhead of multiple JS messages sent
|
|
|
|
|
// to the app and hence view multiple resizes being queued.
|
|
|
|
|
let queueTimeout = null;
|
|
|
|
|
let queuePreferredHeightUpdate = function() {
|
|
|
|
|
if (queueTimeout != null) {
|
|
|
|
|
clearTimeout(queueTimeout);
|
2016-11-25 22:00:06 +11:00
|
|
|
}
|
2017-01-24 19:30:12 +11:00
|
|
|
queueTimeout = setTimeout(
|
|
|
|
|
function() { state.updatePreferredHeight(); }, 10
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Queues an update after the DOM has been initially loaded
|
|
|
|
|
// and had any changes made to it by derived classes.
|
|
|
|
|
document.addEventListener("DOMContentLoaded", function(e) {
|
|
|
|
|
state.loaded();
|
|
|
|
|
queuePreferredHeightUpdate();
|
|
|
|
|
});
|
|
|
|
|
// Queues updates for not only the complete document, but also
|
|
|
|
|
// for any IMG elements loaded, hence handles resizing when
|
|
|
|
|
// the user later requests remote images loading.
|
|
|
|
|
//
|
|
|
|
|
// Note also that the delay introduced here by the last call
|
|
|
|
|
// to queuePreferredHeightUpdate when the complete document is
|
|
|
|
|
// loaded seems to be important to get an acurate idea of the
|
|
|
|
|
// final document size.
|
|
|
|
|
document.addEventListener("load", function(e) {
|
|
|
|
|
queuePreferredHeightUpdate();
|
|
|
|
|
}, true);
|
2016-11-25 22:00:06 +11:00
|
|
|
},
|
2017-01-04 01:10:38 +11:00
|
|
|
getPreferredHeight: function() {
|
2017-01-27 02:09:23 +11:00
|
|
|
let html = window.document.documentElement;
|
|
|
|
|
let height = html.offsetHeight;
|
|
|
|
|
let computed = window.getComputedStyle(html);
|
|
|
|
|
let top = computed.getPropertyValue('margin-top');
|
|
|
|
|
let bot = computed.getPropertyValue('margin-bottom');
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
height
|
|
|
|
|
+ parseInt(top.substring(0, top.length - 2))
|
|
|
|
|
+ parseInt(bot.substring(0, bot.length - 2))
|
|
|
|
|
);
|
2017-01-04 01:10:38 +11:00
|
|
|
},
|
2016-11-27 21:03:52 +11:00
|
|
|
loaded: function() {
|
2017-01-17 23:40:40 +11:00
|
|
|
this.isLoaded = true;
|
2016-11-27 21:03:52 +11:00
|
|
|
},
|
2016-11-25 16:30:50 +11:00
|
|
|
loadRemoteImages: function() {
|
|
|
|
|
this.allowRemoteImages = true;
|
2017-01-04 01:15:08 +11:00
|
|
|
let images = document.getElementsByTagName("IMG");
|
|
|
|
|
for (let i = 0; i < images.length; i++) {
|
|
|
|
|
let img = images.item(i);
|
|
|
|
|
let src = img.src;
|
2016-11-25 16:30:50 +11:00
|
|
|
img.src = "";
|
|
|
|
|
img.src = src;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
remoteImageLoadBlocked: function() {
|
|
|
|
|
window.webkit.messageHandlers.remoteImageLoadBlocked.postMessage(null);
|
2016-11-25 22:00:06 +11:00
|
|
|
},
|
2017-01-24 19:30:12 +11:00
|
|
|
/**
|
|
|
|
|
* Sends "preferredHeightChanged" message if it has changed.
|
|
|
|
|
*/
|
|
|
|
|
updatePreferredHeight: function() {
|
|
|
|
|
let updated = false;
|
2017-01-04 01:10:38 +11:00
|
|
|
let height = this.getPreferredHeight();
|
2017-01-24 19:30:12 +11:00
|
|
|
if (height > 0 && height != this.lastPreferredHeight) {
|
|
|
|
|
updated = true;
|
|
|
|
|
this.lastPreferredHeight = height;
|
2016-11-25 22:00:06 +11:00
|
|
|
window.webkit.messageHandlers.preferredHeightChanged.postMessage(
|
|
|
|
|
height
|
|
|
|
|
);
|
|
|
|
|
}
|
2017-01-24 19:30:12 +11:00
|
|
|
return updated;
|
2016-11-27 11:24:09 +11:00
|
|
|
},
|
|
|
|
|
selectionChanged: function() {
|
2017-01-17 23:40:40 +11:00
|
|
|
let hasSelection = !window.getSelection().isCollapsed;
|
2017-01-19 01:58:26 +11:00
|
|
|
if (this.hasSelection != hasSelection) {
|
|
|
|
|
this.hasSelection = hasSelection;
|
|
|
|
|
window.webkit.messageHandlers.selectionChanged.postMessage(hasSelection);
|
|
|
|
|
}
|
2016-11-25 16:30:50 +11:00
|
|
|
}
|
|
|
|
|
};
|