Commit df5b0824 authored by Robert Hodan's avatar Robert Hodan Committed by Juan Corona

Add initial support for sub-frame injection

parent 2c4d883e
...@@ -20,6 +20,7 @@ if (window.wgxpath) { ...@@ -20,6 +20,7 @@ if (window.wgxpath) {
var $ = require('jquery'); var $ = require('jquery');
// Applications // Applications
var Guest = require('./guest');
var Sidebar = require('./sidebar'); var Sidebar = require('./sidebar');
var PdfSidebar = require('./pdf-sidebar'); var PdfSidebar = require('./pdf-sidebar');
...@@ -46,6 +47,8 @@ $.noConflict(true)(function() { ...@@ -46,6 +47,8 @@ $.noConflict(true)(function() {
Sidebar; Sidebar;
if (config.hasOwnProperty('constructor')) { if (config.hasOwnProperty('constructor')) {
Klass = config.constructor; Klass = config.constructor;
if (Klass === "Guest") Klass = Guest;
delete config.constructor; delete config.constructor;
} }
......
...@@ -3,6 +3,7 @@ Plugin = require('../plugin') ...@@ -3,6 +3,7 @@ Plugin = require('../plugin')
AnnotationSync = require('../annotation-sync') AnnotationSync = require('../annotation-sync')
Bridge = require('../../shared/bridge') Bridge = require('../../shared/bridge')
Discovery = require('../../shared/discovery') Discovery = require('../../shared/discovery')
frameUtil = require('../util/frame-util')
# Extracts individual keys from an object and returns a new one. # Extracts individual keys from an object and returns a new one.
...@@ -33,6 +34,11 @@ module.exports = class CrossFrame extends Plugin ...@@ -33,6 +34,11 @@ module.exports = class CrossFrame extends Plugin
bridge.createChannel(source, origin, token) bridge.createChannel(source, origin, token)
discovery.startDiscovery(onDiscoveryCallback) discovery.startDiscovery(onDiscoveryCallback)
# THESIS TODO: Disabled until fully implemented.
#
# Find, and inject Hypothesis into Guest's iframes
# _discoverOwnFrames()
this.destroy = -> this.destroy = ->
# super doesnt work here :( # super doesnt work here :(
Plugin::destroy.apply(this, arguments) Plugin::destroy.apply(this, arguments)
...@@ -50,3 +56,20 @@ module.exports = class CrossFrame extends Plugin ...@@ -50,3 +56,20 @@ module.exports = class CrossFrame extends Plugin
this.onConnect = (fn) -> this.onConnect = (fn) ->
bridge.onConnect(fn) bridge.onConnect(fn)
_discoverOwnFrames = () ->
# Discover existing iframes
iframes = frameUtil.findIFrames(elem)
_handleIFrames(iframes)
_handleIFrame = (iframe) ->
if !frameUtil.isAccessible(iframe) then return
if !frameUtil.hasHypothesis(iframe)
frameUtil.injectHypothesis(iframe)
_handleIFrames = (iframes) ->
for own index, iframe of iframes
_handleIFrame(iframe)
'use strict';
// THESIS TODO: Once this module is finalized (more or less), then make
// sure to remove JQuery and refactor.
var $ = require('jquery');
module.exports = {
findIFrames,
hasHypothesis,
injectHypothesis,
isAccessible,
isValid,
};
// Find all iframes within this iframe only
function findIFrames(iframe) {
var iframes = [];
$('iframe', iframe).each(function(index, iframe) {
if ( isValid(iframe) ) {
iframes.push(iframe);
}
});
return iframes;
}
// Check if the iframe has already been injected
function hasHypothesis(iframe) {
// THESIS TODO: Are there better identifiers to use?
var scripts = {
src: [
'/hypothesis',
'/embed.js',
]
};
var frameBody = iframe.ownerDocument.body;
var childNodes = frameBody.childNodes;
var hasHypothesis = false;
for (var i = 0; i < childNodes.length-1; i++) {
var node = childNodes[i];
if (node.tagName !== 'SCRIPT') continue; // Skip to next increment
for (var j = 0; j < scripts.src.length-1; j++) {
var src = scripts.src[j];
if (node.src.includes(src)) {
hasHypothesis = true;
return; // Found our answer, stop looping.
}
}
}
return hasHypothesis;
}
// Inject embed.js into the iframe
function injectHypothesis(iframe, i) {
if (!iframe) return;
var iframes;
// Support arrays via recursion
if (iframe.constructor === Array) {
if (!iframe.length) return;
iframes = iframe;
i = (i != undefined) ? i : 0; // if set, use i. Otherwise, use 0
iframe = iframes[i];
}
var config = document.createElement('script');
config.className = "js-hypothesis-config";
config.type = "application/json";
config.innerText = ' {"constructor": "Guest" }';
// THESIS TODO: Temporarily hardcoded
var src = 'http://localhost:3001/hypothesis';
var embed = document.createElement('script');
embed.async = true;
embed.src = src;
iframe.contentDocument.body.appendChild(config);
iframe.contentDocument.body.appendChild(embed);
if (iframes && i < iframes.length-1) {
this._injectHypothesis(iframes, ++i);
}
}
// Check if we can access this iframe's document
function isAccessible(iframe) {
try {
iframe.contentDocument;
return true;
} catch (e) {
return false;
}
}
// Check if this is an iframe that we want to inject embed.js into
function isValid(iframe) {
// Currently only checks if it's not the h-sidebar
return (iframe.className !== 'h-sidebar-iframe');
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment