Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cribjs-editor
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Cédric Le Ninivin
cribjs-editor
Commits
5aae7d82
Commit
5aae7d82
authored
Sep 24, 2020
by
Cédric Le Ninivin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pick Crib Enable Gadget: Validate gadget against Crib Enable interface
parent
2f634e9e
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
494 additions
and
6 deletions
+494
-6
gadget/gadget_cribjs_page_select_site.html
gadget/gadget_cribjs_page_select_site.html
+6
-0
gadget/gadget_cribjs_page_select_site.js
gadget/gadget_cribjs_page_select_site.js
+24
-6
gadget/gadget_interface.html
gadget/gadget_interface.html
+21
-0
gadget/gadget_interface.js
gadget/gadget_interface.js
+386
-0
gadget/gadget_interface_loader.html
gadget/gadget_interface_loader.html
+18
-0
gadget/gadget_interface_loader.js
gadget/gadget_interface_loader.js
+39
-0
No files found.
gadget/gadget_cribjs_page_select_site.html
View file @
5aae7d82
...
@@ -42,6 +42,12 @@
...
@@ -42,6 +42,12 @@
</div>
</div>
</form>
</form>
</div>
</div>
<div
class=
"interface_validator"
style=
"display:none;"
>
<h4>
Testing Interface
</h4>
<div
data-gadget-url=
"./gadget_interface.html"
data-gadget-scope=
"interface_validator"
data-gadget-sandbox=
"public"
></div>
</div>
</div>
</div>
<div
data-gadget-url=
"./gadget_jio.html"
<div
data-gadget-url=
"./gadget_jio.html"
data-gadget-scope=
"jio_gadget"
data-gadget-scope=
"jio_gadget"
...
...
gadget/gadget_cribjs_page_select_site.js
View file @
5aae7d82
...
@@ -4,14 +4,32 @@
...
@@ -4,14 +4,32 @@
"
use strict
"
;
"
use strict
"
;
function
setSiteGadgetUrl
(
gadget
,
event
)
{
function
setSiteGadgetUrl
(
gadget
,
event
)
{
var
site_editor_gadget_url
;
var
site_editor_gadget_url
,
gadget_validator
;
site_editor_gadget_url
=
gadget
.
props
.
element
.
querySelector
(
'
form.site-editor-gadget-url .url
'
).
value
;
site_editor_gadget_url
=
gadget
.
props
.
element
.
querySelector
(
'
form.site-editor-gadget-url .url
'
).
value
;
/*
*/
return
gadget
.
getDeclaredGadget
(
"
interface_validator
"
)
.
push
(
function
(
result
)
{
gadget_validator
=
result
;
gadget
.
props
.
element
.
querySelector
(
'
div.interface_validator
'
)
.
style
=
""
;
return
gadget_validator
.
render
({
gadget_to_check_url
:
site_editor_gadget_url
,
required_interface_list
:
[
"
crib-enable-interface.html
"
]
});
})
.
push
(
function
(
result
)
{
if
(
result
)
{
return
gadget
.
setSetting
(
"
site_editor_gadget_url
"
,
site_editor_gadget_url
)
return
gadget
.
setSetting
(
"
site_editor_gadget_url
"
,
site_editor_gadget_url
)
.
push
(
function
()
{
.
push
(
function
()
{
gadget
.
props
.
element
.
querySelector
(
"
.crib-site-save-status
"
)
gadget
.
props
.
element
.
querySelector
(
"
.crib-site-save-status
"
)
.
textContent
=
"
Saved
"
+
site_editor_gadget_url
+
"
files at
"
+
Date
();
.
textContent
=
"
Saved
"
+
site_editor_gadget_url
+
"
files at
"
+
Date
();
});
});
}
}
gadget
.
props
.
element
.
querySelector
(
"
.crib-site-save-status
"
)
.
textContent
=
"
Error founds for
"
+
site_editor_gadget_url
+
"
at
"
+
Date
()
+
"
Please see message bellow
"
;
});
}
rJS
(
window
)
rJS
(
window
)
.
ready
(
function
(
g
)
{
.
ready
(
function
(
g
)
{
...
...
gadget/gadget_interface.html
0 → 100644
View file @
5aae7d82
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
/>
<meta
name=
"viewport"
content=
"width=device-width"
/>
<title>
Interface Gadget
</title>
<script
src=
"../lib/rsvp.js"
type=
"text/javascript"
></script>
<script
src=
"../lib/renderjs.js"
type=
"text/javascript"
></script>
<script
src=
"../lib/jio-latest.js"
type=
"text/javascript"
></script>
<!-- custom script -->
<script
src=
"gadget_interface.js"
type=
"text/javascript"
></script>
</head>
<body>
<pre>
In Progress
</pre>
<div
style=
"display:none"
></div>
</body>
</html>
\ No newline at end of file
gadget/gadget_interface.js
0 → 100644
View file @
5aae7d82
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
/*global DOMParser, rJS, RSVP, window,
jIO, console, document*/
(
function
(
window
,
rJS
,
RSVP
,
DOMParser
,
jIO
,
console
,
document
)
{
"
use strict
"
;
//////////////////////////////////////////////
// Interface reader
//////////////////////////////////////////////
function
GadgetInterface
()
{
if
(
!
(
this
instanceof
GadgetInterface
))
{
return
new
GadgetInterface
();
}
this
.
title
=
''
;
this
.
description
=
''
;
this
.
method_list
=
[];
}
GadgetInterface
.
parse
=
function
(
txt
)
{
var
parser
=
(
new
DOMParser
()).
parseFromString
(
txt
,
'
text/html
'
).
body
,
reader
=
new
GadgetInterface
(),
element
,
sub_element
,
method
,
argument
;
// Extract title
element
=
parser
.
firstElementChild
;
if
(
element
.
tagName
!==
'
H1
'
)
{
throw
new
Error
(
"
Can't find gadget interface title from
"
+
element
.
outerHTML
);
}
reader
.
title
=
element
.
textContent
;
// Extract description
element
=
element
.
nextElementSibling
;
if
(
element
.
tagName
!==
'
H3
'
)
{
throw
new
Error
(
"
Can't find gadget interface description from
"
+
element
.
outerHTML
);
}
reader
.
description
=
element
.
textContent
;
// Extract method list
element
=
element
.
nextElementSibling
;
if
(
element
.
tagName
!==
'
DL
'
)
{
throw
new
Error
(
"
Can't find gadget interface method list from
"
+
element
.
outerHTML
);
}
if
(
element
.
nextElementSibling
!==
null
)
{
// Ensure the HTML doesn't contain unexpected tags after methods
// definition
throw
new
Error
(
"
Unexpected element
"
+
element
.
tagName
+
"
from
"
+
element
.
outerHTML
);
}
// Parse all methods
element
=
element
.
firstElementChild
;
while
(
element
!==
null
)
{
// Loop on all methods
method
=
{};
// Extract method title
if
(
element
.
tagName
!==
'
DT
'
)
{
throw
new
Error
(
"
Can't find gadget interface method name from
"
+
element
.
outerHTML
);
}
method
.
name
=
element
.
textContent
;
// Extract method description
element
=
element
.
nextElementSibling
;
if
(
element
.
tagName
!==
'
DD
'
)
{
throw
new
Error
(
"
Can't find gadget interface method description
"
+
"
from
"
+
element
.
outerHTML
);
}
method
.
description
=
element
.
textContent
;
// Extract method argument list
element
=
element
.
nextElementSibling
;
if
(
element
.
tagName
!==
'
DL
'
)
{
throw
new
Error
(
"
Can't find gadget interface method argument list
"
+
"
from
"
+
element
.
outerHTML
);
}
// Parse all arguments
method
.
argument_list
=
[];
sub_element
=
element
.
firstElementChild
;
while
(
sub_element
!==
null
)
{
// Loop on all arguments
argument
=
{};
// Extract argument name
if
(
sub_element
.
tagName
!==
'
DT
'
)
{
throw
new
Error
(
"
Can't find gadget interface argument name from
"
+
sub_element
.
outerHTML
);
}
argument
.
name
=
sub_element
.
textContent
;
argument
.
required
=
sub_element
.
getAttribute
(
"
data-parameter-required
"
)
!==
"
optional
"
;
argument
.
type
=
sub_element
.
getAttribute
(
"
data-parameter-type
"
);
// Extract argument description
sub_element
=
sub_element
.
nextElementSibling
;
if
(
sub_element
.
tagName
!==
'
DD
'
)
{
throw
new
Error
(
"
Can't find gadget interface argument description
"
+
"
from
"
+
sub_element
.
outerHTML
);
}
argument
.
description
=
sub_element
.
textContent
;
// Next argument
method
.
argument_list
.
push
(
argument
);
sub_element
=
sub_element
.
nextElementSibling
;
}
// Next method
reader
.
method_list
.
push
(
method
);
element
=
element
.
nextElementSibling
;
}
return
reader
;
};
GadgetInterface
.
fetch
=
function
(
interface_url
)
{
var
context
=
this
;
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
jIO
.
util
.
ajax
({
url
:
interface_url
,
dataType
:
'
text
'
});
})
.
push
(
function
(
evt
)
{
return
context
.
parse
(
evt
.
target
.
responseText
);
});
};
function
verifyAllMethodDeclared
(
interface_method_list
,
gadget_method_list
,
error_list
)
{
//to verify if all the interface methods are declared by the gadget.
var
gadget_method_name_list
=
gadget_method_list
,
interface_method_name_list
=
[],
i
,
j
,
missing_method_list
=
[],
error_message
;
for
(
i
=
0
;
i
<
interface_method_list
.
length
;
i
+=
1
)
{
interface_method_name_list
.
push
(
interface_method_list
[
i
].
name
);
}
// Check missing method declaration
for
(
j
=
0
;
j
<
interface_method_name_list
.
length
;
j
+=
1
)
{
if
(
gadget_method_name_list
.
indexOf
(
interface_method_name_list
[
j
]
)
<
0
)
{
missing_method_list
.
push
(
interface_method_name_list
[
j
]);
}
}
if
(
missing_method_list
.
length
)
{
error_message
=
"
Following required methods are not declared in the gadget:
"
;
for
(
i
=
0
;
i
<
missing_method_list
.
length
;
i
+=
1
)
{
error_message
+=
(
"
\n
"
+
missing_method_list
[
i
]);
}
error_list
.
push
({
details
:
error_message
});
}
}
var
interface_loader_defer
=
RSVP
.
defer
(),
counter
=
0
;
interface_loader_defer
.
resolve
(
'
Bootstrap
'
);
function
getOrDeclareGadget
(
context
,
gadget_to_check_url
)
{
return
context
.
getDeclaredGadget
(
gadget_to_check_url
)
.
push
(
undefined
,
function
(
error
)
{
var
element
,
loader_gadget
,
current_defer
;
if
(
error
instanceof
rJS
.
ScopeError
)
{
element
=
document
.
createElement
(
'
div
'
);
context
.
element
.
querySelector
(
'
div
'
).
appendChild
(
element
);
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
context
.
element
.
firstElementChild
.
textContent
=
'
Waiting
'
+
counter
;
// Wait for previous defer, and create a new one.
var
previous_deferred
=
interface_loader_defer
;
current_defer
=
RSVP
.
defer
();
interface_loader_defer
=
current_defer
;
counter
+=
1
;
return
previous_deferred
.
promise
;
})
.
push
(
function
()
{
context
.
element
.
firstElementChild
.
textContent
=
'
Loading
'
;
// XXX Load in an iframe
return
context
.
declareGadget
(
'
gadget_interface_loader.html
'
,
{
scope
:
gadget_to_check_url
,
element
:
element
});
})
.
push
(
function
(
result
)
{
loader_gadget
=
result
;
return
loader_gadget
.
declareGadgetToCheck
(
gadget_to_check_url
);
})
.
push
(
function
()
{
// Iframe loaded, unblock the next iteration
current_defer
.
resolve
();
return
loader_gadget
;
},
function
(
error
)
{
current_defer
.
resolve
();
throw
error
;
});
}
throw
error
;
});
}
function
getDefinedInterfaceMethodList
(
interface_url
,
error_list
)
{
return
GadgetInterface
.
fetch
(
interface_url
)
.
push
(
function
(
interface_data
)
{
return
interface_data
.
method_list
;
},
function
(
error
)
{
var
interface_name
=
interface_url
.
substr
(
interface_url
.
lastIndexOf
(
'
/
'
)
+
1
);
error_list
.
push
({
details
:
"
Interface Name:
"
+
interface_name
+
"
\n
"
+
"
Error Details :
\n
"
+
error
.
message
+
"
\n
"
});
// As interface can't be parsed, no method is found
return
[];
});
}
rJS
(
window
)
.
declareMethod
(
"
render
"
,
function
(
options
)
{
return
this
.
changeState
(
options
);
})
.
onStateChange
(
function
(
modification_dict
)
{
var
context
=
this
,
required_interface_list
=
[],
gadget_method_list
=
[],
error_list
=
[];
if
(
modification_dict
.
hasOwnProperty
(
'
gadget_to_check_url
'
))
{
if
(
modification_dict
.
hasOwnProperty
(
'
required_interface_list
'
))
{
required_interface_list
=
context
.
state
.
required_interface_list
;
}
return
getOrDeclareGadget
(
context
,
context
.
state
.
gadget_to_check_url
)
/*
.push(undefined, function (error) {
console.warn('oups', error);
context.element.innerHTML = '';
return;
});
*/
.
push
(
function
(
gadget_to_check
)
{
// Get the list of interfaces/methods
if
(
required_interface_list
)
{
return
RSVP
.
all
([
required_interface_list
,
gadget_to_check
.
getGadgetToCheckMethodList
(
'
method
'
)
]);
}
return
RSVP
.
all
([
gadget_to_check
.
getGadgetToCheckInterfaceList
(),
gadget_to_check
.
getGadgetToCheckMethodList
(
'
method
'
)
]);
})
.
push
(
function
(
result_list
)
{
required_interface_list
=
result_list
[
0
];
gadget_method_list
=
result_list
[
1
];
},
function
(
error
)
{
error_list
.
push
({
details
:
"
Error with gadget loading
\n
"
+
(
error
.
message
||
''
)
});
})
.
push
(
function
()
{
// Get all methods definition for every interface
var
promise_list
=
[],
i
;
for
(
i
=
0
;
i
<
required_interface_list
.
length
;
i
+=
1
)
{
promise_list
.
push
(
getDefinedInterfaceMethodList
(
required_interface_list
[
i
],
error_list
)
);
}
return
RSVP
.
all
(
promise_list
);
})
.
push
(
function
(
method_table
)
{
var
interface_method_list
=
[],
i
,
j
,
promise_list
=
[];
for
(
i
=
0
;
i
<
method_table
.
length
;
i
+=
1
)
{
for
(
j
=
0
;
j
<
method_table
[
i
].
length
;
j
+=
1
)
{
// Check method declared twice
if
(
interface_method_list
.
indexOf
(
method_table
[
i
][
j
].
name
)
>=
0
)
{
error_list
.
push
({
details
:
"
Method documented in multiple interface
\n
"
+
method_table
[
i
][
j
].
name
});
}
else
{
interface_method_list
.
push
(
method_table
[
i
][
j
].
name
);
}
}
}
// Check unknown method declaration
for
(
i
=
0
;
i
<
gadget_method_list
.
length
;
i
+=
1
)
{
if
(
interface_method_list
.
indexOf
(
gadget_method_list
[
i
]
)
<
0
)
{
error_list
.
push
({
details
:
"
Method not documented in the interface
\n
"
+
gadget_method_list
[
i
]
});
}
}
// Check that all interfaces are implemented
for
(
i
=
0
;
i
<
required_interface_list
.
length
;
i
+=
1
)
{
promise_list
.
push
(
verifyAllMethodDeclared
(
method_table
[
i
],
gadget_method_list
,
error_list
)
);
}
return
RSVP
.
all
(
promise_list
);
})
.
push
(
function
()
{
// Display result
var
i
,
error_message
=
''
,
summary_message
,
returned_result
=
false
;
if
(
error_list
.
length
===
0
)
{
summary_message
=
'
Success
'
;
returned_result
=
true
;
}
else
{
summary_message
=
'
Failure
'
;
}
for
(
i
=
0
;
i
<
error_list
.
length
;
i
+=
1
)
{
error_message
+=
(
error_list
[
i
].
details
+
'
\n\n
'
);
}
if
(
context
.
state
.
summary
)
{
if
(
error_message
!==
''
)
{
console
.
warn
(
error_message
,
error_list
);
}
error_message
=
summary_message
;
}
else
{
error_message
=
summary_message
+
'
\n\n
'
+
error_message
;
}
context
.
element
.
firstElementChild
.
textContent
=
error_message
;
return
returned_result
;
})
.
push
(
undefined
,
function
(
error
)
{
console
.
warn
(
error
);
context
.
element
.
firstElementChild
.
textContent
=
"
Unexpected error:
"
+
error
;
});
}
if
(
modification_dict
.
hasOwnProperty
(
'
error
'
))
{
console
.
warn
(
context
.
state
.
error
);
context
.
element
.
firstElementChild
.
textContent
=
"
Unexpected error:
"
+
context
.
state
.
error
;
}
})
.
allowPublicAcquisition
(
'
reportServiceError
'
,
function
(
param_list
)
{
// Subgadget services failed.
// Report it as an error instead of crashing the page
return
this
.
changeState
({
error
:
param_list
[
0
]});
});
}(
window
,
rJS
,
RSVP
,
DOMParser
,
jIO
,
console
,
document
));
\ No newline at end of file
gadget/gadget_interface_loader.html
0 → 100644
View file @
5aae7d82
<!DOCTYPE html>
<html>
<head>
<meta
charset=
"utf-8"
/>
<meta
name=
"viewport"
content=
"width=device-width"
/>
<title>
Interface Gadget
</title>
<script
src=
"../lib/rsvp.js"
type=
"text/javascript"
></script>
<script
src=
"../lib/renderjs.js"
type=
"text/javascript"
></script>
<!-- custom script -->
<script
src=
"gadget_interface_loader.js"
type=
"text/javascript"
></script>
</head>
<body>
</body>
</html>
\ No newline at end of file
gadget/gadget_interface_loader.js
0 → 100644
View file @
5aae7d82
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
/*global rJS, window, document*/
(
function
(
window
,
rJS
,
document
)
{
"
use strict
"
;
rJS
(
window
)
.
declareMethod
(
"
declareGadgetToCheck
"
,
function
(
url
)
{
var
div
=
document
.
createElement
(
'
div
'
),
gadget
=
this
;
this
.
element
.
innerHTML
=
''
;
this
.
element
.
appendChild
(
div
);
return
gadget
.
declareGadget
(
url
,
{
scope
:
'
gadget_to_check
'
,
sandbox
:
'
iframe
'
,
element
:
div
})
.
push
(
function
()
{
// Do not return the loaded gadget.
// XXX This seems to break rJS iframe communication
return
;
});
})
.
declareMethod
(
"
getGadgetToCheckInterfaceList
"
,
function
()
{
return
this
.
getDeclaredGadget
(
'
gadget_to_check
'
)
.
push
(
function
(
gadget_to_check
)
{
return
gadget_to_check
.
getInterfaceList
();
});
})
.
declareMethod
(
"
getGadgetToCheckMethodList
"
,
function
(
name
)
{
return
this
.
getDeclaredGadget
(
'
gadget_to_check
'
)
.
push
(
function
(
gadget_to_check
)
{
return
gadget_to_check
.
getMethodList
(
name
);
});
});
}(
window
,
rJS
,
document
));
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment