Merge branch 'master' into gh-pages
This commit is contained in:
commit
90f8716a39
7 changed files with 246 additions and 19 deletions
|
|
@ -879,6 +879,7 @@ HTMLOut.prototype.findTokens = function(reTokens)
|
|||
aParms.push(aMatch[1]);
|
||||
}
|
||||
}
|
||||
//noinspection JSUnresolvedFunction
|
||||
fnToken.call(this, sToken, sIndent, aParms);
|
||||
}
|
||||
}
|
||||
|
|
@ -1968,6 +1969,12 @@ HTMLOut.prototype.processMachines = function(aMachines, buildOptions, done)
|
|||
}
|
||||
}
|
||||
this.addFilesToHTML(asFiles, sScriptEmbed);
|
||||
if (infoMachine['sticky']) {
|
||||
asFiles = [];
|
||||
asFiles.push("/modules/shared/lib/sticky.js");
|
||||
sScriptEmbed = '<script type="text/javascript">addStickyMachine("' + infoMachine['id'] + '")</script>';
|
||||
this.addFilesToHTML(asFiles, sScriptEmbed);
|
||||
}
|
||||
if (buildOptions.id) {
|
||||
asFiles = [];
|
||||
asFiles.push("/modules/build/lib/build.js");
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ MarkOut.aFMBooleanMachineProps = {
|
|||
'autopower': "autoPower",
|
||||
'autostart': "autoStart"
|
||||
};
|
||||
MarkOut.aFMReservedMachineProps = ['id', 'name', 'type', 'debugger', 'config', 'template', 'uncompiled', 'autoMount', 'drives', 'parms'];
|
||||
MarkOut.aFMReservedMachineProps = ['id', 'name', 'type', 'debugger', 'config', 'template', 'uncompiled', 'autoMount', 'drives', 'parms', 'sticky'];
|
||||
|
||||
/**
|
||||
* convertMD()
|
||||
|
|
@ -942,10 +942,12 @@ MarkOut.prototype.convertMDLinks = function(sBlock)
|
|||
* Before we start replacing Markdown links, see if there are any Liquid-style replacements
|
||||
* (in case this Markdown file is part of a Jekyll installation) and remove them.
|
||||
*
|
||||
* TODO: These replacements should use appropriate values from _config.yml; however, unless/until
|
||||
* we start using Node again to host the public site, that's low priority.
|
||||
* TODO: Any double-brace replacements should use appropriate values from _config.yml or the
|
||||
* page's Front Matter; however, unless/until we start using Node again to host the public site,
|
||||
* that's low priority.
|
||||
*/
|
||||
sBlock = sBlock.replace(/\{([\{%]).*?\1}/g, "");
|
||||
sBlock = sBlock.replace(/([^\t])\{([\{%]).*?\2}/g, "$1");
|
||||
sBlock = sBlock.replace(/(\{)([\{%])(.*?\2})/g, "<pre><code>$1$2$3</code></pre>");
|
||||
|
||||
var aMatch;
|
||||
var re = /\[([^\[\]]*)]\((.*?)(?:\s*"(.*?)"\)|\))/g;
|
||||
|
|
@ -1150,23 +1152,24 @@ MarkOut.prototype.convertMDImageLinks = function(sBlock, sIndent)
|
|||
*/
|
||||
MarkOut.prototype.convertMDMachineLinks = function(sBlock)
|
||||
{
|
||||
var aMatch, sReplacement;
|
||||
var aMatch, sReplacement, machine;
|
||||
var sMachineType, sMachineID, sMachineXMLFile, sMachineXSLFile, sMachineVersion, sMachineOptions, sMachineParms;
|
||||
|
||||
/*
|
||||
* Before we start looking for Markdown-style machine links, see if there are any Liquid-style machines,
|
||||
* (in case this Markdown file is part of a Jekyll installation) and convert them to Markdown-style links.
|
||||
*/
|
||||
|
||||
var reIncludes = /\{%\s*include\s+machine\.html\s+id=(["'])(.*?)\1\s*%}/g;
|
||||
var reIncludes = /(.){%\s*include\s+machine\.html\s+id=(["'])(.*?)\2\s*%}/g;
|
||||
|
||||
while ((aMatch = reIncludes.exec(sBlock))) {
|
||||
if (aMatch[1] == '\t') continue;
|
||||
sReplacement = "";
|
||||
sMachineID = aMatch[2];
|
||||
sMachineID = aMatch[3];
|
||||
if (this.aMachineDefs[sMachineID]) {
|
||||
var machine = this.aMachineDefs[sMachineID];
|
||||
machine = this.aMachineDefs[sMachineID];
|
||||
sMachineType = machine['type'] || "PCx86";
|
||||
sMachineOptions = ((sMachineType.indexOf("-dbg") > 0 || machine['debugger'] == "true")? "debugger" : "");
|
||||
if (machine['sticky']) sMachineOptions += (sMachineOptions? "," : "") + "sticky";
|
||||
sMachineType = sMachineType.replace("-dbg", "");
|
||||
sMachineXMLFile = machine['config'] || this.sMachineFile || "machine.xml";
|
||||
sMachineXSLFile = machine['template'] || "";
|
||||
|
|
@ -1175,11 +1178,14 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
|
|||
sReplacement = machine['name'] || "Embedded PC";
|
||||
sReplacement = "[" + sReplacement + "](" + sMachineXMLFile + ' "' + sMachineType + '!' + sMachineID + '!' + sMachineXSLFile + '!!' + sMachineOptions + '!' + sMachineParms + '")';
|
||||
}
|
||||
sBlock = sBlock.replace(aMatch[0], sReplacement);
|
||||
sBlock = sBlock.replace(aMatch[0].substr(1), sReplacement);
|
||||
reIncludes.lastIndex = 0; // reset lastIndex, since we just modified the string that reIncludes is iterating over
|
||||
}
|
||||
|
||||
sBlock = sBlock.replace(/\{%\s*include\s+build\.html\s+id=(["'])(.*?)\1\s*%}/g, '<div class="buildpc" id=$1$2$1></div>');
|
||||
/*
|
||||
* Ditto for any Liquid-style machine build links.
|
||||
*/
|
||||
sBlock = sBlock.replace(/\{%\s*include\s+machine-build\.html\s+id=(["'])(.*?)\1\s*%}/g, '<div class="buildpc" id=$1$2$1></div>');
|
||||
|
||||
/*
|
||||
* Start looking for Markdown-style machine links now...
|
||||
|
|
@ -1204,6 +1210,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
|
|||
sMachineParms = aMachineParms[4] || "";
|
||||
var aMachineOptions = sMachineOptions.split(',');
|
||||
var fDebugger = (aMachineOptions.indexOf("debugger") >= 0);
|
||||
var fSticky = (aMachineOptions.indexOf("sticky") >= 0);
|
||||
|
||||
/*
|
||||
* TODO: Consider validating the existence of this XML file and generating a more meaningful error if not found
|
||||
|
|
@ -1247,10 +1254,48 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
|
|||
'xsl': sMachineXSLFile,
|
||||
'version': sMachineVersion,// eg, "1.10", "*" to select the current version, or "uncompiled"; "*" is the default
|
||||
'debugger': fDebugger, // eg, true or false; false is the default
|
||||
'sticky': fSticky, // eg, true or false; false is the default
|
||||
'parms': sMachineParms}
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Last but not least, see if there are any Liquid-style machine command links that need to be converted.
|
||||
*/
|
||||
reIncludes = /([ \t]*)\{%\s*include\s+machine-command\.html\s+(.*?)\s*%}/g;
|
||||
|
||||
var findParm = function(aParms, sParm) {
|
||||
sParm += '=';
|
||||
for (var i = 0; i < aParms.length; i++) {
|
||||
if (aParms[i].indexOf(sParm) == 0) {
|
||||
return aParms[i].slice(sParm.length+1, -1);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
while ((aMatch = reIncludes.exec(sBlock))) {
|
||||
if (aMatch[1] == '\t') continue;
|
||||
var aParms = aMatch[2].match(/[a-z]+=(["']).*?\1/g);
|
||||
if (!aParms) continue;
|
||||
sReplacement = "";
|
||||
sMachineID = findParm(aParms, 'machine');
|
||||
var sControl = findParm(aParms, 'type') || 'button';
|
||||
var sControlType = sControl == 'button'? ' type="button"' : '';
|
||||
if (this.aMachineDefs[sMachineID]) {
|
||||
sReplacement = '<' + sControl + sControlType + ' onclick="commandMachine(';
|
||||
sReplacement += "'" + sMachineID + "',";
|
||||
sReplacement += "'" + findParm(aParms, 'component') + "',";
|
||||
sReplacement += "'" + findParm(aParms, 'command') + "',";
|
||||
sReplacement += "'" + findParm(aParms, 'value') + "')";
|
||||
sReplacement += '">' + (findParm(aParms, 'label') || 'Try It!') + '</' + sControl + '>';
|
||||
} else {
|
||||
sReplacement = "<!-- Unrecognized machine ID: " + sMachineID + " -->";
|
||||
}
|
||||
sBlock = sBlock.replace(aMatch[0], sReplacement);
|
||||
reIncludes.lastIndex = 0; // reset lastIndex, since we just modified the string that reIncludes is iterating over
|
||||
}
|
||||
|
||||
if (cMatches) {
|
||||
sBlock = sBlock.replace(/^<p>([\s\S]*)<\/p>$/g, "$1");
|
||||
}
|
||||
|
|
|
|||
102
modules/shared/lib/sticky.js
Normal file
102
modules/shared/lib/sticky.js
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* @fileoverview Support for "sticky" machines
|
||||
* @author <a href="mailto:Jeff@pcjs.org">Jeff Parsons</a> (@jeffpar)
|
||||
* @copyright © Jeff Parsons 2012-2017
|
||||
*
|
||||
* This file is part of PCjs, a computer emulation software project at <http://pcjs.org/>.
|
||||
*
|
||||
* PCjs is free software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation, either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCjs. If not,
|
||||
* see <http://www.gnu.org/licenses/gpl.html>.
|
||||
*
|
||||
* You are required to include the above copyright notice in every modified copy of this work
|
||||
* and to display that copyright notice when the software starts running; see COPYRIGHT in
|
||||
* <http://pcjs.org/modules/shared/lib/defines.js>.
|
||||
*
|
||||
* Some PCjs files also attempt to load external resource files, such as character-image files,
|
||||
* ROM files, and disk image files. Those external resource files are not considered part of PCjs
|
||||
* for purposes of the GNU General Public License, and the author does not claim any copyright
|
||||
* as to their contents.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* addStickyMachine(idMachine)
|
||||
*
|
||||
* @param {string} idMachine
|
||||
*/
|
||||
function addStickyMachine(idMachine)
|
||||
{
|
||||
var topMachine = -1;
|
||||
var prevOnScroll = window.onscroll;
|
||||
window.onscroll = function() {
|
||||
/*
|
||||
* TODO: Determine if/when we can cache the machine and machineSibling elements; we already
|
||||
* know we can't cache them when addStickyMachine() is first called, because that currently
|
||||
* happens before embed.js replaces the placeholder machine <div> with the real machine <div>.
|
||||
*
|
||||
* Placement of the addStickyMachine() call is irrelevant, because embed.js asynchronously
|
||||
* reads all the XML files that define the machine *before* replacing the <div>.
|
||||
*/
|
||||
var machine = document.getElementById(idMachine);
|
||||
if (machine) {
|
||||
var machineSibling = machine.nextElementSibling;
|
||||
if (machineSibling) {
|
||||
if (topMachine < 0) {
|
||||
topMachine = findTop(machine);
|
||||
}
|
||||
machine.className = machine.className.replace(/pcjs-machine-(floating|sticky) /g, '');
|
||||
if (window.pageYOffset <= topMachine) {
|
||||
machine.className = 'pcjs-machine-floating ' + machine.className;
|
||||
if (machineSibling) machineSibling.style.paddingTop = 0;
|
||||
} else {
|
||||
machine.className = 'pcjs-machine-sticky ' + machine.className;
|
||||
if (machineSibling) machineSibling.style.paddingTop = machine.offsetHeight + 'px';
|
||||
}
|
||||
if (prevOnScroll) prevOnScroll();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* commandMachine(idMachine, typeComponent, sCommand, sValue)
|
||||
*
|
||||
* @param {string} idMachine
|
||||
* @param {string} typeComponent
|
||||
* @param {string} sCommand
|
||||
* @param {string} [sValue]
|
||||
*/
|
||||
function commandMachine(idMachine, typeComponent, sCommand, sValue)
|
||||
{
|
||||
console.log("commandMachine('" + idMachine + "','" + typeComponent + "','" + sCommand + "','" + sValue + "')");
|
||||
}
|
||||
|
||||
/**
|
||||
* findTop(obj)
|
||||
*
|
||||
* @param {Object} obj
|
||||
*/
|
||||
function findTop(obj)
|
||||
{
|
||||
var curTop = 0;
|
||||
if (typeof obj.offsetParent != 'undefined' && obj.offsetParent) {
|
||||
while (obj.offsetParent) {
|
||||
curTop += obj.offsetTop;
|
||||
obj = obj.offsetParent;
|
||||
}
|
||||
curTop += obj.offsetTop;
|
||||
}
|
||||
else if (obj.y) {
|
||||
curTop += obj.y;
|
||||
}
|
||||
return curTop;
|
||||
}
|
||||
|
|
@ -228,7 +228,19 @@
|
|||
.pcjs-copyright a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.pcjs-machine-floating {
|
||||
position: relative;
|
||||
z-index: auto;
|
||||
background-color: transparent;
|
||||
padding-right: 0;
|
||||
}
|
||||
.pcjs-machine-sticky {
|
||||
position: fixed !important;
|
||||
z-index: 1 !important;
|
||||
background-color: #404040 !important;
|
||||
padding-right: 16px !important;
|
||||
top: 0 !important;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.pcjs-textarea {
|
||||
width: 100% !important;
|
||||
|
|
|
|||
Loading…
Reference in a new issue