const ControlledFrameImpl = require('controlledFrameImpl').ControlledFrameImpl;
const forwardApiMethods =
require('guestViewContainerElement').forwardApiMethods;
const upgradeMethodsToPromises =
require('guestViewContainerElement').upgradeMethodsToPromises;
const ChromeWebViewImpl = require('chromeWebView').ChromeWebViewImpl;
const CONTROLLED_FRAME_API_METHODS =
require('controlledFrameApiMethods').CONTROLLED_FRAME_API_METHODS;
const CONTROLLED_FRAME_DELETED_API_METHODS =
require('controlledFrameApiMethods').CONTROLLED_FRAME_DELETED_API_METHODS;
const CONTROLLED_FRAME_PROMISE_API_METHODS =
require('controlledFrameApiMethods').CONTROLLED_FRAME_PROMISE_API_METHODS;
const convertURLPatternsToMatchPatterns =
require('controlledFrameURLPatternsHelper')
.convertURLPatternsToMatchPatterns;
const registerElement = require('guestViewContainerElement').registerElement;
const WebViewAttributeNames = require('webViewConstants').WebViewAttributeNames;
const WebViewElement = require('webViewElement').WebViewElement;
const WebViewInternal = getInternalApi('webViewInternal');
function convertRunAt(webRunAt) {
if (['document_start', 'document_end', 'document_idle'].includes(webRunAt)) {
throw new Error(
'Encountered incorrect naming, please see specification ' +
'text for correct naming.');
}
if (webRunAt === 'document-start') {
return 'document_start';
} else if (webRunAt === 'document-end') {
return 'document_end';
} else if (webRunAt === 'document-idle') {
return 'document_idle';
}
return webRunAt;
}
function convertContentScriptDetailsKeys(webViewRule, keyMappings) {
for (const mapping of keyMappings) {
if (!('from' in mapping)) {
throw new Error('\'from\' is required');
}
if (!('to' in mapping)) {
throw new Error('\'to\' is required');
}
if (mapping.to in webViewRule) {
throw new Error(
'Encountered incorrect naming, please see specification ' +
'text for correct naming.');
}
if (mapping.from in webViewRule) {
webViewRule[mapping.to] = webViewRule[mapping.from];
delete webViewRule[mapping.from];
}
}
return webViewRule;
}
function convertFromWebNaming(webRules) {
const webViewRules = [];
for (const webRule of webRules) {
if ('runAt' in webRule) {
webRule.runAt = convertRunAt(webRule.runAt);
}
let webViewRule = webRule;
delete webViewRule['include_globs'];
delete webViewRule['exclude_globs'];
webViewRule = convertContentScriptDetailsKeys(webViewRule, [
{from: 'allFrames', to: 'all_frames'},
{from: 'excludeURLPatterns', to: 'exclude_matches'},
{from: 'matchAboutBlank', to: 'match_about_blank'},
{from: 'runAt', to: 'run_at'},
{from: 'urlPatterns', to: 'matches'},
]);
webViewRule.matches =
convertURLPatternsToMatchPatterns(webViewRule.matches);
webViewRule.exclude_matches =
convertURLPatternsToMatchPatterns(webViewRule.exclude_matches);
webViewRules.push(webViewRule);
}
return webViewRules;
}
class HTMLControlledFrameElement extends WebViewElement {
static get observedAttributes() {
return WebViewAttributeNames;
}
constructor() {
super();
privates(this).internal = new ControlledFrameImpl(this);
privates(this).originalGo = originalGo;
}
addContentScripts(rules, callback) {
const internal = privates(this).internal;
const webViewRules = convertFromWebNaming(rules);
return WebViewInternal.addContentScripts(
internal.viewInstanceId, webViewRules, callback);
}
removeContentScripts(names, callback) {
const internal = privates(this).internal;
return WebViewInternal.removeContentScripts(
internal.viewInstanceId, names, callback);
}
canGoBack() {
return $Promise.resolve(super.canGoBack());
}
canGoForward() {
return $Promise.resolve(super.canGoForward());
}
}
forwardApiMethods(
HTMLControlledFrameElement, ControlledFrameImpl, WebViewInternal,
CONTROLLED_FRAME_API_METHODS, CONTROLLED_FRAME_PROMISE_API_METHODS);
const originalGo = HTMLControlledFrameElement.prototype.go;
upgradeMethodsToPromises(
HTMLControlledFrameElement, ControlledFrameImpl, WebViewInternal,
CONTROLLED_FRAME_PROMISE_API_METHODS);
(function() {
for (const methodName of CONTROLLED_FRAME_DELETED_API_METHODS) {
let clazz = HTMLControlledFrameElement.prototype;
while ((methodName in clazz) && clazz.constructor.name !== 'HTMLElement') {
delete clazz[methodName];
clazz = $Object.getPrototypeOf(clazz);
}
}
})();
registerElement(
'ControlledFrame', 'HTMLControlledFrameElement',
HTMLControlledFrameElement);