diff --git a/core/modules/savers/custom.js b/core/modules/savers/custom.js new file mode 100644 index 000000000..836691204 --- /dev/null +++ b/core/modules/savers/custom.js @@ -0,0 +1,60 @@ +/*\ +title: $:/core/modules/savers/custom.js +type: application/javascript +module-type: saver + +Looks for `window.$tw.customSaver` first on the current window, then +on the parent window (of an iframe). If present, the saver must define + save: function(text,method,callback) { ... } +and the saver may define + priority: number +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var findSaver = function(window) { + try { + return window && window.$tw && window.$tw.customSaver; + } catch (err) { + // Catching the exception is the most reliable way to detect cross-origin iframe errors. + // For example, instead of saying that `window.parent.$tw` is undefined, Firefox will throw + // Uncaught DOMException: Permission denied to access property "$tw" on cross-origin object + console.log({ msg: "custom saver is disabled", reason: err }); + return null; + } +} +var saver = findSaver(window) || findSaver(window.parent) || {}; + +var CustomSaver = function(wiki) { +}; + +CustomSaver.prototype.save = function(text,method,callback) { + return saver.save(text, method, callback); +}; + +/* +Information about this saver +*/ +CustomSaver.prototype.info = { + name: "custom", + priority: saver.priority || 4000, + capabilities: ["save","autosave"] +}; + +/* +Static method that returns true if this saver is capable of working +*/ +exports.canSave = function(wiki) { + return !!(saver.save); +}; + +/* +Create an instance of this saver +*/ +exports.create = function(wiki) { + return new CustomSaver(wiki); +}; +})(); diff --git a/licenses/cla-individual.md b/licenses/cla-individual.md index fb4430e2e..32fec886a 100644 --- a/licenses/cla-individual.md +++ b/licenses/cla-individual.md @@ -415,3 +415,5 @@ Kamal Habash, @Kamal-Habash, 2020/08/28 Florian Kohrt, @fkohrt, 2020/09/10 Gerald Liu, @gera2ld, 2020/09/25 + +Ryan Kramer, @default-kramer, 2020/10/24