Page MenuHomePhorge

D25577.1731132022.diff
No OneTemporary

D25577.1731132022.diff

diff --git a/.arcconfig b/.arcconfig
new file mode 100644
--- /dev/null
+++ b/.arcconfig
@@ -0,0 +1,6 @@
+{
+ "phabricator.uri": "https://we.phorge.it/",
+ "load": [
+ "src/"
+ ]
+}
diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,2 @@
-/data/drawio
-
-/src/__phutil_library_init__.php
-/src/__phutil_library_map__.php
+/drawio
/src/.phutil_module_cache
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,12 +3,19 @@
Installation
============
-1) Extract the content of this repository into <phorge>/src/extensions
-2) <arcanist>/bin/arc liberate
-3) <phorge>/bin/storage upgrade
-4) CD to <phorge>/src/extensions/drawio/data
-5) git clone https://github.com/jgraph/drawio.git
-6) Diagrams application is available under "More Applications" in Phorge.
+1) `git clone` this repository somewhere safe: `</somewhere/safe/diagrams>`
+2) CD to `</somewhere/safe/diagrams>` and `git clone https://github.com/jgraph/drawio.git && cd drawio && git switch v24.2.5`
+3) `<phorge>/bin/storage upgrade`
+4) In Phorge's `conf/local/local.json` add the path to the `src/` dir to the entry `load-libraries`,
+ something like this:
+```
+ ...
+ "load-libraries": [
+ "/somewhere/safe/diagrams/src/"
+ ],
+ ...
+```
+5) Diagrams application is available under "More Applications" in Phorge.
You may add it to your navigator menu via "Edit Menu"
Usage
diff --git a/data/iframe.css b/data/iframe.css
deleted file mode 100644
--- a/data/iframe.css
+++ /dev/null
@@ -1,97 +0,0 @@
-body { overflow:hidden; }
-div.picker { z-index: 10007; }
-.geSidebarContainer .geTitle input {
- font-size:8pt;
- color:#606060;
-}
-.geBlock {
- z-index:-3;
- margin:100px;
- margin-top:40px;
- margin-bottom:30px;
- padding:20px;
- text-align:center;
- min-width:50%;
-}
-.geBlock h1, .geBlock h2 {
- margin-top:0px;
- padding-top:0px;
-}
-.geEditor *:not(.geScrollable)::-webkit-scrollbar {
- width:10px;
- height:10px;
-}
-.geEditor ::-webkit-scrollbar-track {
- background-clip:padding-box;
- border:solid transparent;
- border-width:1px;
-}
-.geEditor ::-webkit-scrollbar-corner {
- background-color:transparent;
-}
-.geEditor ::-webkit-scrollbar-thumb {
- background-color:rgba(0,0,0,.1);
- background-clip:padding-box;
- border:solid transparent;
- border-radius:10px;
-}
-.geEditor ::-webkit-scrollbar-thumb:hover {
- background-color:rgba(0,0,0,.4);
-}
-.geTemplate {
- border:1px solid transparent;
- display:inline-block;
- _display:inline;
- vertical-align:top;
- border-radius:3px;
- overflow:hidden;
- font-size:14pt;
- cursor:pointer;
- margin:5px;
-}
-
-@keyframes init-spinner-animation {
- 0%, 39%, 100% {
- opacity: 0.33;
- }
- 40% {
- opacity: .83;
- }
-}
-.init-spinner {
- position: relative;
- height: 80px;
- width: 80px;
- left: calc(50% - 50px);
-}
-.init-spinner .content {
- position: absolute;
- width: 0px;
- left: 50%;
- top: 50%;
-}
-
-.init-spinner .content .spike {
- position: absolute;
- top: -2.5px;
- width: 15px;
- height: 5px;
- background: #000c;
- border-radius: 2.5px;
- transform-origin: left center 0px;
-}
-
-.init-spinner .content .spike .animator {
- width: 100%;
- height: 100%;
- background: rgb(255, 255, 255);
- border-radius: 2.5px;
- box-shadow: transparent 0px 0px 1px;
- animation-name: init-spinner-animation;
- animation-duration: 1s;
- animation-timing-function: linear;
- animation-iteration-count: infinite;
- animation-direction: normal;
- animation-fill-mode: none;
- animation-play-state: running;
-}
\ No newline at end of file
diff --git a/data/iframe1.js b/data/iframe1.js
deleted file mode 100644
--- a/data/iframe1.js
+++ /dev/null
@@ -1,144 +0,0 @@
-var urlParams = (function() {
- var result = {};
- var params = window.location.search.slice(1).split('&');
-
- for (var i = 0; i < params.length; i++) {
- var idx = params[i].indexOf('=');
-
- if (idx > 0) {
- result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
- }
- }
-
- return result;
-})();
-
-if (window.location.hash != null && window.location.hash.substring(0, 2) == '#P') {
- try {
- urlParams = JSON.parse(decodeURIComponent(window.location.hash.substring(2)));
-
- if (urlParams.hash != null) {
- window.location.hash = urlParams.hash;
- }
- }
- catch (e) {
- }
-}
-
-(function() {
- var proto = window.location.protocol;
- var host = window.location.host;
- var href = proto + '//' + host + window.location.href.substring(
- window.location.protocol.length +
- window.location.host.length + 2);
-
- if (href != window.location.href) {
- window.location.href = href;
- }
-})();
-
-function mxmeta(name, content, httpEquiv) {
- try {
- var s = document.createElement('meta');
-
- if (name != null) {
- s.setAttribute('name', name);
- }
-
- s.setAttribute('content', content);
-
- if (httpEquiv != null) {
- s.setAttribute('http-equiv', httpEquiv);
- }
-
- var t = document.getElementsByTagName('meta')[0];
- t.parentNode.insertBefore(s, t);
- }
- catch (e)
- {
- }
-}
-
-function mxscript(src, onLoad, id, dataAppKey, noWrite, onError) {
- var s = document.createElement('script');
- s.setAttribute('type', 'text/javascript');
- s.setAttribute('defer', 'true');
- s.setAttribute('src', src);
-
- if (id != null) {
- s.setAttribute('id', id);
- }
-
- if (dataAppKey != null) {
- s.setAttribute('data-app-key', dataAppKey);
- }
-
- if (onLoad != null) {
- var r = false;
-
- s.onload = s.onreadystatechange = function() {
- if (!r && (!this.readyState || this.readyState == 'complete')) {
- r = true;
- onLoad();
- }
- };
- }
-
- if (onError != null) {
- s.onerror = function(e) {
- onError('Failed to load ' + src, e);
- };
- }
-
- var t = document.getElementsByTagName('script')[0];
-
- if (t != null) {
- t.parentNode.insertBefore(s, t);
- }
-}
-
-function mxinclude(src) {
- var g = document.createElement('script');
- g.type = 'text/javascript';
- g.async = true;
- g.src = src;
-
- var s = document.getElementsByTagName('script')[0];
- s.parentNode.insertBefore(g, s);
-}
-
-(function() {
- var name = 'diagrams.net';
- mxmeta('apple-mobile-web-app-title', name);
- mxmeta('application-name', name);
-})();
-
-var isLocalStorage = true;
-var mxScriptsLoaded = false, mxWinLoaded = false;
-
-function checkAllLoaded() {
- if (mxScriptsLoaded && mxWinLoaded) {
- App.main();
- }
-}
-
-var t0 = new Date();
- (function() {
- function loadAppJS() {
- mxscript('js/app.min.js', function() {
- mxScriptsLoaded = true;
- checkAllLoaded();
- mxscript('js/PostConfig.js');
- });
- }
-
- mxscript('js/PreConfig.js', loadAppJS);
-})();
-
-window.onerror = function() {
- var status = document.getElementById('geStatus');
-
- if (status != null) {
- status.innerHTML = 'Page could not be loaded. Please try refreshing.';
- }
-};
diff --git a/data/iframe2.js b/data/iframe2.js
deleted file mode 100644
--- a/data/iframe2.js
+++ /dev/null
@@ -1,7 +0,0 @@
-window.addEventListener('load', function()
-{
- mxWinLoaded = true;
- checkAllLoaded();
-});
-
-phorge_extension = parent.phorge_extension;
\ No newline at end of file
diff --git a/data/phorge_extension.js b/data/phorge_extension.js
deleted file mode 100644
--- a/data/phorge_extension.js
+++ /dev/null
@@ -1,246 +0,0 @@
-var phorge_extension = {};
-
-function edit(image) {
- var iframe = document.createElement('iframe');
- var iframeInitializedEvent = new CustomEvent('initReceived');
- iframe.setAttribute('title', 'diagrams.net editor');
- iframe.setAttribute('frameborder', '0');
- iframe.style.width = '100%';
- iframe.style.height = 'calc(100vh - 91px)';
- iframe.style.marginTop = '30px';
- iframe.style.marginBottom = '-16px';
- image.style.display = 'none';
-
- var receive = function (evt) {
- if (evt.data.length > 0) {
- var msg = JSON.parse(evt.data);
- if (msg.event == 'init') {
- if (phorge_extension.diagramBase64) {
- image.src = 'data:image/png;base64,' + phorge_extension.diagramBase64;
-
- var diagramName = document.querySelector('.diagramName');
- diagramName.style.display = 'inline-block';
- diagramName.querySelector('a').innerText = phorge_extension.diagramName;
- if (phorge_extension.diagramVersion != '') {
- diagramName.querySelector('.version').innerText = '(#'
- + phorge_extension.diagramVersion
- + ')';
- }
- }
-
- iframe.contentWindow.postMessage(JSON.stringify({
- action: 'load',
- autosave: 1,
- xmlpng: image.getAttribute('src')
- }), '*');
- }
- else if (msg.event == 'load') {
- // enable Mathematical Typesettings by default
- iframe.contentWindow.sb.editorUi.setMathEnabled(true);
-
- setupButtonsInMenuToolbar();
- }
- else if (msg.event == 'export') {
- saveFlowchart(name, msg.data, iframe);
- }
- else if (msg.event == 'save') {
- iframe.contentWindow.postMessage(JSON.stringify({
- action: 'export',
- format: 'xmlpng',
- xml: msg.xml,
- spin: 'Updating page'
- }), '*');
- }
- }
- };
-
- window.addEventListener('message', receive);
- iframe.setAttribute('src', phorge_extension.editor);
- document.querySelector('#mainScreen').appendChild(iframe);
- iframe.dispatchEvent(iframeInitializedEvent);
-
- iframe.contentWindow.RESOURCES_PATH = document.baseURI + 'iframe/resources';
- iframe.contentWindow.STENCIL_PATH = document.baseURI + 'iframe/stencils';
- iframe.contentWindow.IMAGE_PATH = document.baseURI + 'iframe/images';
- iframe.contentWindow.STYLE_PATH = document.baseURI + 'iframe/styles';
- iframe.contentWindow.CSS_PATH = document.baseURI + 'iframe/styles';
-}
-
-function loadJsExtension(diagramName, diagramPHID, diagramVersion, diagramBase64) {
- var baseURI = document.baseURI;
- if (diagramName != '' && diagramBase64 != '') {
- baseURI = baseURI.substr(0, baseURI.length - diagramName.length - 1);
-
- if (diagramVersion != '') {
- baseURI = baseURI.substr(0, baseURI.length - diagramVersion.length - 1);
- }
- }
- phorge_extension.baseURI = baseURI;
- phorge_extension.csrf = document.querySelector('input[name="__csrf__"]')?.value;
- phorge_extension.editor = baseURI + '/iframe/?embed=1&spin=0&proto=json&noExitBtn=1';
- phorge_extension.name = null;
- phorge_extension.editor += '&lang=en';
- phorge_extension.editor += '&ui=min';
- phorge_extension.diagramPHID = diagramPHID;
- phorge_extension.diagramName = diagramName;
- phorge_extension.diagramVersion = diagramVersion;
- phorge_extension.diagramBase64 = diagramBase64;
-
- document.addEventListener('DOMContentLoaded', function () {
- edit(document.querySelector('img.drawio'));
- }, false);
-}
-
-function saveFlowchart(name, flowchartData, iframe) {
- var diagramID = document.querySelector('.diagramName a').innerText.replace(/^DIAG/, '');
- var csrf = document.querySelector('input[name="__csrf__"]')?.value;
- var data = new URLSearchParams();
- data.append('data', flowchartData);
- data.append('diagramID', diagramID);
- data.append('__csrf__', csrf);
- data.append('__form__', '1');
- data.append('__ajax__', 'true');
-
- var xmlhttp = new XMLHttpRequest();
- xmlhttp.overrideMimeType('application/json');
- xmlhttp.open('POST', 'save/', true);
- xmlhttp.onload = function () {
- if (xmlhttp.readyState == 4) {
- var errorMessage = null;
- try {
- var result = JSON.parse(xmlhttp.responseText);
- if (result.Status != 'OK') {
- errorMessage = result.Error;
- } else {
- // make sure we don't show messagebox about redirection in browser
- iframe.parentNode.removeChild(iframe);
-
- if (!phorge_extension.diagramVersion || !phorge_extension.diagramVersion.trim()) {
- if (!phorge_extension.diagramName || !phorge_extension.diagramName.trim()) {
- // load new diagram
- window.location = window.location + '/DIAG' + result.DiagramID;
- } else {
- // reload actual page (so versioned diagrams info is also updated)
- window.location.reload();
- }
- } else {
- // cut off version id from url
- var url = document.baseURI
- .substring(0,
- document.baseURI
- .length
- - phorge_extension.diagramVersion
- .length
- - 1
- );
- // redirect to latest version of diagram
- window.location = url;
- }
- }
- } catch (exc) {
- errorMessage = exc.message;
- }
- }
- };
-
- xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;');
- xmlhttp.send(data);
-}
-
-function setupButtonsInMenuToolbar() {
- var iframe = document.querySelector('iframe');
- var btnSave = Array.prototype.slice.call(
- iframe.contentDocument
- .querySelector('.geMenubarContainer')
- .querySelectorAll('button'), 0
- ).reverse()[0];
-
- // identify Exit Button
- btnSave.classList.add('btnSave');
-
- // change layout settings of area where btnSave belongs to so
- // that the dropdown menu is not hidden under the drawing area
- btnSave.parentNode.style.position = 'fixed';
-
- // create extra controls
- var subscribeUnsubscribe = setupSubscriptionButtonInMenuToolbar(iframe, btnSave);
- var dropdown = setupVersionDropDownInMenuToolbar(iframe, subscribeUnsubscribe);
-
- // initialize toolbuttons
- for (var tb in phorge_extension.toolbtn) {
- if (phorge_extension.toolbtn.hasOwnProperty(tb)) {
- phorge_extension.toolbtn[tb].instance.initialize();
- }
- }
-}
-
-function setupVersionDropDownInMenuToolbar(iframe, btnLeft) {
- // generate 'Select Version' button
- // create the dropdown element
- const dropdown = document.createElement('div');
- dropdown.classList.add('toolbtn-version-dropdown');
-
- // create the dropdown toggle button
- const toggle = document.createElement('button');
- toggle.classList.add('toolbtn-version-dropdown-toggle');
- toggle.textContent = 'Select Version';
- toggle.title = 'View previous versions';
- dropdown.appendChild(toggle);
-
- const iframeContent = document.querySelector('iframe').contentDocument;
- const menubarContainer = iframeContent.querySelector('.geMenubarContainer');
-
- // create the dropdown menu
- const menu = document.createElement('div');
- menu.classList.add('toolbtn-version-dropdown-menu');
- menubarContainer.parentNode.insertBefore(menu, menubarContainer.nextSibling);
-
- // create the version list
- const versionList = document.createElement('ul');
- versionList.classList.add('toolbtn-version-list');
-
- menu.appendChild(versionList);
-
- // create the prev and next buttons
- const prevBtn = document.createElement('button');
- prevBtn.classList.add('toolbtn-version-prev-btn');
- prevBtn.textContent = '<';
-
- const nextBtn = document.createElement('button');
- nextBtn.classList.add('toolbtn-version-next-btn');
- nextBtn.textContent = '>';
-
- menu.appendChild(prevBtn);
- menu.appendChild(nextBtn);
-
- // place dropdown next to button on the left
- btnLeft.parentNode.insertBefore(dropdown, btnLeft.nextSibling);
-
- return dropdown;
-}
-
-function setupSubscriptionButtonInMenuToolbar(iframe, btnLeft) {
- // generate 'Subscribe/Unsubscribe' button
- // create grouping div element
- const div = document.createElement('div');
- div.classList.add('toolbtn-diagram-subscription');
-
- // create subscribe button
- const btnSubscribe = document.createElement('button');
- btnSubscribe.classList.add('subscribe');
- btnSubscribe.classList.add('eye');
- btnSubscribe.title = 'Subscribe';
- div.appendChild(btnSubscribe);
-
- // create unsubscribe button
- const btnUnsubscribe = document.createElement('button');
- btnUnsubscribe.classList.add('unsubscribe');
- btnUnsubscribe.classList.add('eye');
- btnUnsubscribe.title = 'Unsubscribe';
- div.appendChild(btnUnsubscribe);
-
- // place grouping next to button on the left
- btnLeft.parentNode.insertBefore(div, btnLeft.nextSibling);
-
- return div;
-}
\ No newline at end of file
diff --git a/rsrc/behavior-diagram-extension.js b/rsrc/behavior-diagram-extension.js
new file mode 100644
--- /dev/null
+++ b/rsrc/behavior-diagram-extension.js
@@ -0,0 +1,271 @@
+/**
+ * @provides javelin-behavior-diagram-extension
+ */
+
+JX.behavior('diagram-extension', function(config) {
+
+ var phorge_extension = {};
+
+ function createIframe() {
+ var iframe = document.createElement('iframe');
+ var iframeInitializedEvent = new CustomEvent('initReceived');
+ iframe.setAttribute('title', 'diagrams.net editor');
+ iframe.setAttribute('frameborder', '0');
+ iframe.style.width = '100%';
+ iframe.style.height = 'calc(100vh - 91px)';
+ iframe.style.marginTop = '30px';
+ iframe.style.marginBottom = '-16px';
+
+ var receive = function (evt) {
+ if (evt.data.length > 0) {
+ var msg = JSON.parse(evt.data);
+ if (msg.event == 'init') {
+ if (phorge_extension.diagramBase64) {
+
+ var diagramName = document.querySelector('.diagramName');
+ diagramName.style.display = 'inline-block';
+ diagramName.querySelector('a').innerText = phorge_extension.diagramName;
+ if (phorge_extension.diagramVersion != '') {
+ diagramName.querySelector('.version').innerText = '(#'
+ + phorge_extension.diagramVersion
+ + ')';
+ }
+ }
+
+ iframe.contentWindow.postMessage(JSON.stringify({
+ action: 'load',
+ autosave: 1,
+ xmlpng: 'data:image/png;base64,' + phorge_extension.diagramBase64
+ }), '*');
+ }
+ else if (msg.event == 'load') {
+ // enable Mathematical Typesettings by default
+ iframe.contentWindow.sb.editorUi.setMathEnabled(true);
+
+ setupButtonsInMenuToolbar();
+ }
+ else if (msg.event == 'export') {
+ saveFlowchart(name, msg.data, iframe);
+ }
+ else if (msg.event == 'save') {
+ iframe.contentWindow.postMessage(JSON.stringify({
+ action: 'export',
+ format: 'xmlpng',
+ xml: msg.xml,
+ spin: 'Updating page'
+ }), '*');
+ }
+ }
+ };
+
+ window.addEventListener('message', receive);
+ iframe.setAttribute('src', phorge_extension.editor);
+ document.querySelector('#mainScreen').appendChild(iframe);
+ iframe.contentWindow.addEventListener('DOMContentLoaded', addToolbarResourcesToIframe);
+ iframe.dispatchEvent(iframeInitializedEvent);
+
+ iframe.contentWindow.RESOURCES_PATH = document.baseURI + 'iframe/resources';
+ iframe.contentWindow.STENCIL_PATH = document.baseURI + 'iframe/stencils';
+ iframe.contentWindow.IMAGE_PATH = document.baseURI + 'iframe/images';
+ iframe.contentWindow.STYLE_PATH = document.baseURI + 'iframe/styles';
+ iframe.contentWindow.CSS_PATH = document.baseURI + 'iframe/styles';
+ }
+
+ function addToolbarResourcesToIframe() {
+ var head = this.document.getElementsByTagName('head')[0];
+
+ var script = this.document.createElement('script');
+ script.src = config.toolbarJs;
+ head.appendChild(script);
+
+ var styles = this.document.createElement('link');
+ styles.setAttribute('type', 'text/css');
+ styles.setAttribute('rel', 'stylesheet');
+ styles.setAttribute('href', config.toolbarCss);
+ head.appendChild(styles);
+ }
+
+ function init(diagramName, diagramPHID, diagramVersion, diagramBase64) {
+ var baseURI = document.baseURI;
+ if (diagramName != '' && diagramBase64 != '') {
+ baseURI = baseURI.substr(0, baseURI.length - diagramName.length - 1);
+
+ if (diagramVersion != '') {
+ baseURI = baseURI.substr(0, baseURI.length - diagramVersion.length - 1);
+ }
+ }
+ phorge_extension.baseURI = baseURI;
+ phorge_extension.csrf = document.querySelector('input[name="__csrf__"]')?.value;
+ phorge_extension.editor = baseURI + '/iframe/?embed=1&spin=0&proto=json&noExitBtn=1';
+ phorge_extension.name = null;
+ phorge_extension.editor += '&lang=en';
+ phorge_extension.editor += '&ui=min';
+ phorge_extension.diagramPHID = diagramPHID;
+ phorge_extension.diagramName = diagramName;
+ phorge_extension.diagramVersion = diagramVersion;
+ phorge_extension.diagramBase64 = diagramBase64;
+
+ createIframe();
+ }
+
+ function saveFlowchart(name, flowchartData, iframe) {
+ var diagramID = document.querySelector('.diagramName a').innerText.replace(/^DIAG/, '');
+ var csrf = document.querySelector('input[name="__csrf__"]')?.value;
+ var data = new URLSearchParams();
+ data.append('data', flowchartData);
+ data.append('diagramID', diagramID);
+ data.append('__csrf__', csrf);
+ data.append('__form__', '1');
+ data.append('__ajax__', 'true');
+
+ var xmlhttp = new XMLHttpRequest();
+ xmlhttp.overrideMimeType('application/json');
+ xmlhttp.open('POST', 'save/', true);
+ xmlhttp.onload = function () {
+ if (xmlhttp.readyState == 4) {
+ var errorMessage = null;
+ try {
+ var result = JSON.parse(xmlhttp.responseText);
+ if (result.Status != 'OK') {
+ errorMessage = result.Error;
+ } else {
+ // make sure we don't show messagebox about redirection in browser
+ iframe.parentNode.removeChild(iframe);
+
+ if (!phorge_extension.diagramVersion || !phorge_extension.diagramVersion.trim()) {
+ if (!phorge_extension.diagramName || !phorge_extension.diagramName.trim()) {
+ // load new diagram
+ window.location = window.location + '/DIAG' + result.DiagramID;
+ } else {
+ // reload actual page (so versioned diagrams info is also updated)
+ window.location.reload();
+ }
+ } else {
+ // cut off version id from url
+ var url = document.baseURI
+ .substring(0,
+ document.baseURI
+ .length
+ - phorge_extension.diagramVersion
+ .length
+ - 1
+ );
+ // redirect to latest version of diagram
+ window.location = url;
+ }
+ }
+ } catch (exc) {
+ errorMessage = exc.message;
+ }
+ }
+ };
+
+ xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;');
+ xmlhttp.send(data);
+ }
+
+ function setupButtonsInMenuToolbar() {
+ var iframe = document.querySelector('iframe');
+ var btnSave = Array.prototype.slice.call(
+ iframe.contentDocument
+ .querySelector('.geMenubarContainer')
+ .querySelectorAll('button'), 0
+ ).reverse()[0];
+
+ // identify Exit Button
+ btnSave.classList.add('btnSave');
+
+ // change layout settings of area where btnSave belongs to so
+ // that the dropdown menu is not hidden under the drawing area
+ btnSave.parentNode.style.position = 'fixed';
+
+ // create extra controls
+ var subscribeUnsubscribe = setupSubscriptionButtonInMenuToolbar(iframe, btnSave);
+ var dropdown = setupVersionDropDownInMenuToolbar(iframe, subscribeUnsubscribe);
+
+ // initialize toolbuttons
+ for (var tb in phorge_extension.toolbtn) {
+ if (phorge_extension.toolbtn.hasOwnProperty(tb)) {
+ phorge_extension.toolbtn[tb].instance.initialize();
+ }
+ }
+ }
+
+ function setupVersionDropDownInMenuToolbar(iframe, btnLeft) {
+ // generate 'Select Version' button
+ // create the dropdown element
+ const dropdown = document.createElement('div');
+ dropdown.classList.add('toolbtn-version-dropdown');
+
+ // create the dropdown toggle button
+ const toggle = document.createElement('button');
+ toggle.classList.add('toolbtn-version-dropdown-toggle');
+ toggle.textContent = 'Select Version';
+ toggle.title = 'View previous versions';
+ dropdown.appendChild(toggle);
+
+ const iframeContent = document.querySelector('iframe').contentDocument;
+ const menubarContainer = iframeContent.querySelector('.geMenubarContainer');
+
+ // create the dropdown menu
+ const menu = document.createElement('div');
+ menu.classList.add('toolbtn-version-dropdown-menu');
+ menubarContainer.parentNode.insertBefore(menu, menubarContainer.nextSibling);
+
+ // create the version list
+ const versionList = document.createElement('ul');
+ versionList.classList.add('toolbtn-version-list');
+
+ menu.appendChild(versionList);
+
+ // create the prev and next buttons
+ const prevBtn = document.createElement('button');
+ prevBtn.classList.add('toolbtn-version-prev-btn');
+ prevBtn.textContent = '<';
+
+ const nextBtn = document.createElement('button');
+ nextBtn.classList.add('toolbtn-version-next-btn');
+ nextBtn.textContent = '>';
+
+ menu.appendChild(prevBtn);
+ menu.appendChild(nextBtn);
+
+ // place dropdown next to button on the left
+ btnLeft.parentNode.insertBefore(dropdown, btnLeft.nextSibling);
+
+ return dropdown;
+ }
+
+ function setupSubscriptionButtonInMenuToolbar(iframe, btnLeft) {
+ // generate 'Subscribe/Unsubscribe' button
+ // create grouping div element
+ const div = document.createElement('div');
+ div.classList.add('toolbtn-diagram-subscription');
+
+ // create subscribe button
+ const btnSubscribe = document.createElement('button');
+ btnSubscribe.classList.add('subscribe');
+ btnSubscribe.classList.add('eye');
+ btnSubscribe.title = 'Subscribe';
+ div.appendChild(btnSubscribe);
+
+ // create unsubscribe button
+ const btnUnsubscribe = document.createElement('button');
+ btnUnsubscribe.classList.add('unsubscribe');
+ btnUnsubscribe.classList.add('eye');
+ btnUnsubscribe.title = 'Unsubscribe';
+ div.appendChild(btnUnsubscribe);
+
+ // place grouping next to button on the left
+ btnLeft.parentNode.insertBefore(div, btnLeft.nextSibling);
+
+ return div;
+ }
+
+ if (config.initParams) {
+ init.apply(undefined, config.initParams);
+ }
+
+ window.__diagram = phorge_extension;
+
+});
diff --git a/data/iframe-toolbtn.css b/rsrc/iframe-toolbtn.css
rename from data/iframe-toolbtn.css
rename to rsrc/iframe-toolbtn.css
--- a/data/iframe-toolbtn.css
+++ b/rsrc/iframe-toolbtn.css
@@ -1,4 +1,8 @@
-/* begin stylesheets for version toolbutton */
+/**
+ * @provides diagram-css-iframe-toolbtn
+ */
+
+/* begin stylesheets for version toolbutton */
.toolbtn-version-dropdown {
right: 0;
white-space: nowrap;
diff --git a/data/iframe-toolbtn.js b/rsrc/iframe-toolbtn.js
rename from data/iframe-toolbtn.js
rename to rsrc/iframe-toolbtn.js
--- a/data/iframe-toolbtn.js
+++ b/rsrc/iframe-toolbtn.js
@@ -1,8 +1,14 @@
+/**
+ * @provides diagram-js-iframe-toolbtn
+ */
+
/**
* global dicttionary containing all configuration of all installed toolbuttons
*/
const toolbtn = {};
+const phorge_extension = parent.__diagram;
+
/**
* Abstract parent class for creating ToolButtons
*/
@@ -15,7 +21,7 @@
toolbtn[name] = {};
toolbtn[name].instance = this;
- parent.phorge_extension.toolbtn = toolbtn;
+ phorge_extension.toolbtn = toolbtn;
}
initialize() {
@@ -248,4 +254,4 @@
* Initialization of all ToolButton classes
*/
new ToolButtonVersion('version');
-new ToolButtonSubscription('subscription');
\ No newline at end of file
+new ToolButtonSubscription('subscription');
diff --git a/rsrc/remarkup-image.css b/rsrc/remarkup-image.css
new file mode 100644
--- /dev/null
+++ b/rsrc/remarkup-image.css
@@ -0,0 +1,8 @@
+/**
+ * @provides diagram-remarkup-image-css
+ */
+
+.diagram-container > .diagram-content {
+ max-width: 100%;
+ cursor: pointer;
+}
diff --git a/rsrc/remarkup-image.js b/rsrc/remarkup-image.js
new file mode 100644
--- /dev/null
+++ b/rsrc/remarkup-image.js
@@ -0,0 +1,27 @@
+/**
+ * @provides diagram-remarkup-image-js
+ */
+
+JX.onload(function() {
+
+ var singleClickTimeout = null;
+
+ JX.Stratcom.listen(
+ 'click',
+ ['diagram-remarkup-image'],
+ function(evt) {
+ var detail = evt.getRawEvent().detail;
+
+ if (detail === 1) {
+ singleClickTimeout = window.setTimeout(function() {
+ window.open('/diagram/data/' + evt.getTarget().dataset.diagramVersion);
+ singleClickTimeout = null;
+ }, 300);
+ } else if (detail === 2) {
+ window.clearTimeout(singleClickTimeout);
+ window.open('/diagram/DIAG' + evt.getTarget().dataset.diagramId);
+ }
+ }
+ );
+
+});
diff --git a/src/__phutil_library_init__.php b/src/__phutil_library_init__.php
new file mode 100644
--- /dev/null
+++ b/src/__phutil_library_init__.php
@@ -0,0 +1,3 @@
+<?php
+
+phutil_register_library('diagram', __FILE__);
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
new file mode 100644
--- /dev/null
+++ b/src/__phutil_library_map__.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * This file is automatically generated. Use 'arc liberate' to rebuild it
+ *
+ * @generated
+ * @phutil-library-version 2
+ */
+phutil_register_library_map(array(
+ '__library_version__' => 2,
+ 'class' => array(
+ 'Diagram' => 'storage/Diagram.php',
+ 'DiagramApplication' => 'application/DiagramApplication.php',
+ 'DiagramCelerityResources' => 'celerity/DiagramCelerityResources.php',
+ 'DiagramContentTransaction' => 'xaction/DiagramContentTransaction.php',
+ 'DiagramController' => 'controller/DiagramController.php',
+ 'DiagramDAO' => 'storage/DiagramDAO.php',
+ 'DiagramPHIDType' => 'phid/DiagramPHIDType.php',
+ 'DiagramPatchList' => 'storage/patch/DiagramPatchList.php',
+ 'DiagramReplyHandler' => 'mail/DiagramReplyHandler.php',
+ 'DiagramSchemaSpec' => 'storage/DiagramSchemaSpec.php',
+ 'DiagramSearchConduitAPIMethod' => 'conduit/DiagramSearchConduitAPIMethod.php',
+ 'DiagramTransaction' => 'storage/DiagramTransaction.php',
+ 'DiagramTransactionEditor' => 'editor/DiagramTransactionEditor.php',
+ 'DiagramTransactionType' => 'xaction/DiagramTransactionType.php',
+ 'DiagramUploadConduitAPIMethod' => 'conduit/DiagramUploadConduitAPIMethod.php',
+ 'DiagramVersion' => 'storage/DiagramVersion.php',
+ 'PhabricatorDiagramQuery' => 'query/PhabricatorDiagramQuery.php',
+ 'PhabricatorDiagramTransactionQuery' => 'query/PhabricatorDiagramTransactionQuery.php',
+ 'PhabricatorDiagramVersionQuery' => 'query/PhabricatorDiagramVersionQuery.php',
+ 'PhabricatorRemarkupDiagramRule' => 'remarkup/PhabricatorRemarkupDiagramRule.php',
+ 'PlainHtmlWebpageResponse' => 'response/PlainHtmlWebpageResponse.php',
+ ),
+ 'function' => array(),
+ 'xmap' => array(
+ 'Diagram' => array(
+ 'DiagramDAO',
+ 'PhabricatorApplicationTransactionInterface',
+ 'PhabricatorDestructibleInterface',
+ 'PhabricatorPolicyInterface',
+ 'PhabricatorSubscribableInterface',
+ ),
+ 'DiagramApplication' => 'PhabricatorApplication',
+ 'DiagramCelerityResources' => 'CelerityResourcesOnDisk',
+ 'DiagramContentTransaction' => 'DiagramTransactionType',
+ 'DiagramController' => 'PhabricatorController',
+ 'DiagramDAO' => 'PhabricatorLiskDAO',
+ 'DiagramPHIDType' => 'PhabricatorPHIDType',
+ 'DiagramPatchList' => 'PhabricatorSQLPatchList',
+ 'DiagramReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
+ 'DiagramSchemaSpec' => 'PhabricatorConfigSchemaSpec',
+ 'DiagramSearchConduitAPIMethod' => 'ConduitAPIMethod',
+ 'DiagramTransaction' => 'PhabricatorModularTransaction',
+ 'DiagramTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'DiagramTransactionType' => 'PhabricatorModularTransactionType',
+ 'DiagramUploadConduitAPIMethod' => 'ConduitAPIMethod',
+ 'DiagramVersion' => array(
+ 'DiagramDAO',
+ 'PhabricatorDestructibleInterface',
+ 'PhabricatorPolicyInterface',
+ ),
+ 'PhabricatorDiagramQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhabricatorDiagramTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+ 'PhabricatorDiagramVersionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhabricatorRemarkupDiagramRule' => 'PhabricatorObjectRemarkupRule',
+ 'PlainHtmlWebpageResponse' => 'AphrontHTMLResponse',
+ ),
+));
diff --git a/src/application/DiagramApplication.php b/src/application/DiagramApplication.php
--- a/src/application/DiagramApplication.php
+++ b/src/application/DiagramApplication.php
@@ -35,33 +35,33 @@
// url to image data
"data/(?P<diagramphid>PHID-DGVN-[a-z0-9]{20})"
. "(?:/(?P<version>[^/]+))?"
- . "(?:/|\?|$).*"
+ . "(?:/|\?|$).*"
=> "DiagramController",
-
+
// version info requests
"version/DIAG(?P<versioninfodiagram>(\d+))"
. "/(?P<versioninfopage>(\d+))"
- . "(?:/|\?|$).*"
+ . "(?:/|\?|$).*"
=> "DiagramController",
-
+
// draw.io iframe urls
"(?:(?P<versioneddiagramid>DIAG(\d+))/(?P<version>\d+)/?)"
. "(?P<route>iframe)"
- . "(?:/|\?|$).*"
+ . "(?:/|\?|$).*"
=> "DiagramController",
-
+
// draw.io iframe urls
"(?:(?P<diagramid>DIAG(\d+))/?)?"
. "(?P<route>iframe)"
- . "(?:/|\?|$).*"
+ . "(?:/|\?|$).*"
=> "DiagramController",
-
+
// url with diagram id and version in it
"(?P<versioneddiagramid>DIAG(\d+))"
. "/(?P<version>\d+)"
- . "(?:/|\?|$).*"
+ . "(?:/|\?|$).*"
=> "DiagramController",
-
+
// url with diagram id in it
"(?P<diagramid>DIAG(\d+))"
. "(?:/|\?|$).*"
@@ -72,18 +72,10 @@
. "(?P<subscriptionphid>[^/]+)/"
=> 'DiagramController',
- // url for loading/initializing diagram content
- "(?P<route>loadJsExtension)/"
- . "(/?(?P<loadDiagramName>[^/]*))?"
- . "(/?(?P<loadDiagramPHID>[^/]*))?"
- . "(/?(?P<loadDiagramVersion>[^/]*))?"
- . ".*"
- => 'DiagramController',
-
// other urls
".*"
=> "DiagramController",
)
);
}
-}
\ No newline at end of file
+}
diff --git a/src/celerity/DiagramCelerityResources.php b/src/celerity/DiagramCelerityResources.php
new file mode 100644
--- /dev/null
+++ b/src/celerity/DiagramCelerityResources.php
@@ -0,0 +1,15 @@
+<?php
+
+final class DiagramCelerityResources extends CelerityResourcesOnDisk {
+ public function getName() {
+ return 'diagram-resources';
+ }
+
+ public function getPathToResources() {
+ return phutil_get_library_root('diagram').'/../rsrc';
+ }
+
+ public function getPathToMap() {
+ return phutil_get_library_root('diagram').'/celerity/map.php';
+ }
+}
diff --git a/src/celerity/map.php b/src/celerity/map.php
new file mode 100644
--- /dev/null
+++ b/src/celerity/map.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * This file is automatically generated. Use 'bin/celerity map' to rebuild it.
+ *
+ * @generated
+ */
+return array(
+ 'names' => array(
+ 'behavior-diagram-extension.js' => 'adc38334',
+ 'iframe-toolbtn.css' => '35ad6f49',
+ 'iframe-toolbtn.js' => '26d75a35',
+ 'remarkup-image.css' => '42b46bf1',
+ 'remarkup-image.js' => '64e7e9e1',
+ ),
+ 'symbols' => array(
+ 'diagram-css-iframe-toolbtn' => '35ad6f49',
+ 'diagram-js-iframe-toolbtn' => '26d75a35',
+ 'diagram-remarkup-image-css' => '42b46bf1',
+ 'diagram-remarkup-image-js' => '64e7e9e1',
+ 'javelin-behavior-diagram-extension' => 'adc38334',
+ ),
+ 'requires' => array(),
+ 'packages' => array(),
+);
diff --git a/src/controller/DiagramController.php b/src/controller/DiagramController.php
--- a/src/controller/DiagramController.php
+++ b/src/controller/DiagramController.php
@@ -21,9 +21,6 @@
$route = $request->getURIData('route');
$versioninfoDiagramID = $request->getURIData('versioninfodiagram');
$versioninfoPage = $request->getURIData('versioninfopage');
- $loadDiagramName = $request->getURIData('loadDiagramName');
- $loadDiagramPHID = $request->getURIData('loadDiagramPHID');
- $loadDiagramVersion = $request->getURIData('loadDiagramVersion');
if (isset($diagramphid) && !empty(trim($diagramphid))) {
// return PNG image data
@@ -103,39 +100,6 @@
}
}
- if ($route == 'loadJsExtension') {
- $response = new AphrontFileResponse();
- $response->setMimeType('application/javascript');
-
- $base64_data = "";
- if (isset($loadDiagramName) && !empty(trim($loadDiagramName))) {
- $diagram_id = (int) substr($loadDiagramName, strlen("DIAG"));
- if (isset($loadDiagramVersion) && !empty(trim($loadDiagramVersion))) {
- $diagramVersion = id(new DiagramVersion())->loadByVersionedDiagramID(
- $diagram_id,
- $loadDiagramVersion);
- } else {
- $diagramVersion = id(new DiagramVersion())->loadLatestByDiagramID(
- $diagram_id);
- }
- if ($diagramVersion) {
- $data = $diagramVersion->getData();
- $base64_data = base64_encode($data);
- }
- }
-
- $response->setContent('loadJsExtension("'
- . $loadDiagramName
- . '", "'
- . $loadDiagramPHID
- . '", "'
- . $loadDiagramVersion
- . '", "'
- . $base64_data
- . '");');
- return $response;
- }
-
$root = '';
$file = rtrim($request->getPath(), '/');
$root = dirname(phutil_get_library_root('diagram'));
@@ -150,11 +114,11 @@
if ($versioneddiagramid != null && $version != null) {
$file = preg_replace(
"/^\/diagram\/$versioneddiagramid\/$version" ."iframe\//",
- "data/drawio/src/main/webapp/",
+ "drawio/src/main/webapp/",
$file);
} else {
$file = preg_replace("/^\/diagram\/($diagramid\/?)?iframe\//",
- "data/drawio/src/main/webapp/",
+ "drawio/src/main/webapp/",
$file);
}
} else {
@@ -179,20 +143,6 @@
}
}
- // check if we are trying to load "iframe loader" files,
- // if so, correct the path accordingly
- if ($file == "data/drawio/src/main/webapp/index.html") {
- return $this->showIframe($request);
- }
- else
- if ($file == "data/drawio/src/main/webapp/iframe.css"
- || $file == "data/drawio/src/main/webapp/iframe-toolbtn.css"
- || $file == "data/drawio/src/main/webapp/iframe1.js"
- || $file == "data/drawio/src/main/webapp/iframe2.js"
- || $file == "data/drawio/src/main/webapp/iframe-toolbtn.js") {
- $file = str_replace("drawio/src/main/webapp/", "", $file);
- }
-
// determine full path
$path = $root . '/' . $file;
@@ -230,6 +180,7 @@
switch (pathinfo($file, PATHINFO_EXTENSION)) {
case 'html':
$response = id(new PlainHtmlWebpageResponse())
+ ->setDisableContentSecurityPolicy(true)
->setFrameable(true)
->setContent(file_get_contents($path));
break;
@@ -265,6 +216,9 @@
}
try {
$response->setContent(file_get_contents($path));
+ $response->setCacheDurationInSeconds(60 * 60 * 24 * 30);
+ $response->setLastModified(time());
+ $response->setCanCDN(true);
} catch (Exception $e) {
$response->setContent($route);
}
@@ -464,13 +418,26 @@
*/
private function showApplication(
AphrontRequest $request,
- string $diagramName = null,
- string $diagramPHID = null,
- string $diagramVersion = null,
- string $diagramBase64 = null
+ string $diagramName = '',
+ string $diagramPHID = '',
+ string $diagramVersion = '',
+ string $base64_data = ''
) {
$applicationUrl = "/" . explode("/", $request->getPath())[1];
+ $behaviorConfig = array();
+ $behaviorConfig['initParams'] = array(
+ $diagramName,
+ $diagramPHID,
+ $diagramVersion,
+ $base64_data
+ );
+ $behaviorConfig['toolbarCss'] = celerity_get_resource_uri('/iframe-toolbtn.css', 'diagram-resources');
+ $behaviorConfig['toolbarJs'] = celerity_get_resource_uri('/iframe-toolbtn.js', 'diagram-resources');
+
+ require_celerity_resource('javelin-behavior');
+ Javelin::initBehavior('diagram-extension', $behaviorConfig, 'diagram-resources');
+
$content = phutil_tag(
'div',
array(),
@@ -480,37 +447,6 @@
array(
'id' => 'mainScreen',
)),
- phutil_tag('div',
- array(),
- array(
- phutil_tag(
- 'img',
- array(
- 'class' => 'drawio',
- )),
- )),
- phutil_tag(
- 'script',
- array(
- 'src' => 'phorge_extension.js',
- 'defer' => true
- ),
- ''
- ),
- phutil_tag(
- 'script',
- array(
- 'src' => $applicationUrl . '/loadJsExtension/'
- . $diagramName
- . '/'
- . $diagramPHID
- . '/'
- . $diagramVersion
- . '/',
- 'defer' => true
- ),
- ''
- ),
phutil_tag(
'div',
array(
@@ -585,363 +521,4 @@
return $response;
}
- /**
- * Shows the internal draw.io application
- */
- private function showIframe(
- AphrontRequest $request
- ) {
- $content = phutil_tag(
- 'html',
- array(),
- array(
- phutil_tag(
- 'head',
- array(),
- array(
- phutil_tag(
- 'title',
- array(),
- 'Flowchart Maker & Online Diagram Software'
- ),
- phutil_tag(
- 'meta',
- array(
- 'charset' => 'utf-8'
- )
- ),
- phutil_tag(
- 'meta',
- array(
- 'http-equiv' => 'content-type',
- 'content' => 'text/html; charset=utf-8'
- )
- ),
- phutil_tag(
- 'meta',
- array(
- 'name' => 'viewport',
- 'content' => 'width=device-width, initial-scale=1.0, '
- . 'maximum-scale=1.0, user-scalable=no'
- )
- ),
- phutil_tag(
- 'meta',
- array(
- 'name' => 'mobile-web-app-capable',
- 'content' => 'yes'
- )
- ),
- phutil_tag(
- 'link',
- array(
- 'rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => 'iframe.css'
- )
- ),
- phutil_tag(
- 'link',
- array(
- 'rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => 'iframe-toolbtn.css'
- )
- ),
- phutil_tag(
- 'link',
- array(
- 'rel' => 'stylesheet',
- 'type' => 'text/css',
- 'href' => 'styles/grapheditor.css'
- )
- ),
- phutil_tag(
- 'script',
- array(
- 'type' => 'text/javascript',
- 'src' => 'iframe1.js',
- 'defer' => true
- )
- )
- )
- ),
- phutil_tag(
- 'body',
- array(
- 'class' => 'geEditor'
- ),
- array(
- phutil_tag(
- 'div',
- array(
- 'id' => 'geinfo'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'geBlock'
- ),
- array(
- phutil_tag(
- 'h1',
- array(),
- 'Flowchart Maker and Online Diagram Software'
- ),
- phutil_tag(
- 'p',
- array(),
- 'draw.io is free online diagram software. You can use '
- . 'it as a flowchart maker, network diagram software, '
- . 'to create UML online, as an ER diagram tool, to '
- . 'design database schema, to build BPMN online, as a '
- . 'circuit diagram maker, and more. draw.io can import '
- . '.vsdx, Gliffy™ and Lucidchart™ files.'
- ),
- phutil_tag(
- 'h2',
- array(
- 'id' => 'gestatus'
- ),
- 'Loading...'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'init-spinner'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'content'
- ),
- array(
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(0deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -1s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(27deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.923077ss;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(55deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.846154s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(83deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.769231s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(110deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.692308s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(138deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.615385s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(166deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.538462s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(193deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.461538s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(221deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.384615s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(249deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.307692s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(276deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.230769s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(304deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.153846s;'
- )
- )
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'spike',
- 'style' => 'transform: rotate(332deg)'
- . ' translatex(13px);'
- ),
- phutil_tag(
- 'div',
- array(
- 'class' => 'animator',
- 'style' => 'animation-delay: -0.0769231s;'
- )
- )
- )
- )
- )
- )
- )
- )
- ),
- phutil_tag(
- 'script',
- array(
- 'type' => 'text/javascript',
- 'src' => 'iframe2.js',
- 'defer' => true
- )
- ),
- phutil_tag(
- 'script',
- array(
- 'type' => 'text/javascript',
- 'src' => 'iframe-toolbtn.js',
- 'defer' => true
- )
- )
- )
- )
- )
- );
-
- $response = id(new PlainHtmlWebpageResponse())
- ->setFrameable(true)
- ->setContent($content);
-
- return $response;
- }
}
diff --git a/src/remarkup/PhabricatorRemarkupDiagramRule.php b/src/remarkup/PhabricatorRemarkupDiagramRule.php
--- a/src/remarkup/PhabricatorRemarkupDiagramRule.php
+++ b/src/remarkup/PhabricatorRemarkupDiagramRule.php
@@ -1,5 +1,8 @@
<?php
+require_celerity_resource('diagram-remarkup-image-js', 'diagram-resources');
+require_celerity_resource('diagram-remarkup-image-css', 'diagram-resources');
+
final class PhabricatorRemarkupDiagramRule
extends PhabricatorObjectRemarkupRule {
@@ -34,9 +37,6 @@
$params = array();
}
- // Get the file PHID for the Diagram object.
- $file_phid = $diagram->getPHID();
-
// Generate the appropriate HTML using the data from the Diagram and
// file objects.
$style = '';
@@ -88,11 +88,12 @@
array(
'style' => $style,
'class' => $class,
- 'src' => $diagram->getViewURI(),
+ 'src' => 'data:image/png;base64,' . $diagram->getBase64Data(),
'alt' => $alt,
- 'ondblclick' => 'window.open("/diagram/DIAG'
- . $diagram->getDiagramID()
- . '", "_blank")',
+ 'data-sigil' => 'diagram-remarkup-image',
+ 'data-diagram-version' => $diagram->getPHID(),
+ 'data-diagram-id' => $diagram->getDiagramID(),
+ 'title' => 'Double click to edit...'
)
)
);

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 9, 06:00 (10 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
962699
Default Alt Text
D25577.1731132022.diff (56 KB)

Event Timeline