Last active
January 3, 2022 23:36
-
-
Save sancarn/b974b650f4b451ff2de51861af1671b1 to your computer and use it in GitHub Desktop.
A test to attempt to listen to VBA changes to the customXMLParts structure.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: VBA-OfficeJS bridge test | |
description: A test to attempt to listen to VBA changes to the customXMLParts structure. | |
host: EXCEL | |
api_set: {} | |
script: | |
content: |+ | |
/* VBA USAGE EXAMPLE | |
'Example from VBA: | |
'Requires JsBridge from here: https://github.com/sancarn/VbaJsBridge | |
'ScriptLab test can be downloaded here: https://gist.github.com/sancarn/b974b650f4b451ff2de51861af1671b1 | |
Sub test() | |
Dim js As JsBridge: Set js = JsBridge.Create("test") | |
Call js.SendMessage("hello world") | |
End Sub | |
*/ | |
type IXMLWatcherListener = (value: string, e: IAction) => boolean; | |
type IAction = { | |
root: Excel.CustomXmlPart; | |
xml: OfficeExtension.ClientResult<string>; | |
doc: HTMLElement; | |
finish: () => void; | |
}; | |
class XMLWatcher { | |
private context: Excel.RequestContext; | |
private uid: string; | |
private interval: number; | |
private listeners: IXMLWatcherListener[]; | |
private running: boolean; | |
constructor(context: Excel.RequestContext, sUID: string, listener?: IXMLWatcherListener) { | |
this.context = context; | |
this.uid = sUID; | |
this.listeners = []; | |
if (listener) { | |
this.addListener(listener); | |
this.start(); | |
} | |
} | |
addListener(listener: IXMLWatcherListener) { | |
this.listeners.push(listener); | |
} | |
start() { | |
if (!this.running) { | |
//Poll for changes every half a second | |
this.interval = setInterval(async () => { | |
var elements = this.context.workbook.customXmlParts.getByNamespace(this.uid); | |
elements.load("values"); | |
await this.context.sync(); | |
//Get XML | |
let actions: IAction[] = elements.items.map((e) => ({ | |
root: e, | |
xml: e.getXml(), | |
doc: null, | |
finish: function() { | |
this.doc.setAttribute("finished", "true"); | |
this.root.setXml(this.doc.outerHTML); | |
} | |
})); | |
await this.context.sync(); | |
//Get actions as xmlDocs | |
let parser = new DOMParser(); | |
actions.forEach((blob) => (blob.doc = parser.parseFromString(blob.xml.value, "text/xml").documentElement)); | |
let jsActions = actions.filter( | |
(action) => action.doc.attributes["for"].value == "js" && action.doc.attributes["handled"].value == "false" | |
); | |
//Call listeners | |
for (let action of jsActions) { | |
for (let listener of this.listeners) { | |
if (listener(action.doc.innerHTML, action)) { | |
action.doc.setAttribute("handled", "true"); | |
action.root.setXml(action.doc.outerHTML); | |
break; | |
} | |
} | |
} | |
}, 500); | |
} | |
} | |
stop() { | |
if (this.running) { | |
clearInterval(this.interval); | |
} | |
} | |
} | |
document.getElementById("run").addEventListener("click",run); | |
let watcher: XMLWatcher; | |
async function run() { | |
await Excel.run(async (context) => { | |
watcher = new XMLWatcher(context, "test", function(value, action) { | |
console.log(value); | |
action.finish(); | |
return true; | |
}); | |
}); | |
} | |
language: typescript | |
template: | |
content: | | |
<button id="run" class="ms-Button"> | |
<span class="ms-Button-label">Run</span> | |
</button> | |
language: html | |
style: | |
content: |- | |
section.samples { | |
margin-top: 20px; | |
} | |
section.samples .ms-Button, section.setup .ms-Button { | |
display: block; | |
margin-bottom: 5px; | |
margin-left: 20px; | |
min-width: 80px; | |
} | |
language: css | |
libraries: | | |
https://appsforoffice.microsoft.com/lib/1/hosted/office.js | |
@types/office-js | |
[email protected]/dist/css/fabric.min.css | |
[email protected]/dist/css/fabric.components.min.css | |
[email protected]/client/core.min.js | |
@types/core-js | |
[email protected] | |
@types/[email protected] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment